diff --git a/cmd/echo/main.go b/cmd/echo/main.go index d4494a6..72eb3ac 100644 --- a/cmd/echo/main.go +++ b/cmd/echo/main.go @@ -36,7 +36,28 @@ func main() { defer l.Close() wmLogger := watermill.NewStdLogger(false, false) - wrappedSlogger := logger.NewWrappedSlogger(os.Stdout, verbose) + traceFile, err := os.OpenFile("trace.log", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + log.Fatalf("couldn't open trace log: %s\n", err) + } + + traceLogConfig := logger.LogConfig{ + Writer: traceFile, + Format: "json", + Level: -5, + } + + stdoutLogConfig := logger.LogConfig{ + Writer: os.Stdout, + Format: "text", + Level: verbose, + } + + wrappedSlogger := logger.NewWrappedSlogger( + traceLogConfig, + stdoutLogConfig, + ) + router, err := message.NewRouter(message.RouterConfig{}, wrappedSlogger) router.AddPlugin(plugin.SignalsHandler) @@ -51,6 +72,8 @@ func main() { ctx := context.Background() ts := telnet.NewTELNETServer(ctx, l, pubSub, wrappedSlogger) tp := telnet.NewTELNETParser(ctx, pubSub, wrappedSlogger) + + wrappedSlogger.Info("booting up, welcome back formers", nil) go tp.Handle() for { diff --git a/logger/wrappedslogger.go b/logger/wrappedslogger.go index c59909e..4130b14 100644 --- a/logger/wrappedslogger.go +++ b/logger/wrappedslogger.go @@ -23,42 +23,76 @@ func LogFieldsToSlogAttrs(in watermill.LogFields) []slog.Attr { } type WrappedSlogger struct { - *slog.Logger + loggers []*slog.Logger } -func NewWrappedSlogger(w io.Writer, verbose int) *WrappedSlogger { - opts := &slog.HandlerOptions{ - Level: slog.Level(verbose), +type LogConfig struct { + Format string + Writer io.Writer + Level int +} + +func NewWrappedSlogger(configs ...LogConfig) *WrappedSlogger { + + loggers := make([]*slog.Logger, 0) + for _, config := range configs { + + opts := &slog.HandlerOptions{ + Level: slog.Level(config.Level), + } + + var handler slog.Handler + + switch config.Format { + case "json": + handler = slog.NewJSONHandler(config.Writer, opts) + case "text": + handler = slog.NewTextHandler(config.Writer, opts) + + } + + loggers = append(loggers, slog.New(handler)) } - handler := slog.NewTextHandler(w, opts) + return &WrappedSlogger{ - slog.New(handler), + loggers: loggers, } } func (wl *WrappedSlogger) Error(msg string, err error, fields watermill.LogFields) { attrs := LogFieldsToSlogAttrs(fields) - wl.LogAttrs(nil, LevelTrace, msg, attrs...) + for _, l := range wl.loggers { + l.LogAttrs(nil, slog.LevelError, msg, attrs...) + } } func (wl *WrappedSlogger) Info(msg string, fields watermill.LogFields) { attrs := LogFieldsToSlogAttrs(fields) - wl.LogAttrs(nil, slog.LevelInfo, msg, attrs...) + for _, l := range wl.loggers { + l.LogAttrs(nil, slog.LevelInfo, msg, attrs...) + } } func (wl *WrappedSlogger) Debug(msg string, fields watermill.LogFields) { attrs := LogFieldsToSlogAttrs(fields) - wl.LogAttrs(nil, slog.LevelDebug, msg, attrs...) + for _, l := range wl.loggers { + l.LogAttrs(nil, slog.LevelDebug, msg, attrs...) + } } func (wl *WrappedSlogger) Trace(msg string, fields watermill.LogFields) { attrs := LogFieldsToSlogAttrs(fields) - wl.LogAttrs(nil, LevelTrace, msg, attrs...) + for _, l := range wl.loggers { + l.LogAttrs(nil, LevelTrace, msg, attrs...) + } } func (wl *WrappedSlogger) With(fields watermill.LogFields) watermill.LoggerAdapter { attrs := LogFieldsToSlogAttrs(fields) - l := slog.Default().With(attrs) - return &WrappedSlogger{l} + newLoggers := make([]*slog.Logger, 0) + for _, l := range wl.loggers { + newLoggers = append(newLoggers, l.With(attrs)) + } + return &WrappedSlogger{loggers: newLoggers} }