diff --git a/cmd/root.go b/cmd/root.go index 17c8d76..78cad35 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" + "gopkg.in/natefinch/lumberjack.v2" ) var cfgFile string @@ -84,7 +85,7 @@ func initConfig() { } // setupLogrusFromConfig 根据配置文件进一步配置logrus -// 设置日志级别和输出目标 +// 设置日志级别和输出目标,支持日志切割功能 func setupLogrusFromConfig() { // 设置日志级别 if level := viper.GetString("log.level"); level != "" { @@ -98,14 +99,30 @@ func setupLogrusFromConfig() { if logFile != "" { // 确保日志目录存在 logDir := filepath.Dir(logFile) - if err := os.MkdirAll(logDir, 0755); err == nil { - // 打开日志文件 - if file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); err == nil { - // 同时输出到控制台和文件 - multiWriter := io.MultiWriter(os.Stdout, file) - logrus.SetOutput(multiWriter) - } + if err := os.MkdirAll(logDir, 0755); err != nil { + logrus.WithError(err).Error("创建日志目录失败") + return } + + // 配置lumberjack日志轮转 + lumberjackLogger := &lumberjack.Logger{ + Filename: logFile, + MaxSize: viper.GetInt("log.max_size"), // MB + MaxBackups: viper.GetInt("log.max_backups"), // 保留的旧日志文件数量 + MaxAge: viper.GetInt("log.max_age"), // 天数 + Compress: true, // 压缩旧日志文件 + } + + // 同时输出到控制台和文件(带日志切割) + multiWriter := io.MultiWriter(os.Stdout, lumberjackLogger) + logrus.SetOutput(multiWriter) + + logrus.WithFields(logrus.Fields{ + "file": logFile, + "max_size": viper.GetInt("log.max_size"), + "max_backups": viper.GetInt("log.max_backups"), + "max_age": viper.GetInt("log.max_age"), + }).Info("日志切割功能已启用") } // 当日志文件路径为空时,保持默认输出到控制台,不创建任何目录 } diff --git a/go.mod b/go.mod index 143d94d..66b87fe 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.20.1 golang.org/x/crypto v0.41.0 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 gorm.io/driver/mysql v1.6.0 gorm.io/gorm v1.30.1 ) diff --git a/go.sum b/go.sum index d397cd6..410649b 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/utils/logger/http.go b/utils/logger/http.go index 0281171..5063bf0 100644 --- a/utils/logger/http.go +++ b/utils/logger/http.go @@ -50,10 +50,16 @@ func (l *Logger) LogRequestWithHeaders(method, path, clientIP string, statusCode l.writeHTTPLog(logLine) } -// writeHTTPLog 直接输出HTTP日志到标准输出 +// writeHTTPLog 输出HTTP日志到标准输出和配置的日志文件 // 避免Logrus的任何格式化和转义,保持Apache日志格式的原始性 // logLine: 格式化后的日志行 func (l *Logger) writeHTTPLog(logLine string) { - // 直接输出到标准输出,避免Logrus的转义处理 + // 输出到标准输出 fmt.Fprintln(os.Stdout, logLine) + + // 同时输出到logrus配置的输出目标(包括文件) + // 使用logrus的输出目标,但不经过格式化器 + if l.Logger.Out != nil && l.Logger.Out != os.Stdout { + fmt.Fprintln(l.Logger.Out, logLine) + } }