Skip to content

Instantly share code, notes, and snippets.

@SilverCory
Last active August 17, 2023 00:00
Show Gist options
  • Save SilverCory/3ade31b99d706538f61050c5ae0a3235 to your computer and use it in GitHub Desktop.
Save SilverCory/3ade31b99d706538f61050c5ae0a3235 to your computer and use it in GitHub Desktop.
A tee logging implementation for slog golang. Log with multiple handlers.

Usage:

var logger = slog.New(
  NewTeeLogger(
    slog.NewJSONHandler(
      os.Stdout,
      &slog.HandlerOptions{
        AddSource:   false,
        Level:       level,
        ReplaceAttr: nil,
      },
    ),
    slog.NewTextHandler(
      os.Stderr,
      &slog.HandlerOptions{
        AddSource:   true,
        Level:       slog.LevelDebug,
        ReplaceAttr: nil,
      },
    ),
  ),
)

logger.Info("Hello World!")
package logging
import (
"context"
"log/slog"
)
var _ slog.Handler = (*TeeLogger)(nil)
type TeeLogger struct {
handlers []slog.Handler
}
func NewTeeLogger(handlers ...slog.Handler) *TeeLogger {
return &TeeLogger{
handlers: handlers,
}
}
func (t *TeeLogger) Enabled(ctx context.Context, level slog.Level) bool {
for _, handler := range t.handlers {
if handler.Enabled(ctx, level) {
return true
}
}
return false
}
func (t *TeeLogger) Handle(ctx context.Context, record slog.Record) error {
for _, handler := range t.handlers {
if err := handler.Handle(ctx, record); err != nil {
return err
}
}
return nil
}
func (t *TeeLogger) WithAttrs(attrs []slog.Attr) slog.Handler {
var ret = &TeeLogger{
handlers: make([]slog.Handler, len(t.handlers)),
}
for k, handler := range t.handlers {
ret.handlers[k] = handler.WithAttrs(attrs)
}
return ret
}
func (t *TeeLogger) WithGroup(name string) slog.Handler {
var ret = &TeeLogger{
handlers: make([]slog.Handler, len(t.handlers)),
}
for k, handler := range t.handlers {
ret.handlers[k] = handler.WithGroup(name)
}
return ret
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment