build: switch to slog Handlers

Start using the new slog handlers. With this commit we also remove the
need for the LogWriter since we let our LogRotator implement io.Writer
and pass that in to our log file handler.
This commit is contained in:
Elle Mouton 2024-10-15 14:34:24 +02:00
parent 9a9761008c
commit cd697913ef
No known key found for this signature in database
GPG Key ID: D7D916376026F177
11 changed files with 130 additions and 116 deletions

View File

@ -175,3 +175,27 @@ func (r *reducedSet) WithGroup(name string) slog.Handler {
// A compile-time check to ensure that handlerSet implements slog.Handler.
var _ slog.Handler = (*reducedSet)(nil)
// subLogGenerator implements the SubLogCreator backed by a Handler.
type subLogGenerator struct {
handler btclog.Handler
}
// newSubLogGenerator constructs a new subLogGenerator from a Handler.
func newSubLogGenerator(handler btclog.Handler) *subLogGenerator {
return &subLogGenerator{
handler: handler,
}
}
// Logger returns a new logger for a particular sub-system.
//
// NOTE: this is part of the SubLogCreator interface.
func (b *subLogGenerator) Logger(subsystemTag string) btclog.Logger {
handler := b.handler.SubSystem(subsystemTag)
return btclog.NewSLogger(handler)
}
// A compile-time check to ensure that handlerSet implements slog.Handler.
var _ SubLogCreator = (*subLogGenerator)(nil)

View File

@ -1,9 +1,9 @@
package build
import (
"io"
"os"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btclog/v2"
)
// LogType is an indicating the type of logging specified by the build flag.
@ -60,17 +60,6 @@ func SuportedLogCompressor(logCompressor string) bool {
return ok
}
// LogWriter is a stub type whose behavior can be changed using the build flags
// "stdlog" and "nolog". The default behavior is to write to both stdout and the
// RotatorPipe. Passing "stdlog" will cause it only to write to stdout, and
// "nolog" implements Write as a no-op.
type LogWriter struct {
// RotatorPipe is the write-end pipe for writing to the log rotator. It
// is written to by the Write method of the LogWriter type. This only
// needs to be set if neither the stdlog or nolog builds are set.
RotatorPipe *io.PipeWriter
}
// NewSubLogger constructs a new subsystem log from the current LogWriter
// implementation. This is primarily intended for use with stdlog, as the actual
// writer is shared amongst all instantiations.
@ -104,8 +93,10 @@ func NewSubLogger(subsystem string,
// that they share the same backend, since all output is written
// to std out.
case LogTypeStdOut:
backend := btclog.NewBackend(&LogWriter{})
logger := backend.Logger(subsystem)
backend := btclog.NewDefaultHandler(os.Stdout)
logger := btclog.NewSLogger(
backend.SubSystem(subsystem),
)
// Set the logging level of the stdout logger to use the
// configured logging level specified by build flags.

View File

@ -3,17 +3,6 @@
package build
import "os"
// LoggingType is a log type that writes to both stdout and the log rotator, if
// present.
const LoggingType = LogTypeDefault
// Write writes the byte slice to both stdout and the log rotator, if present.
func (w *LogWriter) Write(b []byte) (int, error) {
os.Stdout.Write(b)
if w.RotatorPipe != nil {
w.RotatorPipe.Write(b)
}
return len(b), nil
}

View File

@ -5,8 +5,3 @@ package build
// LoggingType is a log type that writes no logs.
const LoggingType = LogTypeNone
// Write is a noop.
func (w *LogWriter) Write(b []byte) (int, error) {
return len(b), nil
}

View File

@ -1,7 +1,7 @@
package build
import (
"github.com/btcsuite/btclog"
"github.com/btcsuite/btclog/v2"
)
// ShutdownLogger wraps an existing logger with a shutdown function which will

View File

@ -3,13 +3,5 @@
package build
import "os"
// LoggingType is a log type that only writes to stdout.
const LoggingType = LogTypeStdOut
// Write writes the provided byte slice to stdout.
func (w *LogWriter) Write(b []byte) (int, error) {
os.Stdout.Write(b)
return len(b), nil
}

View File

@ -3,7 +3,7 @@ package build_test
import (
"testing"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btclog/v2"
"github.com/lightningnetwork/lnd/build"
"github.com/stretchr/testify/require"
)

View File

@ -14,7 +14,8 @@ import (
// RotatingLogWriter is a wrapper around the LogWriter that supports log file
// rotation.
type RotatingLogWriter struct {
logWriter *LogWriter
// pipe is the write-end pipe for writing to the log rotator.
pipe *io.PipeWriter
rotator *rotator.Rotator
}
@ -23,8 +24,8 @@ type RotatingLogWriter struct {
//
// NOTE: `InitLogRotator` must be called to set up log rotation after creating
// the writer.
func NewRotatingLogWriter(w *LogWriter) *RotatingLogWriter {
return &RotatingLogWriter{logWriter: w}
func NewRotatingLogWriter() *RotatingLogWriter {
return &RotatingLogWriter{}
}
// InitLogRotator initializes the log file rotator to write logs to logFile and
@ -80,11 +81,20 @@ func (r *RotatingLogWriter) InitLogRotator(logFile, logCompressor string,
}
}()
r.logWriter.RotatorPipe = pw
r.pipe = pw
return nil
}
// Write writes the byte slice to the log rotator, if present.
func (r *RotatingLogWriter) Write(b []byte) (int, error) {
if r.rotator != nil {
return r.rotator.Write(b)
}
return len(b), nil
}
// Close closes the underlying log rotator if it has already been created.
func (r *RotatingLogWriter) Close() error {
if r.rotator != nil {

View File

@ -2,12 +2,11 @@ package build
import (
"fmt"
"io"
"sort"
"strings"
"sync"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btclog/v2"
)
// SubLogCreator can be used to create a new logger for a particular subsystem.
@ -30,10 +29,12 @@ type SubLoggerManager struct {
var _ LeveledSubLogger = (*SubLoggerManager)(nil)
// NewSubLoggerManager constructs a new SubLoggerManager.
func NewSubLoggerManager(w io.Writer) *SubLoggerManager {
func NewSubLoggerManager(handlers ...btclog.Handler) *SubLoggerManager {
return &SubLoggerManager{
loggers: SubLoggers{},
genLogger: btclog.NewBackend(w),
loggers: make(SubLoggers),
genLogger: newSubLogGenerator(
newHandlerSet(btclog.LevelInfo, handlers...),
),
}
}

View File

@ -21,6 +21,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btclog/v2"
flags "github.com/jessevdk/go-flags"
"github.com/lightninglabs/neutrino"
"github.com/lightningnetwork/lnd/autopilot"
@ -497,7 +498,6 @@ type Config struct {
// SubLogMgr is the root logger that all the daemon's subloggers are
// hooked up to.
SubLogMgr *build.SubLoggerManager
LogWriter *build.LogWriter
LogRotator *build.RotatingLogWriter
// networkDir is the path to the directory of the currently active
@ -716,7 +716,7 @@ func DefaultConfig() Config {
MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation,
MaxCommitFeeRateAnchors: lnwallet.DefaultAnchorsCommitMaxFeeRateSatPerVByte,
MaxFeeExposure: uint64(htlcswitch.DefaultMaxFeeExposure.ToSatoshis()),
LogWriter: &build.LogWriter{},
LogRotator: build.NewRotatingLogWriter(),
DB: lncfg.DefaultDB(),
Cluster: lncfg.DefaultCluster(),
RPCMiddleware: lncfg.DefaultRPCMiddleware(),
@ -1402,10 +1402,18 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
lncfg.NormalizeNetwork(cfg.ActiveNetParams.Name),
)
// A log writer must be passed in, otherwise we can't function and would
// run into a panic later on.
if cfg.LogWriter == nil {
return nil, mkErr("log writer missing in config")
var (
consoleLogHander = btclog.NewDefaultHandler(os.Stdout)
logHandlers []btclog.Handler
)
switch build.LoggingType {
case build.LogTypeStdOut:
logHandlers = []btclog.Handler{consoleLogHander}
case build.LogTypeDefault:
logHandlers = []btclog.Handler{
consoleLogHander,
btclog.NewDefaultHandler(cfg.LogRotator),
}
}
if !build.SuportedLogCompressor(cfg.LogCompressor) {
@ -1413,8 +1421,7 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
cfg.LogCompressor)
}
cfg.LogRotator = build.NewRotatingLogWriter(cfg.LogWriter)
cfg.SubLogMgr = build.NewSubLoggerManager(cfg.LogWriter)
cfg.SubLogMgr = build.NewSubLoggerManager(logHandlers...)
// Initialize logging at the default logging level.
SetupLoggers(cfg.SubLogMgr, interceptor)

121
log.go
View File

@ -3,7 +3,8 @@ package lnd
import (
"github.com/btcsuite/btcd/connmgr"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btclog"
btclogv1 "github.com/btcsuite/btclog"
"github.com/btcsuite/btclog/v2"
"github.com/lightninglabs/neutrino"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/autopilot"
@ -116,6 +117,8 @@ func genSubLogger(root *build.SubLoggerManager,
}
// SetupLoggers initializes all package-global logger variables.
//
//nolint:lll
func SetupLoggers(root *build.SubLoggerManager, interceptor signal.Interceptor) {
genLogger := genSubLogger(root, interceptor)
@ -123,7 +126,7 @@ func SetupLoggers(root *build.SubLoggerManager, interceptor signal.Interceptor)
// placeholder lnd package loggers.
for _, l := range lndPkgLoggers {
l.Logger = build.NewSubLogger(l.subsystem, genLogger)
SetSubLogger(root, l.subsystem, l.Logger)
SetV1SubLogger(root, l.subsystem, l.Logger)
}
// Initialize loggers from packages outside of `lnd` first. The
@ -132,69 +135,69 @@ func SetupLoggers(root *build.SubLoggerManager, interceptor signal.Interceptor)
// `btcwallet.chain`, which is overwritten by `lnwallet`. To ensure the
// overwriting works, we need to initialize the loggers here so they
// can be overwritten later.
AddSubLogger(root, "BTCN", interceptor, neutrino.UseLogger)
AddSubLogger(root, "CMGR", interceptor, connmgr.UseLogger)
AddSubLogger(root, "RPCC", interceptor, rpcclient.UseLogger)
AddV1SubLogger(root, "BTCN", interceptor, neutrino.UseLogger)
AddV1SubLogger(root, "CMGR", interceptor, connmgr.UseLogger)
AddV1SubLogger(root, "RPCC", interceptor, rpcclient.UseLogger)
// Some of the loggers declared in the main lnd package are also used
// in sub packages.
signal.UseLogger(ltndLog)
autopilot.UseLogger(atplLog)
AddSubLogger(root, "LNWL", interceptor, lnwallet.UseLogger)
AddSubLogger(root, "DISC", interceptor, discovery.UseLogger)
AddSubLogger(root, "NTFN", interceptor, chainntnfs.UseLogger)
AddSubLogger(root, "CHDB", interceptor, channeldb.UseLogger)
AddSubLogger(root, "HSWC", interceptor, htlcswitch.UseLogger)
AddSubLogger(root, "CNCT", interceptor, contractcourt.UseLogger)
AddSubLogger(root, "UTXN", interceptor, contractcourt.UseNurseryLogger)
AddSubLogger(root, "BRAR", interceptor, contractcourt.UseBreachLogger)
AddSubLogger(root, "SPHX", interceptor, sphinx.UseLogger)
AddSubLogger(root, "SWPR", interceptor, sweep.UseLogger)
AddSubLogger(root, "SGNR", interceptor, signrpc.UseLogger)
AddSubLogger(root, "WLKT", interceptor, walletrpc.UseLogger)
AddSubLogger(root, "ARPC", interceptor, autopilotrpc.UseLogger)
AddSubLogger(root, "NRPC", interceptor, neutrinorpc.UseLogger)
AddSubLogger(root, "DRPC", interceptor, devrpc.UseLogger)
AddSubLogger(root, "INVC", interceptor, invoices.UseLogger)
AddSubLogger(root, "NANN", interceptor, netann.UseLogger)
AddSubLogger(root, "WTWR", interceptor, watchtower.UseLogger)
AddSubLogger(root, "NTFR", interceptor, chainrpc.UseLogger)
AddSubLogger(root, "IRPC", interceptor, invoicesrpc.UseLogger)
AddSubLogger(root, "CHNF", interceptor, channelnotifier.UseLogger)
AddSubLogger(root, "CHBU", interceptor, chanbackup.UseLogger)
AddSubLogger(root, "PROM", interceptor, monitoring.UseLogger)
AddSubLogger(root, "WTCL", interceptor, wtclient.UseLogger)
AddSubLogger(root, "PRNF", interceptor, peernotifier.UseLogger)
AddSubLogger(root, "CHFD", interceptor, chanfunding.UseLogger)
AddSubLogger(root, "PEER", interceptor, peer.UseLogger)
AddSubLogger(root, "CHCL", interceptor, chancloser.UseLogger)
AddV1SubLogger(root, "LNWL", interceptor, lnwallet.UseLogger)
AddV1SubLogger(root, "DISC", interceptor, discovery.UseLogger)
AddV1SubLogger(root, "NTFN", interceptor, chainntnfs.UseLogger)
AddV1SubLogger(root, "CHDB", interceptor, channeldb.UseLogger)
AddV1SubLogger(root, "HSWC", interceptor, htlcswitch.UseLogger)
AddV1SubLogger(root, "CNCT", interceptor, contractcourt.UseLogger)
AddV1SubLogger(root, "UTXN", interceptor, contractcourt.UseNurseryLogger)
AddV1SubLogger(root, "BRAR", interceptor, contractcourt.UseBreachLogger)
AddV1SubLogger(root, "SPHX", interceptor, sphinx.UseLogger)
AddV1SubLogger(root, "SWPR", interceptor, sweep.UseLogger)
AddV1SubLogger(root, "SGNR", interceptor, signrpc.UseLogger)
AddV1SubLogger(root, "WLKT", interceptor, walletrpc.UseLogger)
AddV1SubLogger(root, "ARPC", interceptor, autopilotrpc.UseLogger)
AddV1SubLogger(root, "NRPC", interceptor, neutrinorpc.UseLogger)
AddV1SubLogger(root, "DRPC", interceptor, devrpc.UseLogger)
AddV1SubLogger(root, "INVC", interceptor, invoices.UseLogger)
AddV1SubLogger(root, "NANN", interceptor, netann.UseLogger)
AddV1SubLogger(root, "WTWR", interceptor, watchtower.UseLogger)
AddV1SubLogger(root, "NTFR", interceptor, chainrpc.UseLogger)
AddV1SubLogger(root, "IRPC", interceptor, invoicesrpc.UseLogger)
AddV1SubLogger(root, "CHNF", interceptor, channelnotifier.UseLogger)
AddV1SubLogger(root, "CHBU", interceptor, chanbackup.UseLogger)
AddV1SubLogger(root, "PROM", interceptor, monitoring.UseLogger)
AddV1SubLogger(root, "WTCL", interceptor, wtclient.UseLogger)
AddV1SubLogger(root, "PRNF", interceptor, peernotifier.UseLogger)
AddV1SubLogger(root, "CHFD", interceptor, chanfunding.UseLogger)
AddV1SubLogger(root, "PEER", interceptor, peer.UseLogger)
AddV1SubLogger(root, "CHCL", interceptor, chancloser.UseLogger)
AddSubLogger(root, routing.Subsystem, interceptor, routing.UseLogger)
AddSubLogger(root, routerrpc.Subsystem, interceptor, routerrpc.UseLogger)
AddSubLogger(root, chanfitness.Subsystem, interceptor, chanfitness.UseLogger)
AddSubLogger(root, verrpc.Subsystem, interceptor, verrpc.UseLogger)
AddSubLogger(root, healthcheck.Subsystem, interceptor, healthcheck.UseLogger)
AddSubLogger(root, chainreg.Subsystem, interceptor, chainreg.UseLogger)
AddSubLogger(root, chanacceptor.Subsystem, interceptor, chanacceptor.UseLogger)
AddSubLogger(root, funding.Subsystem, interceptor, funding.UseLogger)
AddSubLogger(root, cluster.Subsystem, interceptor, cluster.UseLogger)
AddSubLogger(root, rpcperms.Subsystem, interceptor, rpcperms.UseLogger)
AddSubLogger(root, tor.Subsystem, interceptor, tor.UseLogger)
AddSubLogger(root, btcwallet.Subsystem, interceptor, btcwallet.UseLogger)
AddSubLogger(root, rpcwallet.Subsystem, interceptor, rpcwallet.UseLogger)
AddSubLogger(root, peersrpc.Subsystem, interceptor, peersrpc.UseLogger)
AddSubLogger(root, graph.Subsystem, interceptor, graph.UseLogger)
AddSubLogger(root, lncfg.Subsystem, interceptor, lncfg.UseLogger)
AddSubLogger(
AddV1SubLogger(root, routing.Subsystem, interceptor, routing.UseLogger)
AddV1SubLogger(root, routerrpc.Subsystem, interceptor, routerrpc.UseLogger)
AddV1SubLogger(root, chanfitness.Subsystem, interceptor, chanfitness.UseLogger)
AddV1SubLogger(root, verrpc.Subsystem, interceptor, verrpc.UseLogger)
AddV1SubLogger(root, healthcheck.Subsystem, interceptor, healthcheck.UseLogger)
AddV1SubLogger(root, chainreg.Subsystem, interceptor, chainreg.UseLogger)
AddV1SubLogger(root, chanacceptor.Subsystem, interceptor, chanacceptor.UseLogger)
AddV1SubLogger(root, funding.Subsystem, interceptor, funding.UseLogger)
AddV1SubLogger(root, cluster.Subsystem, interceptor, cluster.UseLogger)
AddV1SubLogger(root, rpcperms.Subsystem, interceptor, rpcperms.UseLogger)
AddV1SubLogger(root, tor.Subsystem, interceptor, tor.UseLogger)
AddV1SubLogger(root, btcwallet.Subsystem, interceptor, btcwallet.UseLogger)
AddV1SubLogger(root, rpcwallet.Subsystem, interceptor, rpcwallet.UseLogger)
AddV1SubLogger(root, peersrpc.Subsystem, interceptor, peersrpc.UseLogger)
AddV1SubLogger(root, graph.Subsystem, interceptor, graph.UseLogger)
AddV1SubLogger(root, lncfg.Subsystem, interceptor, lncfg.UseLogger)
AddV1SubLogger(
root, blindedpath.Subsystem, interceptor, blindedpath.UseLogger,
)
}
// AddSubLogger is a helper method to conveniently create and register the
// AddV1SubLogger is a helper method to conveniently create and register the
// logger of one or more sub systems.
func AddSubLogger(root *build.SubLoggerManager, subsystem string,
interceptor signal.Interceptor, useLoggers ...func(btclog.Logger)) {
func AddV1SubLogger(root *build.SubLoggerManager, subsystem string,
interceptor signal.Interceptor, useLoggers ...func(btclogv1.Logger)) {
// genSubLogger will return a callback for creating a logger instance,
// which we will give to the root logger.
@ -203,13 +206,15 @@ func AddSubLogger(root *build.SubLoggerManager, subsystem string,
// Create and register just a single logger to prevent them from
// overwriting each other internally.
logger := build.NewSubLogger(subsystem, genLogger)
SetSubLogger(root, subsystem, logger, useLoggers...)
SetV1SubLogger(root, subsystem, logger, useLoggers...)
}
// SetSubLogger is a helper method to conveniently register the logger of a sub
// system.
func SetSubLogger(root *build.SubLoggerManager, subsystem string,
logger btclog.Logger, useLoggers ...func(btclog.Logger)) {
// SetV1SubLogger is a helper method to conveniently register the logger of a
// sub system. Note that the btclog v2 logger implements the btclog v1 logger
// which is why we can pass the v2 logger to the UseLogger call-backs that
// expect the v1 logger.
func SetV1SubLogger(root *build.SubLoggerManager, subsystem string,
logger btclog.Logger, useLoggers ...func(btclogv1.Logger)) {
root.RegisterSubLogger(subsystem, logger)
for _, useLogger := range useLoggers {