[exp] slog: add NewLogLogger

39 views
Skip to first unread message

Jonathan Amsterdam (Gerrit)

unread,
Feb 10, 2023, 3:48:23 PM2/10/23
to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gopher Robot, Russ Cox, Alan Donovan, golang-co...@googlegroups.com

Jonathan Amsterdam submitted this change.

View Change



1 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: slog/logger.go
Insertions: 4, Deletions: 2.

@@ -52,6 +52,7 @@
}
var pc uintptr
if w.capturePC {
+ // skip [runtime.Callers, callerPC, w.Write, Logger.Output, log.Print]
pc = callerPC(5)
}

@@ -146,8 +147,9 @@
return l.Handler().Enabled(l.ctx, level)
}

-// NewLogLogger returns a log.Logger whose output becomes the message
-// of the given Handler, at the given level.
+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
func NewLogLogger(h Handler, level Level) *log.Logger {
return log.New(&handlerWriter{h, level, true}, "", 0)
}
```

Approvals: Alan Donovan: Looks good to me, approved Russ Cox: Looks good to me, approved Gopher Robot: TryBots succeeded Jonathan Amsterdam: Run TryBots
slog: add NewLogLogger

Add a function that creates a log.Logger that writes to a Handler.

This generalizes what we already do for the default log.Logger.

Change-Id: I7ebfba3404b6fe9960eeb7dccd5385d1166a4bcb
Reviewed-on: https://go-review.googlesource.com/c/exp/+/465356
Reviewed-by: Alan Donovan <adon...@google.com>
Reviewed-by: Russ Cox <r...@golang.org>
Run-TryBot: Jonathan Amsterdam <j...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
M slog/logger.go
M slog/logger_test.go
2 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/slog/logger.go b/slog/logger.go
index 79d5bdd..cf77f40 100644
--- a/slog/logger.go
+++ b/slog/logger.go
@@ -32,7 +32,8 @@
// This can occur with SetDefault(Default()).
// See TestSetDefault.
if _, ok := l.Handler().(*defaultHandler); !ok {
- log.SetOutput(&handlerWriter{l.Handler(), log.Flags()})
+ capturePC := log.Flags()&(log.Lshortfile|log.Llongfile) != 0
+ log.SetOutput(&handlerWriter{l.Handler(), LevelInfo, capturePC})
log.SetFlags(0) // we want just the log message, no time or location
}
}
@@ -40,16 +41,18 @@
// handlerWriter is an io.Writer that calls a Handler.
// It is used to link the default log.Logger to the default slog.Logger.
type handlerWriter struct {
- h Handler
- flags int
+ h Handler
+ level Level
+ capturePC bool
}

func (w *handlerWriter) Write(buf []byte) (int, error) {
- if !w.h.Enabled(nil, LevelInfo) {
+ if !w.h.Enabled(nil, w.level) {
return 0, nil
}
var pc uintptr
- if w.flags&(log.Lshortfile|log.Llongfile) != 0 {
+ if w.capturePC {
+ // skip [runtime.Callers, callerPC, w.Write, Logger.Output, log.Print]
pc = callerPC(5)
}

@@ -58,7 +61,7 @@
if len(buf) > 0 && buf[len(buf)-1] == '\n' {
buf = buf[:len(buf)-1]
}
- r := NewRecord(time.Now(), LevelInfo, string(buf), pc, nil)
+ r := NewRecord(time.Now(), w.level, string(buf), pc, nil)
return origLen, w.h.Handle(r)
}

@@ -144,6 +147,13 @@
return l.Handler().Enabled(l.ctx, level)
}

+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
+func NewLogLogger(h Handler, level Level) *log.Logger {
+ return log.New(&handlerWriter{h, level, true}, "", 0)
+}
+
// Log emits a log record with the current time and the given level and message.
// The Record's Attrs consist of the Logger's attributes followed by
// the Attrs specified by args.
diff --git a/slog/logger_test.go b/slog/logger_test.go
index c7529eb..0729ca7 100644
--- a/slog/logger_test.go
+++ b/slog/logger_test.go
@@ -408,6 +408,14 @@
checkContext(l4)
}

+func TestNewLogLogger(t *testing.T) {
+ var buf bytes.Buffer
+ h := NewTextHandler(&buf)
+ ll := NewLogLogger(h, LevelWarn)
+ ll.Print("hello")
+ checkLogOutput(t, buf.String(), "time="+timeRE+` level=WARN msg=hello`)
+}
+
func checkLogOutput(t *testing.T, got, wantRegexp string) {
t.Helper()
got = clean(got)

To view, visit change 465356. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: exp
Gerrit-Branch: master
Gerrit-Change-Id: I7ebfba3404b6fe9960eeb7dccd5385d1166a4bcb
Gerrit-Change-Number: 465356
Gerrit-PatchSet: 3
Gerrit-Owner: Jonathan Amsterdam <j...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jonathan Amsterdam <j...@google.com>
Gerrit-Reviewer: Russ Cox <r...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages