feat(logger): add size/age/backup rotation for file output (#874)

This commit is contained in:
irium
2026-05-11 22:52:12 +02:00
committed by GitHub
parent a86085f2d9
commit f173e8ad05
5 changed files with 33 additions and 5 deletions
+4
View File
@@ -136,6 +136,10 @@ func realMain() int {
Level: cfg.Logging.Level,
Format: cfg.Logging.Format,
OutputPath: cfg.Logging.OutputPath,
MaxSizeMB: cfg.Logging.MaxSizeMB,
MaxBackups: cfg.Logging.MaxBackups,
MaxAgeDays: cfg.Logging.MaxAgeDays,
Compress: cfg.Logging.Compress,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize logger: %v\n", err)
+1
View File
@@ -109,6 +109,7 @@ require (
google.golang.org/grpc v1.80.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
)
+2
View File
@@ -683,6 +683,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
@@ -140,6 +140,13 @@ type LoggingConfig struct {
Level string `mapstructure:"level"`
Format string `mapstructure:"format"`
OutputPath string `mapstructure:"outputPath"`
// Rotation options — apply only when OutputPath is a file path
// (ignored for stdout/stderr). Backed by lumberjack.
MaxSizeMB int `mapstructure:"maxSizeMb"`
MaxBackups int `mapstructure:"maxBackups"`
MaxAgeDays int `mapstructure:"maxAgeDays"`
Compress bool `mapstructure:"compress"`
}
// RepositoryDiscoveryConfig holds configuration for local repository scanning.
@@ -271,6 +278,10 @@ func setDefaults(v *viper.Viper) {
v.SetDefault("logging.level", "info")
v.SetDefault("logging.format", detectDefaultLogFormat())
v.SetDefault("logging.outputPath", "stdout")
v.SetDefault("logging.maxSizeMb", 100)
v.SetDefault("logging.maxBackups", 5)
v.SetDefault("logging.maxAgeDays", 30)
v.SetDefault("logging.compress", true)
// Repository discovery defaults
v.SetDefault("repositoryDiscovery.roots", []string{})
+15 -5
View File
@@ -8,6 +8,7 @@ import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"github.com/kandev/kandev/internal/common/logger/buffer"
)
@@ -25,6 +26,13 @@ type LoggingConfig struct {
Level string `mapstructure:"level"` // debug, info, warn, error
Format string `mapstructure:"format"` // json, console
OutputPath string `mapstructure:"output_path"` // stdout, stderr, or file path
// Rotation options — apply only when OutputPath is a file path
// (ignored for stdout/stderr). Backed by lumberjack.
MaxSizeMB int `mapstructure:"max_size_mb"` // rotate when file exceeds this size; 0 = lumberjack default (100MB)
MaxBackups int `mapstructure:"max_backups"` // max number of rotated files to retain; 0 = unlimited
MaxAgeDays int `mapstructure:"max_age_days"` // max age of rotated files; 0 = unlimited
Compress bool `mapstructure:"compress"` // gzip rotated files
}
// Logger wraps zap.Logger to provide structured logging with helper methods.
@@ -94,11 +102,13 @@ func NewLogger(cfg LoggingConfig) (*Logger, error) {
case "stderr":
writeSyncer = zapcore.AddSync(os.Stderr)
default:
file, err := os.OpenFile(cfg.OutputPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return nil, err
}
writeSyncer = zapcore.AddSync(file)
writeSyncer = zapcore.AddSync(&lumberjack.Logger{
Filename: cfg.OutputPath,
MaxSize: cfg.MaxSizeMB,
MaxBackups: cfg.MaxBackups,
MaxAge: cfg.MaxAgeDays,
Compress: cfg.Compress,
})
}
outputCore := zapcore.NewCore(encoder, writeSyncer, level)