package slog import ( "fmt" "io" "strings" "time" "github.com/fatih/color" ) type Logger struct { prefix string level LogLevel writers []LoggerWriter printTraceback bool printTime bool jsonPretty bool } type LogLevel struct { n uint8 t string c color.Attribute } func (l *LogLevel) GetName() string { return l.t } type MethodTraceback struct { Method string `json:"method"` Filename string `json:"filename"` Line int `json:"line"` Signature string `json:"signature"` FullPath string `json:"fullPath"` } var ( INFO = LogLevel{n: 0, t: "info", c: color.FgWhite} WARN = LogLevel{n: 1, t: "warn", c: color.FgHiYellow} ERROR = LogLevel{n: 2, t: "error", c: color.FgHiRed} FATAL = LogLevel{n: 3, t: "fatal", c: color.FgRed} DEBUG = LogLevel{n: 4, t: "debug", c: color.FgGreen} ) func CreateLogger() *Logger { return &Logger{ prefix: "LOG", level: FATAL, printTraceback: false, printTime: true, } } func (l *Logger) Prefix(prefix string) *Logger { l.prefix = prefix return l } func (l *Logger) Level(level LogLevel) *Logger { l.level = level return l } func (l *Logger) PrintTraceback(b bool) *Logger { l.printTraceback = b return l } func (l *Logger) PrintTime(b bool) *Logger { l.printTime = b return l } func (l *Logger) JsonPretty(b bool) *Logger { l.jsonPretty = b return l } func (l *Logger) AddWriters(writers ...LoggerWriter) *Logger { l.writers = append(l.writers, writers...) return l } func (l *Logger) AddWriter(writer LoggerWriter) *Logger { l.writers = append(l.writers, writer) return l } func (l *Logger) Close() error { for _, writer := range l.writers { err := writer.Close() if err != nil { l.Error(err) } } return nil } func (l *Logger) CreateTextWriter(w io.Writer) *LoggerTextWriter { return CreateTextWriter(w, l.printTraceback, l.printTime) } func (l *Logger) CreateTextStdoutWriter() *LoggerTextWriter { return CreateTextStdoutWriter(l.printTraceback, l.printTime) } func (l *Logger) CreateTextFileWriter(filename string) (*LoggerTextWriter, error) { return CreateTextFileWriter(filename, l.printTraceback, l.printTime) } func (l *Logger) CreateJsonWriter(w io.Writer) *LoggerJsonWriter { return CreateJsonWriter(w, l.jsonPretty) } func (l *Logger) CreateJsonStdoutWriter() *LoggerJsonWriter { return CreateJsonStdoutWriter(l.jsonPretty) } func (l *Logger) CreateJsonFileWriter(filename string) (*LoggerJsonWriter, error) { return CreateJsonFileWriter(filename, l.jsonPretty) } func FormatTime(t time.Time) string { return fmt.Sprintf("%02d.%02d.%02d %02d:%02d:%02d", t.Day(), t.Month(), t.Year(), t.Hour(), t.Minute(), t.Second()) } func FormatTraceback(mt *MethodTraceback) string { return fmt.Sprintf("%s:%s:%d", mt.Filename, mt.Method, mt.Line) } func FormatFullTraceback(tracebacks []*MethodTraceback) string { formatted := make([]string, 0) for _, tb := range tracebacks { formatted = append(formatted, FormatTraceback(tb)) } return strings.Join(formatted, "->") } func BuildString(level LogLevel, prefix string, printTime, printTraceback bool, m ...any) string { args := []string{ fmt.Sprintf("[%s]", prefix), fmt.Sprintf("[%s]", strings.ToUpper(level.t)), } if printTraceback { args = append(args, fmt.Sprintf("[%s]", FormatTraceback(getTraceback()))) } if printTime { args = append(args, fmt.Sprintf("[%s]", FormatTime(time.Now()))) } msg := Map(m, func(el any) string { return fmt.Sprintf("%v", el) }) s := fmt.Sprintf("%s %s", strings.Join(args, " "), strings.Join(msg, " ")) return s }