当前位置: 首页 > news >正文

Go使用自带的slog+lumberjack实现日志的封装

v2版本 go get github.com/natefinch/lumberjack

package mainimport ("context""io""log/slog""os""path/filepath""sync""github.com/natefinch/lumberjack"
)// 【以下 LeveledHandler 结构体和方法与 v3 版本完全一致,省略(直接复制上面的)】
// (注:为节省篇幅,这里省略重复代码,实际使用时需完整复制)
type LeveledHandler struct {handlers    map[slog.Level]slog.HandlerrootHandler slog.Handlermu          sync.RWMutex
}func NewLeveledHandler(rootHandler slog.Handler) *LeveledHandler {return &LeveledHandler{handlers:    make(map[slog.Level]slog.Handler),rootHandler: rootHandler,}
}func (lh *LeveledHandler) RegisterHandler(level slog.Level, h slog.Handler) {lh.mu.Lock()defer lh.mu.Unlock()lh.handlers[level] = h
}func (lh *LeveledHandler) Enabled(ctx context.Context, level slog.Level) bool {lh.mu.RLock()defer lh.mu.RUnlock()if h, ok := lh.handlers[level]; ok {return h.Enabled(ctx, level)}return lh.rootHandler.Enabled(ctx, level)
}func (lh *LeveledHandler) Handle(ctx context.Context, r slog.Record) error {lh.mu.RLock()defer lh.mu.RUnlock()if h, ok := lh.handlers[r.Level]; ok {return h.Handle(ctx, r)}return lh.rootHandler.Handle(ctx, r)
}func (lh *LeveledHandler) WithAttrs(attrs []slog.Attr) slog.Handler {lh.mu.RLock()defer lh.mu.RUnlock()newHandlers := make(map[slog.Level]slog.Handler, len(lh.handlers))for level, h := range lh.handlers {newHandlers[level] = h.WithAttrs(attrs)}return &LeveledHandler{handlers:    newHandlers,rootHandler: lh.rootHandler.WithAttrs(attrs),}
}func (lh *LeveledHandler) WithGroup(name string) slog.Handler {lh.mu.RLock()defer lh.mu.RUnlock()newHandlers := make(map[slog.Level]slog.Handler, len(lh.handlers))for level, h := range lh.handlers {newHandlers[level] = h.WithGroup(name)}return &LeveledHandler{handlers:    newHandlers,rootHandler: lh.rootHandler.WithGroup(name),}
}// NewRotateWriter 创建带轮转功能的 Writer(v2 版本)
func NewRotateWriter(logPath string, maxSize, maxBackups, maxAge int, compress bool) io.Writer {if err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil {slog.Error("创建日志目录失败", slog.String("path", logPath), slog.Any("err", err))return os.Stderr}// v2 版本:同样是 &lumberjack.Logger{},但 Compress 字段是 v3 新增的,v2 需删除return &lumberjack.Logger{Filename:   logPath,MaxSize:    maxSize,MaxBackups: maxBackups,MaxAge:     maxAge,LocalTime:  true,Compress:   false, //压缩}
}// InitSlog 和 main 函数与 v3 版本完全一致,直接复制即可
func InitSlog() {debugWriter := NewRotateWriter("./logs/debug.log", 1, 10, 7, true)infoWriter := NewRotateWriter("./logs/info.log", 1, 10, 7, true)warnWriter := NewRotateWriter("./logs/warn.log", 1, 10, 7, true)errorWriter := NewRotateWriter("./logs/error.log", 1, 10, 7, true)debugHandler := slog.NewJSONHandler(debugWriter, &slog.HandlerOptions{Level: slog.LevelDebug})infoHandler := slog.NewJSONHandler(infoWriter, &slog.HandlerOptions{Level: slog.LevelInfo})warnHandler := slog.NewJSONHandler(warnWriter, &slog.HandlerOptions{Level: slog.LevelWarn})errorHandler := slog.NewJSONHandler(errorWriter, &slog.HandlerOptions{Level: slog.LevelError})consoleHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})leveledHandler := NewLeveledHandler(consoleHandler)leveledHandler.RegisterHandler(slog.LevelDebug, debugHandler)leveledHandler.RegisterHandler(slog.LevelInfo, infoHandler)leveledHandler.RegisterHandler(slog.LevelWarn, warnHandler)leveledHandler.RegisterHandler(slog.LevelError, errorHandler)slog.SetDefault(slog.New(leveledHandler))
}func main() {InitSlog()for i := 0; i < 1000; i++ {slog.Debug("Debug 日志", slog.String("test", "debug"))slog.Info("Info 日志", slog.String("test", "info"))slog.Warn("Warn 日志", slog.String("test", "warn"))slog.Error("Error 日志", slog.String("test", "error"), slog.Any("err", os.ErrNotExist))}ctx := context.WithValue(context.Background(), "trace_id", "123456")slog.InfoContext(ctx, "带上下文的 Info 日志")slog.Info("Info 日志", slog.String("trace_id", ctx.Value("trace_id").(string)))
}
http://www.jsqmd.com/news/444049/

