feat(logs): 日志系统升级 — 文件轮转 + 分级存储

- 引入 lumberjack 实现日志文件自动轮转(按大小切割、保留数量、过期清理)
- app.log: 全量日志(JSON 格式),便于后期接入 ELK/Loki
- error.log: 仅 WARN 及以上级别,便于快速定位问题
- 控制台输出保持不变(彩色可读文本)
- 配置新增 log.file 节,支持 enable/dir/max_size/max_backups/max_age/compress

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-02-28 15:15:00 +08:00
parent 327cb6308e
commit 63c6079667
5 changed files with 28 additions and 7 deletions

View File

@@ -28,7 +28,7 @@ func main() {
} }
// 2. 初始化日志系统 // 2. 初始化日志系统
if err := logs.Init(cfg.Log.Level, cfg.Log.Format, cfg.Log.OutputPath); err != nil { if err := logs.Init(&cfg.Log); err != nil {
fmt.Printf("初始化日志失败: %v\n", err) fmt.Printf("初始化日志失败: %v\n", err)
os.Exit(1) os.Exit(1)
} }

View File

@@ -1,5 +1,5 @@
server: server:
port: 8080 port: 8085
mode: debug mode: debug
database: database:
@@ -28,3 +28,10 @@ log:
level: debug level: debug
format: text format: text
output_path: stdout output_path: stdout
file:
enable: true
dir: logs
max_size: 50
max_backups: 10
max_age: 30
compress: false

View File

@@ -59,17 +59,28 @@ func (r *RedisConfig) Addr() string {
// JWTConfig JWT 认证配置 // JWTConfig JWT 认证配置
type JWTConfig struct { type JWTConfig struct {
Secret string `mapstructure:"secret"` // 签名密钥 Secret string `mapstructure:"secret"` // 签名密钥
AccessExpireMin int `mapstructure:"access_expire_min"` // Access Token 有效期(分钟) AccessExpireMin int `mapstructure:"access_expire_min"` // Access Token 有效期(分钟)
RefreshExpireDay int `mapstructure:"refresh_expire_day"` // Refresh Token 有效期(天) RefreshExpireDay int `mapstructure:"refresh_expire_day"` // Refresh Token 有效期(天)
Issuer string `mapstructure:"issuer"` // 签发者 Issuer string `mapstructure:"issuer"` // 签发者
} }
// LogConfig 日志配置 // LogConfig 日志配置
type LogConfig struct { type LogConfig struct {
Level string `mapstructure:"level"` // debug/info/warn/error Level string `mapstructure:"level"` // debug/info/warn/error
Format string `mapstructure:"format"` // text(开发)/json(生产) Format string `mapstructure:"format"` // text(开发)/json(生产)
OutputPath string `mapstructure:"output_path"` // stdout 或文件路径 OutputPath string `mapstructure:"output_path"` // stdout 或文件路径
File LogFileConfig `mapstructure:"file"` // 日志文件轮转配置
}
// LogFileConfig 日志文件轮转配置(基于 lumberjack
type LogFileConfig struct {
Enable bool `mapstructure:"enable"` // 是否启用文件日志
Dir string `mapstructure:"dir"` // 日志文件目录
MaxSize int `mapstructure:"max_size"` // 单个文件最大大小MB超过后自动切割
MaxBackups int `mapstructure:"max_backups"` // 保留的旧日志文件最大数量
MaxAge int `mapstructure:"max_age"` // 旧日志文件保留天数
Compress bool `mapstructure:"compress"` // 是否压缩归档的旧日志文件
} }
// Load 加载配置文件并返回 Config 实例 // Load 加载配置文件并返回 Config 实例

View File

@@ -9,6 +9,7 @@ require (
github.com/redis/go-redis/v9 v9.18.0 github.com/redis/go-redis/v9 v9.18.0
github.com/spf13/viper v1.21.0 github.com/spf13/viper v1.21.0
go.uber.org/zap v1.27.1 go.uber.org/zap v1.27.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/driver/postgres v1.6.0 gorm.io/driver/postgres v1.6.0
gorm.io/gorm v1.31.1 gorm.io/gorm v1.31.1
) )

View File

@@ -150,6 +150,8 @@ google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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.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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=