Skip to content

Commit 5937bbe

Browse files
committed
feat: impl slog.Handler for geth v1.13. used in json-rpc
These changes update Nibiru's integration with the `go-ethereum/log` package to align with its upstream migration to Go's standard structured logging library (`slog`). The previous logging setup in Nibiru, which relied on `go-ethereum/log`'s deprecated `FuncHandler` and `Record` types, was removed. 1. **Added `LogHandler`:** A new file `app/server/geth_log_handler.go` introduces the `LogHandler` type. This type implements the standard `slog.Handler` interface. Its primary role is to receive log records generated by Geth components (which now use `slog`) and translate them into corresponding calls on Nibiru's standard `cmtlog.Logger` (CometBFT logger). It correctly maps Geth/`slog` levels (including `Trace` and `Crit`) and formats log attributes for compatibility. 2. **Updated Initialization:** In `app/server/json_rpc.go`, the old `ethlog.Root().SetHandler(...)` block was replaced. The code now instantiates the new `LogHandler` (providing it the context logger `ctx.Logger.With("module", "geth")`), wraps it using `gethlog.NewLogger()`, and sets the result as the default logger for `go-ethereum` components via `gethlog.SetDefault()`. The primary reason for this refactor was the breaking change in the `go-ethereum/log` dependency, which deprecated its custom logging implementation in favor of Go's standard `slog`. These changes adapt Nibiru to the new `slog`-based API, ensuring that logs generated within embedded Geth components are correctly captured and processed by Nibiru's existing logging infrastructure (`cmtlog.Logger`). This maintains consistent logging behavior and compatibility with the updated dependency.
1 parent 10010d6 commit 5937bbe

File tree

2 files changed

+118
-16
lines changed

2 files changed

+118
-16
lines changed

app/server/geth_log_handler.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package server
2+
3+
import (
4+
"context"
5+
cmtlog "github.com/cometbft/cometbft/libs/log"
6+
gethlog "github.com/ethereum/go-ethereum/log"
7+
8+
// Use "log/slog" from the Go std lib because Geth migrated to support
9+
// slog and deprecated the original go-ethereum/log implementation.
10+
// For more info on the migration, see https://github.com/ethereum/go-ethereum/pull/28187
11+
"golang.org/x/exp/slog"
12+
)
13+
14+
// Ensure LogHandler implements slog.Handler
15+
var _ slog.Handler = (*LogHandler)(nil)
16+
17+
// LogHandler implements slog.Handler, which is needed to construct the
18+
// conventional go-ethereum.Logger, using a CometBFT logger
19+
// ("github.com/cometbft/cometbft/libs/log".Logger).
20+
type LogHandler struct {
21+
CmtLogger cmtlog.Logger
22+
attrs []slog.Attr // Attributes gathered via WithAttrs
23+
group string // Group name gathered via WithGroup (simple implementation)
24+
}
25+
26+
// Enabled decides whether a log record should be processed.
27+
// We let the underlying CometBFT logger handle filtering.
28+
func (h *LogHandler) Enabled(_ context.Context, level slog.Level) bool {
29+
// You could potentially check the CmtLogger's level here if needed,
30+
// but returning true is usually sufficient.
31+
return true
32+
}
33+
34+
// Handle processes the log record and sends it to the CometBFT logger.
35+
func (h *LogHandler) Handle(_ context.Context, r slog.Record) error {
36+
// 1. Determine the corresponding CometBFT log function
37+
var logFunc func(msg string, keyvals ...interface{})
38+
switch r.Level {
39+
// Check against Geth's custom levels first if they exist
40+
// This handler covers all defined slog and go-ethereum log levels.
41+
case gethlog.LevelTrace, slog.LevelDebug: // Handles -8, -4
42+
logFunc = h.CmtLogger.Debug
43+
case slog.LevelInfo, slog.LevelWarn: // Handles 0, 4
44+
logFunc = h.CmtLogger.Info
45+
case gethlog.LevelCrit, slog.LevelError: // Handles 12, 8
46+
// Map Geth Crit level along with standard Error
47+
logFunc = h.CmtLogger.Error
48+
default: // Handle any other levels (e.g., below Debug)
49+
logFunc = h.CmtLogger.Debug // Default to Debug or Info as appropriate
50+
}
51+
52+
// 2. Collect attributes (key-value pairs)
53+
// Preallocate assuming 2 slots per attribute plus handler attrs
54+
keyvals := make([]interface{}, 0, (r.NumAttrs()+len(h.attrs))*2)
55+
56+
// Add attributes stored in the handler first (from WithAttrs)
57+
currentGroup := h.group
58+
for _, attr := range h.attrs {
59+
key := attr.Key
60+
if currentGroup != "" {
61+
key = currentGroup + "." + key // Basic grouping
62+
}
63+
keyvals = append(keyvals, key, attr.Value.Any())
64+
}
65+
66+
// Add attributes from the specific log record
67+
r.Attrs(func(attr slog.Attr) bool {
68+
key := attr.Key
69+
if currentGroup != "" {
70+
key = currentGroup + "." + key // Basic grouping
71+
}
72+
keyvals = append(keyvals, key, attr.Value.Any())
73+
return true // Continue iterating
74+
})
75+
76+
// 3. Call the CometBFT logger function
77+
logFunc(r.Message, keyvals...)
78+
79+
return nil // No error to return in this basic implementation
80+
}
81+
82+
// WithAttrs returns a new LogHandler with the provided attributes added.
83+
func (h *LogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
84+
// Create a new handler, cloning existing state and adding new attrs
85+
newHandler := &LogHandler{
86+
CmtLogger: h.CmtLogger, // Keep the same underlying logger
87+
// Important: Clone slices to avoid modifying the original handler's state
88+
attrs: append(append([]slog.Attr{}, h.attrs...), attrs...),
89+
group: h.group,
90+
}
91+
return newHandler
92+
}
93+
94+
// WithGroup returns a new LogHandler associated with the specified group.
95+
func (h *LogHandler) WithGroup(name string) slog.Handler {
96+
// Create a new handler, cloning attributes and setting/appending the group
97+
newHandler := &LogHandler{
98+
CmtLogger: h.CmtLogger,
99+
attrs: append([]slog.Attr{}, h.attrs...), // Clone attributes
100+
// Basic implementation: Overwrites group. Could concatenate if nesting needed.
101+
group: name,
102+
}
103+
// If nested groups are needed:
104+
// if h.group != "" {
105+
// name = h.group + "." + name
106+
// }
107+
// newHandler.group = name
108+
return newHandler
109+
}

