diff --git a/build/handler_sets.go b/build/handler_sets.go index 97fc60064c..b417fc8c0e 100644 --- a/build/handler_sets.go +++ b/build/handler_sets.go @@ -169,3 +169,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 Handler +} + +// newSubLogGenerator constructs a new subLogGenerator from a Handler. +func newSubLogGenerator(handler 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) diff --git a/build/log.go b/build/log.go index 31be5d4d94..793b63fbbd 100644 --- a/build/log.go +++ b/build/log.go @@ -1,7 +1,7 @@ package build import ( - "io" + "os" "github.com/btcsuite/btclog" ) @@ -34,17 +34,6 @@ func (t LogType) String() string { } } -// 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. @@ -78,7 +67,7 @@ func NewSubLogger(subsystem string, // that they share the same backend, since all output is written // to std out. case LogTypeStdOut: - backend := btclog.NewBackend(&LogWriter{}) + backend := btclog.NewBackend(os.Stdout) logger := backend.Logger(subsystem) // Set the logging level of the stdout logger to use the diff --git a/build/log_default.go b/build/log_default.go index bbb6d4c390..6e027e0dd0 100644 --- a/build/log_default.go +++ b/build/log_default.go @@ -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 -} diff --git a/build/log_nolog.go b/build/log_nolog.go index 32199ada00..75f17bf66b 100644 --- a/build/log_nolog.go +++ b/build/log_nolog.go @@ -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 -} diff --git a/build/log_stdlog.go b/build/log_stdlog.go index 34a8c1bf02..461474376d 100644 --- a/build/log_stdlog.go +++ b/build/log_stdlog.go @@ -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 -} diff --git a/build/logrotator.go b/build/logrotator.go index 71928550aa..5d9de179a2 100644 --- a/build/logrotator.go +++ b/build/logrotator.go @@ -12,7 +12,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 } @@ -21,8 +22,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 @@ -57,11 +58,19 @@ func (r *RotatingLogWriter) InitLogRotator(logFile string, maxLogFileSize int, } }() - r.logWriter.RotatorPipe = pw + r.pipe = pw return nil } +// Write writes the byte slice to both stdout and 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 { diff --git a/build/sub_logger.go b/build/sub_logger.go index 2096757d0d..1084a07369 100644 --- a/build/sub_logger.go +++ b/build/sub_logger.go @@ -2,7 +2,6 @@ package build import ( "fmt" - "io" "sort" "strings" "sync" @@ -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 ...Handler) *SubLoggerManager { return &SubLoggerManager{ - loggers: SubLoggers{}, - genLogger: btclog.NewBackend(w), + loggers: SubLoggers{}, + genLogger: newSubLogGenerator( + newHandlerSet(btclog.LevelInfo, handlers...), + ), } } diff --git a/config.go b/config.go index c2258a0d0b..b38f6977d2 100644 --- a/config.go +++ b/config.go @@ -495,7 +495,6 @@ type Config struct { // LogMgr is the root logger that all the daemon's subloggers are // hooked up to. LogMgr *build.SubLoggerManager - LogWriter *build.LogWriter LogRotator *build.RotatingLogWriter // networkDir is the path to the directory of the currently active @@ -713,7 +712,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(), @@ -1435,14 +1434,20 @@ 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 ( + cliLogHander = build.NewCLIHandler(os.Stdout, false) + logHandlers []build.Handler + ) + switch build.LoggingType { + case build.LogTypeStdOut: + logHandlers = []build.Handler{cliLogHander} + case build.LogTypeDefault: + logHandlers = []build.Handler{ + cliLogHander, + build.NewLogFileHandler(cfg.LogRotator), + } } - - cfg.LogRotator = build.NewRotatingLogWriter(cfg.LogWriter) - cfg.LogMgr = build.NewSubLoggerManager(cfg.LogWriter) + cfg.LogMgr = build.NewSubLoggerManager(logHandlers...) // Special show command to list supported subsystems and exit. if cfg.DebugLevel == "show" {