Skip to content

Commit

Permalink
merge: branch '3612-fix-stdlog' into 'main'
Browse files Browse the repository at this point in the history
Fix stdlog/slog [#3612]

Closes #3612

See merge request accumulatenetwork/accumulate!1079
  • Loading branch information
firelizzard18 committed Jul 5, 2024
2 parents 2a39944 + 8a09b6f commit 99e0e8c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
12 changes: 12 additions & 0 deletions cmd/accumulated/run/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package run
import (
"encoding/json"
"io"
"log"
"log/slog"
"os"
"strings"
Expand Down Expand Up @@ -71,6 +72,17 @@ func (l *Logging) start(inst *Instance) error {
inst.logger = slog.New(h)
slog.SetDefault(inst.logger)

// [slog.SetDefault] also sets the [log] output to pass all [log] messages
// through [slog]. By default this bridge logs [log] calls with level INFO.
// Which means all [log] calls will get dropped if the [slog] level is
// greater than INFO. The log level of the bridge can be changed (before the
// call to [slog.SetDefault]) via [slog.SetLogLoggerLevel], but IMO setting
// the default level to something more severe (i.e. WARN or ERROR) is not a
// good solution. So instead, we set the [log] output to
// [logging.StdlogWriter] which cooperates with [logging]'s [slog.Handler]
// to exclude [log] messages from filtering.
log.SetOutput(&logging.StdlogWriter{Handler: h})

return nil
}

Expand Down
34 changes: 33 additions & 1 deletion internal/logging/slog.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
"context"
"fmt"
"io"
stdlog "log"
"log/slog"
"runtime"
"strings"
"time"

Expand Down Expand Up @@ -130,6 +132,9 @@ func (h *logHandler) WithGroup(name string) slog.Handler {
}

func (h *logHandler) Enabled(ctx context.Context, level slog.Level) bool {
if ctx.Value(isStdlog) != nil {
return true
}
if level < h.lowestLevel {
return false
}
Expand All @@ -141,7 +146,8 @@ func (h *logHandler) Enabled(ctx context.Context, level slog.Level) bool {

func (h *logHandler) Handle(ctx context.Context, record slog.Record) error {
record.AddAttrs(Attrs(ctx)...)
if record.Level < h.levelFor(h.defaultLevel, record.Attrs) {
if ctx.Value(isStdlog) == nil &&
record.Level < h.levelFor(h.defaultLevel, record.Attrs) {
return nil
}

Expand Down Expand Up @@ -194,3 +200,29 @@ func (h *logHandler) levelFor(level slog.Level, fn func(func(slog.Attr) bool)) s
})
return level
}

var isStdlog _contextKey

type StdlogWriter struct {
Handler slog.Handler
}

func (w *StdlogWriter) Write(buf []byte) (int, error) {
var pc uintptr
if stdlog.Flags()&(stdlog.Lshortfile|stdlog.Llongfile) != 0 {
// skip [runtime.Callers, w.Write, Logger.Output, log.Print]
var pcs [1]uintptr
runtime.Callers(4, pcs[:])
pc = pcs[0]
}

// Remove final newline.
origLen := len(buf) // Report that the entire buf was written.
if len(buf) > 0 && buf[len(buf)-1] == '\n' {
buf = buf[:len(buf)-1]
}

ctx := context.WithValue(context.Background(), isStdlog, true)
r := slog.NewRecord(time.Now(), slog.LevelInfo, string(buf), pc)
return origLen, w.Handler.Handle(ctx, r)
}

0 comments on commit 99e0e8c

Please sign in to comment.