app/server/json_rpc.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import (
1414
"github.com/cosmos/cosmos-sdk/client"
1515
"github.com/cosmos/cosmos-sdk/server"
1616
"github.com/cosmos/cosmos-sdk/server/types"
17-
ethlog "github.com/ethereum/go-ethereum/log"
18-
ethrpc "github.com/ethereum/go-ethereum/rpc"
17+
gethlog "github.com/ethereum/go-ethereum/log"
18+
gethrpc "github.com/ethereum/go-ethereum/rpc"
1919

2020
srvconfig "github.com/NibiruChain/nibiru/v2/app/server/config"
2121
)
@@ -31,20 +31,13 @@ func StartJSONRPC(
3131
) (*http.Server, chan struct{}, error) {
3232
tmWsClientForRPCApi := ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger)
3333

34-
logger := ctx.Logger.With("module", "geth")
35-
ethlog.Root().SetHandler(ethlog.FuncHandler(func(r *ethlog.Record) error {
36-
switch r.Lvl {
37-
case ethlog.LvlTrace, ethlog.LvlDebug:
38-
logger.Debug(r.Msg, r.Ctx...)
39-
case ethlog.LvlInfo, ethlog.LvlWarn:
40-
logger.Info(r.Msg, r.Ctx...)
41-
case ethlog.LvlError, ethlog.LvlCrit:
42-
logger.Error(r.Msg, r.Ctx...)
43-
}
44-
return nil
45-
}))
34+
// Configure the go-ethereum logger to sync with the ctx.Logger
35+
gethLogger := gethlog.NewLogger(&LogHandler{
36+
CmtLogger: ctx.Logger.With("module", "geth"),
37+
})
38+
gethlog.SetDefault(gethLogger)
4639

47-
rpcServer := ethrpc.NewServer()
40+
rpcServer := gethrpc.NewServer()
4841

4942
allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs
5043
rpcAPIArr := config.JSONRPC.API
@@ -53,7 +46,7 @@ func StartJSONRPC(
5346

5447
for _, api := range apis {
5548
if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil {
56-
ctx.Logger.Error(
49+
gethLogger.Error(
5750
"failed to register service in JSON RPC namespace",
5851
"namespace", api.Namespace,
5952
"service", api.Service,

0 commit comments

Comments
 (0)