Fix log cutting

This commit is contained in:
2025-10-25 19:17:18 +08:00
parent 3c01aed25a
commit f0cdb0f228
4 changed files with 36 additions and 10 deletions

View File

@@ -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("日志切割功能已启用")
}
// 当日志文件路径为空时,保持默认输出到控制台,不创建任何目录
}

1
go.mod
View File

@@ -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
)

2
go.sum
View File

@@ -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=

View File

@@ -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)
}
}