1
0
Files
nex/backend/pkg/logger/logger.go
lanyuanxiaoyao f18904af1e feat: 实现分层架构,包含 domain、service、repository 和 pkg 层
- 新增 domain 层:model、provider、route、stats 实体
- 新增 service 层:models、providers、routing、stats 业务逻辑
- 新增 repository 层:models、providers、stats 数据访问
- 新增 pkg 工具包:errors、logger、validator
- 新增中间件:CORS、logging、recovery、request ID
- 新增数据库迁移:初始 schema 和索引
- 新增单元测试和集成测试
- 新增规范文档:config-management、database-migration、error-handling、layered-architecture、middleware-system、request-validation、structured-logging、test-coverage
- 移除 config 子包和 model_router(已迁移至分层架构)
2026-04-16 00:47:20 +08:00

110 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logger
import (
"os"
"path/filepath"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Config 日志配置
type Config struct {
Level string // 日志级别: debug, info, warn, error
Path string // 日志文件目录,为空则仅输出到 stdout
MaxSize int // 单个日志文件最大尺寸 (MB)
MaxBackups int // 保留的旧日志文件最大数量
MaxAge int // 保留旧日志文件的最大天数
Compress bool // 是否压缩旧日志文件
}
// New 根据配置创建 zap.Logger
// 如果 Path 为空,仅输出到 stdout
// 如果 Path 已设置,同时输出到 stdout 和文件(文件使用 JSON 格式stdout 使用 console 格式)
func New(cfg Config) (*zap.Logger, error) {
level, err := parseLevel(cfg.Level)
if err != nil {
return nil, err
}
// stdout encoder — console 格式
stdoutEncoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalColorLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
})
stdoutCore := zapcore.NewCore(
stdoutEncoder,
zapcore.AddSync(os.Stdout),
level,
)
// 仅 stdout 模式
if cfg.Path == "" {
return zap.New(stdoutCore, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel)), nil
}
// 文件 encoder — JSON 格式
fileEncoder := zapcore.NewJSONEncoder(zapcore.EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
FunctionKey: zapcore.OmitKey,
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.StringDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
})
rotateWriter := newRotateWriter(cfg)
fileCore := zapcore.NewCore(
fileEncoder,
zapcore.AddSync(rotateWriter),
level,
)
core := zapcore.NewTee(stdoutCore, fileCore)
return zap.New(core, zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel)), nil
}
// parseLevel 将字符串解析为 zapcore.Level
func parseLevel(s string) (zapcore.Level, error) {
switch s {
case "debug":
return zapcore.DebugLevel, nil
case "info":
return zapcore.InfoLevel, nil
case "warn":
return zapcore.WarnLevel, nil
case "error":
return zapcore.ErrorLevel, nil
default:
return zapcore.InfoLevel, nil
}
}
// logFileName 生成当日日志文件名: nex-YYYY-MM-DD.log
func logFileName() string {
return "nex-" + time.Now().Format("2006-01-02") + ".log"
}
// logFilePath 拼接完整日志文件路径
func logFilePath(dir string) string {
return filepath.Join(dir, logFileName())
}