| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- package test
- import (
- "context"
- "io"
- "log/slog"
- "os"
- "time"
- "github.com/slackhq/nebula/logging"
- )
- // NewLogger returns a *slog.Logger suitable for use in tests. Output goes to
- // io.Discard by default; set TEST_LOGS=1 (info), 2 (debug), or 3 (trace) to
- // stream output to stderr for local debugging.
- func NewLogger() *slog.Logger {
- v := os.Getenv("TEST_LOGS")
- if v == "" {
- return slog.New(slog.DiscardHandler)
- }
- level := slog.LevelInfo
- switch v {
- case "2":
- level = slog.LevelDebug
- case "3":
- level = logging.LevelTrace
- }
- return slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level}))
- }
- // NewLoggerWithOutput returns a *slog.Logger whose text output is captured by
- // w. Timestamps are suppressed so tests can assert on exact output without
- // baking the current time into expected strings.
- func NewLoggerWithOutput(w io.Writer) *slog.Logger {
- return slog.New(&stripTimeHandler{inner: slog.NewTextHandler(w, nil)})
- }
- // NewLoggerWithOutputAndLevel is NewLoggerWithOutput with an explicit level
- // so tests can exercise Enabled-gated paths.
- func NewLoggerWithOutputAndLevel(w io.Writer, level slog.Level) *slog.Logger {
- return slog.New(&stripTimeHandler{inner: slog.NewTextHandler(w, &slog.HandlerOptions{Level: level})})
- }
- // NewJSONLoggerWithOutput returns a *slog.Logger emitting JSON to w with
- // timestamps suppressed, for tests that pin the JSON shape.
- func NewJSONLoggerWithOutput(w io.Writer, level slog.Level) *slog.Logger {
- return slog.New(&stripTimeHandler{inner: slog.NewJSONHandler(w, &slog.HandlerOptions{Level: level})})
- }
- // stripTimeHandler zeros each record's time before delegating so slog's
- // built-in handlers skip emitting the time attribute. Used to avoid
- // timestamp-dependent assertions in tests without resorting to ReplaceAttr.
- type stripTimeHandler struct {
- inner slog.Handler
- }
- func (h *stripTimeHandler) Enabled(ctx context.Context, l slog.Level) bool {
- return h.inner.Enabled(ctx, l)
- }
- func (h *stripTimeHandler) Handle(ctx context.Context, r slog.Record) error {
- r.Time = time.Time{}
- return h.inner.Handle(ctx, r)
- }
- func (h *stripTimeHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
- return &stripTimeHandler{inner: h.inner.WithAttrs(attrs)}
- }
- func (h *stripTimeHandler) WithGroup(name string) slog.Handler {
- return &stripTimeHandler{inner: h.inner.WithGroup(name)}
- }
|