Last active
July 3, 2024 12:10
-
-
Save dlisboa/0fe5373c6b2c03eec241e5916f19e488 to your computer and use it in GitHub Desktop.
Slog TeeHandler with signal for level change
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"errors" | |
"fmt" | |
"log/slog" | |
"os" | |
"os/signal" | |
"syscall" | |
"time" | |
) | |
func main() { | |
var level slog.LevelVar | |
opts := slog.HandlerOptions{ | |
Level: &level, | |
} | |
tee := NewTeeHandler(slog.NewTextHandler(os.Stdout, &opts), slog.NewJSONHandler(os.Stderr, &opts)) | |
logger := slog.New(tee) | |
sigChan := make(chan os.Signal, 1) | |
signal.Notify(sigChan, syscall.SIGUSR2) | |
go func() { | |
for { | |
<-sigChan | |
currentLevel := level.Level() | |
if currentLevel != slog.LevelDebug { | |
level.Set(slog.LevelDebug) | |
} else { | |
level.Set(slog.LevelInfo) | |
} | |
logger.Info("Log level changed") | |
} | |
}() | |
fmt.Printf("PID is %d\n", os.Getpid()) | |
fmt.Printf("Send `kill -USR2 %d` signal to toggle log level\n", os.Getpid()) | |
for { | |
logger.Info("this is INFO", "foo", "bar") | |
time.Sleep(500 * time.Millisecond) | |
logger.Debug("this is DEBUG", "qux", "gazonk") | |
} | |
} | |
type teeHandler struct { | |
handlers []slog.Handler | |
} | |
func NewTeeHandler(handlers ...slog.Handler) slog.Handler { | |
return &teeHandler{handlers: handlers} | |
} | |
func (h *teeHandler) Handle(ctx context.Context, r slog.Record) error { | |
var errs []error | |
for _, handler := range h.handlers { | |
err := handler.Handle(ctx, r) | |
errs = append(errs, err) | |
} | |
return errors.Join(errs...) | |
} | |
func (h *teeHandler) Enabled(ctx context.Context, level slog.Level) bool { | |
for _, handler := range h.handlers { | |
if handler.Enabled(ctx, level) { | |
return true | |
} | |
} | |
return false | |
} | |
func (h *teeHandler) WithAttrs(attrs []slog.Attr) slog.Handler { | |
var tee teeHandler | |
for _, handler := range h.handlers { | |
handler = handler.WithAttrs(attrs) | |
tee.handlers = append(tee.handlers, handler) | |
} | |
return &tee | |
} | |
func (h *teeHandler) WithGroup(name string) slog.Handler { | |
var tee teeHandler | |
for _, handler := range h.handlers { | |
handler = handler.WithGroup(name) | |
tee.handlers = append(tee.handlers, handler) | |
} | |
return &tee | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment