Skip to content

Commit 825fc3e

Browse files
osmaczkodlipicar
authored andcommitted
chore: adapt to new geth logger
1 parent 7152777 commit 825fc3e

File tree

4 files changed

+102
-38
lines changed

4 files changed

+102
-38
lines changed

logutils/geth_adapter.go

Lines changed: 70 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package logutils
22

33
import (
4-
"fmt"
4+
"context"
5+
"log/slog"
56
"strings"
67

78
"go.uber.org/zap"
@@ -10,42 +11,78 @@ import (
1011
"github.com/ethereum/go-ethereum/log"
1112
)
1213

13-
// gethAdapter returns a log.Handler interface that forwards logs to a zap.Logger.
14-
// Logs are forwarded raw as if geth were printing them.
15-
func gethAdapter(logger *zap.Logger) log.Handler {
16-
return log.FuncHandler(func(r *log.Record) error {
17-
level, err := LvlFromString(r.Lvl.String())
18-
if err != nil {
19-
return err
20-
}
21-
// Skip trace logs to not clutter the output
22-
if level == traceLevel {
23-
return nil
24-
}
25-
serializedLog := string(log.TerminalFormat(false).Format(r))
26-
logger.Check(level, fmt.Sprintf("'%s'", strings.TrimSuffix(serializedLog, "\n"))).Write()
27-
return nil
28-
})
14+
type gethAdapter struct {
15+
log.Logger
16+
target *zap.Logger
17+
}
18+
19+
func newGethAdapter(target *zap.Logger) *gethAdapter {
20+
return &gethAdapter{
21+
Logger: log.NewLogger(log.DiscardHandler()),
22+
target: target,
23+
}
24+
}
25+
26+
func (g *gethAdapter) serializeLog(level slog.Level, msg string, ctx ...interface{}) string {
27+
buf := strings.Builder{}
28+
logger := log.NewLogger(log.LogfmtHandlerWithLevel(&buf, level))
29+
logger.Log(level, msg, ctx...)
30+
return buf.String()
31+
}
32+
33+
func (g *gethAdapter) Log(level slog.Level, msg string, ctx ...interface{}) {
34+
g.Write(level, msg, ctx...)
35+
}
36+
37+
func (g *gethAdapter) Trace(msg string, ctx ...interface{}) {
38+
g.Write(log.LevelTrace, msg, ctx...)
39+
}
40+
41+
func (g *gethAdapter) Debug(msg string, ctx ...interface{}) {
42+
g.Write(log.LevelDebug, msg, ctx...)
43+
}
44+
45+
func (g *gethAdapter) Info(msg string, ctx ...interface{}) {
46+
g.Write(log.LevelInfo, msg, ctx...)
47+
}
48+
49+
func (g *gethAdapter) Warn(msg string, ctx ...interface{}) {
50+
g.Write(log.LevelWarn, msg, ctx...)
51+
}
52+
53+
func (g *gethAdapter) Error(msg string, ctx ...interface{}) {
54+
g.Write(log.LevelError, msg, ctx...)
55+
}
56+
57+
func (g *gethAdapter) Crit(msg string, ctx ...interface{}) {
58+
g.Write(log.LevelCrit, msg, ctx...)
59+
}
60+
61+
func (g *gethAdapter) Write(level slog.Level, msg string, attrs ...any) {
62+
g.target.Check(zapLevelFromGeth(level), g.serializeLog(level, msg, attrs...)).Write()
63+
}
64+
65+
func (g *gethAdapter) Enabled(ctx context.Context, level slog.Level) bool {
66+
return g.target.Core().Enabled(zapLevelFromGeth(level)) && g.Logger.Enabled(ctx, level)
2967
}
3068

3169
const traceLevel = zapcore.DebugLevel - 1
3270

33-
// LvlFromString returns the appropriate zapcore.Level from a string.
34-
func LvlFromString(lvlString string) (zapcore.Level, error) {
35-
switch strings.ToLower(lvlString) {
36-
case "trace", "trce":
37-
return traceLevel, nil // zap does not have a trace level, use custom
38-
case "debug", "dbug":
39-
return zapcore.DebugLevel, nil
40-
case "info":
41-
return zapcore.InfoLevel, nil
42-
case "warn":
43-
return zapcore.WarnLevel, nil
44-
case "error", "eror":
45-
return zapcore.ErrorLevel, nil
46-
case "crit":
47-
return zapcore.DPanicLevel, nil // zap does not have a crit level, using DPanicLevel as closest
71+
func zapLevelFromGeth(lvl slog.Level) zapcore.Level {
72+
switch lvl {
73+
case log.LevelTrace:
74+
return traceLevel // zap does not have a trace level, use custom
75+
case log.LevelDebug:
76+
return zapcore.DebugLevel
77+
case log.LevelInfo:
78+
return zapcore.InfoLevel
79+
case log.LevelWarn:
80+
return zapcore.WarnLevel
81+
case log.LevelError:
82+
return zapcore.ErrorLevel
83+
case log.LevelCrit:
84+
return zapcore.DPanicLevel // zap does not have a crit level, using DPanicLevel as closest
4885
default:
49-
return zapcore.InvalidLevel, fmt.Errorf("unknown level: %v", lvlString)
86+
return zapcore.InvalidLevel
5087
}
5188
}

logutils/geth_adapter_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ func TestGethAdapter(t *testing.T) {
2323
)
2424
logger := zap.New(core)
2525

26-
log.Root().SetHandler(gethAdapter(logger))
26+
log.SetDefault(newGethAdapter(logger))
2727

2828
log.Debug("should not be printed, as it's below the log level")
2929
require.Empty(t, buffer.String())
3030

3131
buffer.Reset()
3232
log.Info("should be printed")
33-
require.Regexp(t, `INFO\s+'INFO\s*\[.*\]\s*should be printed '`, buffer.String())
33+
require.Regexp(t, `INFO\s+t=.* lvl=info msg="should be printed"`, buffer.String())
3434

3535
buffer.Reset()
3636
level.SetLevel(zap.DebugLevel)
3737
log.Debug("should be printed with context", "value1", 12345, "value2", "string")
38-
require.Regexp(t, `DEBUG\s+'DEBUG\s*\[.*\]\s*should be printed with context\s+value1=12345\s+value2=string'`, buffer.String())
38+
require.Regexp(t, `DEBUG\s+t=.* lvl=debug msg="should be printed with context" value1=12345 value2=string`, buffer.String())
3939

4040
buffer.Reset()
4141
log.Trace("should be skipped")

logutils/logger.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ func ZapLogger() *zap.Logger {
2222
_zapLogger = defaultLogger()
2323

2424
// forward geth logs to zap logger
25-
_gethLogger := _zapLogger.Named("geth")
26-
log.Root().SetHandler(gethAdapter(_gethLogger))
25+
log.SetDefault(newGethAdapter(_zapLogger.Named("geth")))
2726
})
2827
return _zapLogger
2928
}

logutils/lvl_from_string.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package logutils
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"go.uber.org/zap/zapcore"
8+
)
9+
10+
// LvlFromString returns the appropriate zapcore.Level from a string.
11+
func LvlFromString(lvlString string) (zapcore.Level, error) {
12+
switch strings.ToLower(lvlString) {
13+
case "trace", "trce":
14+
return traceLevel, nil // zap does not have a trace level, use custom
15+
case "debug", "dbug":
16+
return zapcore.DebugLevel, nil
17+
case "info":
18+
return zapcore.InfoLevel, nil
19+
case "warn":
20+
return zapcore.WarnLevel, nil
21+
case "error", "eror":
22+
return zapcore.ErrorLevel, nil
23+
case "crit":
24+
return zapcore.DPanicLevel, nil // zap does not have a crit level, using DPanicLevel as closest
25+
default:
26+
return zapcore.InvalidLevel, fmt.Errorf("unknown level: %v", lvlString)
27+
}
28+
}

0 commit comments

Comments
 (0)