mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
22c13790df
Add deprecation notices but continue to read both.
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package build
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/jrick/logrotate/rotator"
|
|
"github.com/klauspost/compress/zstd"
|
|
)
|
|
|
|
// RotatingLogWriter is a wrapper around the LogWriter that supports log file
|
|
// rotation.
|
|
type RotatingLogWriter struct {
|
|
// pipe is the write-end pipe for writing to the log rotator.
|
|
pipe *io.PipeWriter
|
|
|
|
rotator *rotator.Rotator
|
|
}
|
|
|
|
// 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 {
|
|
return &RotatingLogWriter{}
|
|
}
|
|
|
|
// 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(cfg *FileLoggerConfig,
|
|
logFile string) error {
|
|
|
|
logDir, _ := filepath.Split(logFile)
|
|
err := os.MkdirAll(logDir, 0700)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create log directory: %w", err)
|
|
}
|
|
|
|
r.rotator, err = rotator.New(
|
|
logFile, int64(cfg.MaxLogFileSize*1024), false, cfg.MaxLogFiles,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create file rotator: %w", err)
|
|
}
|
|
|
|
// Reject unknown compressors.
|
|
if !SupportedLogCompressor(cfg.Compressor) {
|
|
return fmt.Errorf("unknown log compressor: %v", cfg.Compressor)
|
|
}
|
|
|
|
var c rotator.Compressor
|
|
switch cfg.Compressor {
|
|
case Gzip:
|
|
c = gzip.NewWriter(nil)
|
|
|
|
case Zstd:
|
|
c, err = zstd.NewWriter(nil)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create zstd compressor: "+
|
|
"%w", err)
|
|
}
|
|
}
|
|
|
|
// Apply the compressor and its file suffix to the log rotator.
|
|
r.rotator.SetCompressor(c, logCompressors[cfg.Compressor])
|
|
|
|
// 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.rotator.Run(pr)
|
|
if err != nil {
|
|
_, _ = fmt.Fprintf(os.Stderr,
|
|
"failed to run file rotator: %v\n", err)
|
|
}
|
|
}()
|
|
|
|
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 {
|
|
return r.rotator.Close()
|
|
}
|
|
|
|
return nil
|
|
}
|