mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-02 23:15:36 +02:00
build: move log rotator code
This commit is contained in:
151
build/logrotator.go
Normal file
151
build/logrotator.go
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btclog"
|
||||||
|
"github.com/jrick/logrotate/rotator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RotatingLogWriter is a wrapper around the LogWriter that supports log file
|
||||||
|
// rotation.
|
||||||
|
type RotatingLogWriter struct {
|
||||||
|
// GenSubLogger is a function that returns a new logger for a subsystem
|
||||||
|
// belonging to the current RotatingLogWriter.
|
||||||
|
GenSubLogger func(string) btclog.Logger
|
||||||
|
|
||||||
|
logWriter *LogWriter
|
||||||
|
|
||||||
|
backendLog *btclog.Backend
|
||||||
|
|
||||||
|
logRotator *rotator.Rotator
|
||||||
|
|
||||||
|
subsystemLoggers SubLoggers
|
||||||
|
}
|
||||||
|
|
||||||
|
// A compile time check to ensure RotatingLogWriter implements the
|
||||||
|
// LeveledSubLogger interface.
|
||||||
|
var _ LeveledSubLogger = (*RotatingLogWriter)(nil)
|
||||||
|
|
||||||
|
// NewRotatingLogWriter creates a new file rotating log writer.
|
||||||
|
//
|
||||||
|
// NOTE: `InitLogRotator` must be called to set up log rotation after creating
|
||||||
|
// the writer.
|
||||||
|
func NewRotatingLogWriter() *RotatingLogWriter {
|
||||||
|
logWriter := &LogWriter{}
|
||||||
|
backendLog := btclog.NewBackend(logWriter)
|
||||||
|
return &RotatingLogWriter{
|
||||||
|
GenSubLogger: backendLog.Logger,
|
||||||
|
logWriter: logWriter,
|
||||||
|
backendLog: backendLog,
|
||||||
|
subsystemLoggers: SubLoggers{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterSubLogger registers a new subsystem logger.
|
||||||
|
func (r *RotatingLogWriter) RegisterSubLogger(subsystem string,
|
||||||
|
logger btclog.Logger) {
|
||||||
|
|
||||||
|
r.subsystemLoggers[subsystem] = logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitLogRotator initializes the log file rotator to write logs to logFile and
|
||||||
|
// create roll files in the same directory. It should be called as early on
|
||||||
|
// startup and possible and must be closed on shutdown by calling `Close`.
|
||||||
|
func (r *RotatingLogWriter) InitLogRotator(logFile string, maxLogFileSize int,
|
||||||
|
maxLogFiles int) error {
|
||||||
|
|
||||||
|
logDir, _ := filepath.Split(logFile)
|
||||||
|
err := os.MkdirAll(logDir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create log directory: %v", err)
|
||||||
|
}
|
||||||
|
r.logRotator, err = rotator.New(
|
||||||
|
logFile, int64(maxLogFileSize*1024), false, maxLogFiles,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create file rotator: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run rotator as a goroutine now but make sure we catch any errors
|
||||||
|
// that happen in case something with the rotation goes wrong during
|
||||||
|
// runtime (like running out of disk space or not being allowed to
|
||||||
|
// create a new logfile for whatever reason).
|
||||||
|
pr, pw := io.Pipe()
|
||||||
|
go func() {
|
||||||
|
err := r.logRotator.Run(pr)
|
||||||
|
if err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr,
|
||||||
|
"failed to run file rotator: %v\n", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
r.logWriter.RotatorPipe = pw
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the underlying log rotator if it has already been created.
|
||||||
|
func (r *RotatingLogWriter) Close() error {
|
||||||
|
if r.logRotator != nil {
|
||||||
|
return r.logRotator.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubLoggers returns all currently registered subsystem loggers for this log
|
||||||
|
// writer.
|
||||||
|
//
|
||||||
|
// NOTE: This is part of the LeveledSubLogger interface.
|
||||||
|
func (r *RotatingLogWriter) SubLoggers() SubLoggers {
|
||||||
|
return r.subsystemLoggers
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupportedSubsystems returns a sorted string slice of all keys in the
|
||||||
|
// subsystems map, corresponding to the names of the subsystems.
|
||||||
|
//
|
||||||
|
// NOTE: This is part of the LeveledSubLogger interface.
|
||||||
|
func (r *RotatingLogWriter) SupportedSubsystems() []string {
|
||||||
|
// Convert the subsystemLoggers map keys to a string slice.
|
||||||
|
subsystems := make([]string, 0, len(r.subsystemLoggers))
|
||||||
|
for subsysID := range r.subsystemLoggers {
|
||||||
|
subsystems = append(subsystems, subsysID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the subsystems for stable display.
|
||||||
|
sort.Strings(subsystems)
|
||||||
|
return subsystems
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogLevel sets the logging level for provided subsystem. Invalid
|
||||||
|
// subsystems are ignored. Uninitialized subsystems are dynamically created as
|
||||||
|
// needed.
|
||||||
|
//
|
||||||
|
// NOTE: This is part of the LeveledSubLogger interface.
|
||||||
|
func (r *RotatingLogWriter) SetLogLevel(subsystemID string, logLevel string) {
|
||||||
|
// Ignore invalid subsystems.
|
||||||
|
logger, ok := r.subsystemLoggers[subsystemID]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaults to info if the log level is invalid.
|
||||||
|
level, _ := btclog.LevelFromString(logLevel)
|
||||||
|
logger.SetLevel(level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogLevels sets the log level for all subsystem loggers to the passed
|
||||||
|
// level. It also dynamically creates the subsystem loggers as needed, so it
|
||||||
|
// can be used to initialize the logging system.
|
||||||
|
//
|
||||||
|
// NOTE: This is part of the LeveledSubLogger interface.
|
||||||
|
func (r *RotatingLogWriter) SetLogLevels(logLevel string) {
|
||||||
|
// Configure all sub-systems with the new logging level. Dynamically
|
||||||
|
// create loggers as needed.
|
||||||
|
for subsystemID := range r.subsystemLoggers {
|
||||||
|
r.SetLogLevel(subsystemID, logLevel)
|
||||||
|
}
|
||||||
|
}
|
@@ -958,10 +958,11 @@ func loadConfig() (*config, error) {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Initialize logging at the default logging level.
|
// Initialize logging at the default logging level.
|
||||||
|
/*TODO(guggero) fix
|
||||||
initLogRotator(
|
initLogRotator(
|
||||||
filepath.Join(cfg.LogDir, defaultLogFilename),
|
filepath.Join(cfg.LogDir, defaultLogFilename),
|
||||||
cfg.MaxLogFileSize, cfg.MaxLogFiles,
|
cfg.MaxLogFileSize, cfg.MaxLogFiles,
|
||||||
)
|
)*/
|
||||||
|
|
||||||
// Parse, validate, and set debug log level(s).
|
// Parse, validate, and set debug log level(s).
|
||||||
/*TODO(guggero) fix
|
/*TODO(guggero) fix
|
||||||
|
53
log.go
53
log.go
@@ -2,10 +2,6 @@ package lnd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/connmgr"
|
"github.com/btcsuite/btcd/connmgr"
|
||||||
"github.com/btcsuite/btclog"
|
"github.com/btcsuite/btclog"
|
||||||
@@ -173,55 +169,6 @@ var subsystemLoggers = map[string]btclog.Logger{
|
|||||||
"PRNF": prnfLog,
|
"PRNF": prnfLog,
|
||||||
}
|
}
|
||||||
|
|
||||||
// initLogRotator initializes the logging rotator to write logs to logFile and
|
|
||||||
// create roll files in the same directory. It must be called before the
|
|
||||||
// package-global log rotator variables are used.
|
|
||||||
func initLogRotator(logFile string, MaxLogFileSize int, MaxLogFiles int) {
|
|
||||||
logDir, _ := filepath.Split(logFile)
|
|
||||||
err := os.MkdirAll(logDir, 0700)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
r, err := rotator.New(logFile, int64(MaxLogFileSize*1024), false, MaxLogFiles)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
go r.Run(pr)
|
|
||||||
|
|
||||||
logWriter.RotatorPipe = pw
|
|
||||||
logRotator = r
|
|
||||||
}
|
|
||||||
|
|
||||||
// setLogLevel sets the logging level for provided subsystem. Invalid
|
|
||||||
// subsystems are ignored. Uninitialized subsystems are dynamically created as
|
|
||||||
// needed.
|
|
||||||
func setLogLevel(subsystemID string, logLevel string) {
|
|
||||||
// Ignore invalid subsystems.
|
|
||||||
logger, ok := subsystemLoggers[subsystemID]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults to info if the log level is invalid.
|
|
||||||
level, _ := btclog.LevelFromString(logLevel)
|
|
||||||
logger.SetLevel(level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// setLogLevels sets the log level for all subsystem loggers to the passed
|
|
||||||
// level. It also dynamically creates the subsystem loggers as needed, so it
|
|
||||||
// can be used to initialize the logging system.
|
|
||||||
func setLogLevels(logLevel string) {
|
|
||||||
// Configure all sub-systems with the new logging level. Dynamically
|
|
||||||
// create loggers as needed.
|
|
||||||
for subsystemID := range subsystemLoggers {
|
|
||||||
setLogLevel(subsystemID, logLevel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// logClosure is used to provide a closure over expensive logging operations so
|
// logClosure is used to provide a closure over expensive logging operations so
|
||||||
// don't have to be performed when the logging level doesn't warrant it.
|
// don't have to be performed when the logging level doesn't warrant it.
|
||||||
type logClosure func() string
|
type logClosure func() string
|
||||||
|
Reference in New Issue
Block a user