package loggers import ( "fmt" "io" "os" "time" "github.com/haydenhargreaves/Potion/internal/infrastructure/logging" ) type ConsoleLogger struct { writer io.Writer filter logging.LogLevel } var _ logging.Logger = (*ConsoleLogger)(nil) // NewConsoleLogger creates a new logger which writes directly to standard out (stdout). func NewConsoleLogger(filter logging.LogLevel) logging.Logger { return &ConsoleLogger{ writer: os.Stdout, filter: filter, } } // formatLevelString converts a log level string (level) into a new, formatted output string. // This also includes color, if the shell supports it. Otherwise, the rendering may appear odd. func formatLevelString(level logging.LogLevel) string { switch level { case logging.LogLevelTrace: return fmt.Sprintf("%s[%s]%s", logging.BgMagenta, level, logging.Reset) case logging.LogLevelDebug: return fmt.Sprintf("%s[%s]%s", logging.BgBlue, level, logging.Reset) case logging.LogLevelInfo: return fmt.Sprintf("%s[%s]%s", logging.BgGreen, level, logging.Reset) case logging.LogLevelWarning: return fmt.Sprintf("%s[%s]%s", logging.BgYellow, level, logging.Reset) case logging.LogLevelError: return fmt.Sprintf("%s[%s]%s", logging.BgRed, level, logging.Reset) case logging.LogLevelFatal: return fmt.Sprintf("%s[%s]%s", logging.BgRed, level, logging.Reset) } return fmt.Sprintf("[%s]", level) } // Log implements the interface. func (l *ConsoleLogger) Log(level logging.LogLevel, format string, v ...any) { // level is too low, do not log if !l.filter.MatchFilter(level) { return } timestamp := time.Now().UTC().Format("01/02/2006 - 15:04:05") levelStr := formatLevelString(level) fullFormat := fmt.Sprintf("%-18s %s | %s\n", levelStr, timestamp, format) bytes := fmt.Appendf(nil, fullFormat, v...) l.writer.Write(bytes) }