chore(logging)_: introduce geth adapter

This commit is contained in:
Patryk Osmaczko 2024-11-04 09:01:06 +01:00 committed by osmaczko
parent ed36d60540
commit d18dfeffca
2 changed files with 94 additions and 0 deletions

51
logutils/geth_adapter.go Normal file
View File

@ -0,0 +1,51 @@
package logutils
import (
"fmt"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"github.com/ethereum/go-ethereum/log"
)
// gethAdapter returns a log.Handler interface that forwards logs to a zap.Logger.
// Logs are forwarded raw as if geth were printing them.
func gethAdapter(logger *zap.Logger) log.Handler {
return log.FuncHandler(func(r *log.Record) error {
level, err := lvlFromString(r.Lvl.String())
if err != nil {
return err
}
// Skip trace logs to not clutter the output
if level == traceLevel {
return nil
}
serializedLog := string(log.TerminalFormat(false).Format(r))
logger.Check(level, fmt.Sprintf("'%s'", strings.TrimSuffix(serializedLog, "\n"))).Write()
return nil
})
}
const traceLevel = zapcore.DebugLevel - 1
// lvlFromString returns the appropriate zapcore.Level from a string.
func lvlFromString(lvlString string) (zapcore.Level, error) {
switch strings.ToLower(lvlString) {
case "trace", "trce":
return traceLevel, nil // zap does not have a trace level, use custom
case "debug", "dbug":
return zapcore.DebugLevel, nil
case "info":
return zapcore.InfoLevel, nil
case "warn":
return zapcore.WarnLevel, nil
case "error", "eror":
return zapcore.ErrorLevel, nil
case "crit":
return zapcore.DPanicLevel, nil // zap does not have a crit level, using DPanicLevel as closest
default:
return zapcore.InvalidLevel, fmt.Errorf("unknown level: %v", lvlString)
}
}

View File

@ -0,0 +1,43 @@
package logutils
import (
"bytes"
"testing"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/log"
)
func TestGethAdapter(t *testing.T) {
level := zap.NewAtomicLevelAt(zap.InfoLevel)
buffer := bytes.NewBuffer(nil)
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
zapcore.AddSync(buffer),
level,
)
logger := zap.New(core)
log.Root().SetHandler(gethAdapter(logger))
log.Debug("should not be printed, as it's below the log level")
require.Empty(t, buffer.String())
buffer.Reset()
log.Info("should be printed")
require.Regexp(t, `INFO\s+'INFO\s*\[.*\]\s*should be printed '`, buffer.String())
buffer.Reset()
level.SetLevel(zap.DebugLevel)
log.Debug("should be printed with context", "value1", 12345, "value2", "string")
require.Regexp(t, `DEBUG\s+'DEBUG\s*\[.*\]\s*should be printed with context\s+value1=12345\s+value2=string'`, buffer.String())
buffer.Reset()
log.Trace("should be skipped")
require.Empty(t, buffer.String())
}