Gin框架中自定义日志格式与高亮显示教程

雨杰君_5942

雨杰君_5942

2026-10-30

134人浏览

原创

必须用gin.LoggerWithWriter配合gin.LoggerConfig才能自定义日志格式,因gin.Logger()硬编码格式且不接受参数;直接改DefaultWriter仅能换输出位置,无法添加trace_id、拆分Latency、过滤路径或标红错误码。

gin框架中自定义日志格式与高亮显示教程

gin.LoggerWithWriter 是唯一能改日志格式的入口

直接改 gin.DefaultWriter 只能换输出位置,日志内容还是固定模板:[GIN] 200 | 1.2ms | ::1 | GET /path。想加 trace_id、拆开 {{.Latency}}、过滤 /healthz、给 5xx 标红——全做不到。必须用 gin.LoggerWithWriter 配合 *gin.LoggerConfig。

关键点:

  • Format 字段必须以 \n 结尾,否则多条日志会挤在一行
  • 时间推荐用 {{.Time}}(带空格),别用 {{.StartTime}}(无格式)
  • 想同时写文件和控制台,用 io.MultiWriter(fileWriter, os.Stdout)
  • 注册时要显式调用 router.Use(gin.LoggerWithWriter(...)),gin.Default() 不会自动加载它

gin.LoggerWithFormatter 要自己实现 LogFormatter 函数

gin.LoggerWithFormatter 不是“配置即生效”的接口,它只是把日志组装逻辑委托给你写的函数。你得实现 func(gin.LogFormatterParams) string,且返回值不能含换行符(gin 自己会加)。

容易踩的坑:

  • 状态码颜色要用 ANSI 序列,比如 \033[97;41m 标红,末尾必须跟 \033[0m 重置,否则后续日志染色错乱
  • ClientIP 建议调 c.ClientIP(),别直接用参数里的字段,避免代理穿透失效
  • 时间格式用 start.Format("2006-01-02 15:04:05"),别依赖系统时区;需 UTC 就先 start.UTC().Format(...)
  • 别在 formatter 里调 log.Print 或 fmt.Println,会导致重复输出或并发冲突

生产环境写文件必须处理轮转和并发安全

只用 os.OpenFile 配 os.O_APPEND 远不够。两个问题会立刻暴露:

Gin框架 1.9.0
Gin框架 1.9.0

Gin框架 1.9.0版本源码包下载,版本号 1.9.0,适合需要 sonic JSON 支持、路由修复和内容协商改进的 Go Web 开发场景。

下载
  • 单个日志文件无限增长 → 必须用 lumberjack.Logger 做按大小/时间轮转
  • 裸 *os.File 并发写不安全 → io.MultiWriter 不加锁,得包一层 bufio.NewWriter 或直接用 lumberjack 自带缓冲
  • 多个微服务实例绝不能共用同一日志路径,否则文件损坏风险极高

示例片段:

cfg := &gin.LoggerConfig{
    Format: "{{.Time}} | \033[97;41m{{.Status}}\033[0m | {{.Latency}} | {{.ClientIP}} | {{.Method}} | {{.Path}}\n",
}
writer := &lumberjack.Logger{
    Filename:   "./logs/access.log",
    MaxSize:    100, // MB
    MaxBackups: 7,
    MaxAge:     28, // days
    Compress:   true,
}
router.Use(gin.LoggerWithWriter(io.MultiWriter(writer, os.Stdout), cfg))

状态码和耗时必须在 c.Next() 后准确捕获

直接读 c.Writer.Status() 很危险:如果前面挂了 gin.Recovery() 或 gin.BasicAuth(),拿到的可能是 500 或 401,而非业务真实返回码。

可靠做法是包装 c.Writer,拦截 WriteHeader:

  • 在中间件开头创建自定义 responseWriter,嵌入 gin.ResponseWriter
  • 重写 WriteHeader(int),只记录首次调用的状态码
  • 耗时用 time.Since(start),start 必须是 time.Now()(非 UTC()),否则纳秒级误差影响 Latency 精度
  • 确保日志中间件注册顺序在 Recovery 和鉴权中间件之后

最复杂的不是格式,而是状态码来源是否可信——这点在微服务链路中一旦出错,排查成本翻倍。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

gin框架入门 gin框架

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Go Web框架Gin接口开发与中间件设计实践
Go Web框架Gin接口开发与中间件设计实践

本专题围绕 Go 在 Web 后端开发中的主流框架 Gin 展开,系统讲解高性能接口开发与中间件机制设计。内容涵盖路由分组、请求绑定、参数校验、统一响应封装、日志与鉴权中间件实现,以及接口限流与异常处理策略。通过实战项目案例,帮助开发者构建结构清晰、性能优良的 Go Web 服务体系,提升接口开发效率与系统可维护性。

2026.03.19

337

21

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

60

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

20

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

40

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

80

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

80

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

80

25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Gin框架快速入门指南
Gin框架快速入门指南

共0课时 | 0人学习

Gin框架官方中文文档
Gin框架官方中文文档

共0课时 | 0人学习