相关文章:

  • 2026年企业选型必看:深圳会计师事务所适配指南与核心优势全览 - 品牌推荐
  • Tailwind Mastery:一个全面的Tailwind CSS学习平台
  • 2026年重庆零担运输哪家靠谱?覆盖全行业场景 安全高效有保障 适配多行业需求 - 深度智识库
  • 2026年别墅大宅装修必看:重庆全屋定制品牌选型指南与精准适配解析 - 品牌推荐
  • 2026年中国精益生产咨询公司深度测评:基于实战效果与本土化能力的五维对比 - 品牌推荐
  • 深入剖析多线程核心概念、线程安全问题的根源,以及volatile关键字、线程同步机制和锁的原理与实战应用
  • 企业邮箱怎么选?2026年阿里云服务商横向测评,功能与性价比全面解析 - 品牌2026
  • 2026年高端家装必看:重庆全屋定制品牌选型指南与精准适配策略 - 品牌推荐
  • 2026年中国精益生产咨询公司深度测评:基于CDBS系统与本土化适配的五维战力解析 - 品牌推荐
  • 2026年东方美学珠宝定制指南,发现传统工艺之美,高端珠宝/东方美学珠宝/东方秩序,东方美学珠宝品牌口碑排行 - 品牌推荐师
  • 必妩韩国皮肤科不手术摆脱“蝴蝶袖”焦虑,自信穿无袖装案例篇 - 资讯焦点
  • 在Kubernetes集群运行Java单体服务Jenkins并实现数据持久化
  • 必妩韩国皮肤科提醒:光子嫩肤不清楚这些不要跟风做! - 资讯焦点
  • 权威汇总:界面张力仪生产厂家中口碑上乘的佼佼者推荐 - 品牌推荐大师
  • 2026年用户口碑最佳品牌咨询公司推荐:五家机构实战案例与效果实证对比 - 品牌推荐
  • 电池放电仪、电池内阻仪行业优秀企业推荐:2026年选择靠谱、质量好的品牌 - 深度智识库
  • 2026年品牌咨询公司深度测评:基于企业增长实效的三维价值模型全解析 - 品牌推荐
  • 2026年杭州会计师事务所深度测评:基于服务能力与行业适配的五维解析 - 品牌推荐
  • 关于 openworld-js 驱动的 open world zone 的开发想法、思考
  • 2026工业厂房恒温恒湿改造扩建工程 靠谱公司名单与选择要点 - 品牌2026
  • 2026年3月西安工伤/借贷/拆迁/劳动/合同纠纷律师团队哪家好?行业标杆与选型指南 - 2026年企业推荐榜
  • 2026年国内优质配电箱供应商推荐榜 - 资讯焦点
  • Streamlit基础用法
  • 2026年决策、管理与学习系统国际学术会议 (DMLS 2026)
  • 2026年品牌咨询公司权威榜单发布:五大机构战略落地能力深度排位赛 - 品牌推荐
  • 2026年石墨坩埚厂家实力推荐:辉县市伟业石墨制品,单环/高纯石墨坩埚全系适配冶金与新能源产业 - 品牌推荐官
  • 2026年重庆物流厂家推荐榜 靠谱优质 覆盖全场景运输需求 适配家具制造快消等多行业 - 深度智识库
  • 2026电子半导体生物医药厂房环保工程解决方案服务商汇总 - 品牌2026
  • 每日Paper - 2026-03-06
  • 抢占DeepSeek第一推荐位:2026年GEO优化公司盘点推荐 - 资讯焦点