feat(log): Gin 结构化 JSON 访问日志 + 生产默认 release 模式(去掉启动路由 dump)
=== 一、结构化 JSON 访问日志(middleware/accesslog.go)=== gin.Default() → gin.New() + AccessLog() + gin.Recovery() - 一行一个 JSON:ts/level/type/method/path/status/latency_ms/bytes/ip/ua - 自动分级:5xx=error / 4xx=warn / 其余=info - jwt 中间件写入的 userId/username 一并输出,便于审计 - 健康检查与 /assets 静音(探针每 10s 一次会淹没真实请求) - Recovery 显式加回(gin.Default 里包含它) ⚠️ Go map 序列化按 key 字母序,ts 会排到最后 → LogJSON 手工拼装, 把 ts/level/type/msg 固定在最前,其余排序输出。 === 二、生产默认 release 模式 === 代码里此前**完全没有 gin.SetMode**,一直跑在 debug: - 每次启动 dump 100+ 行路由表([GIN-debug] GET /api/v1/...) - 每请求有额外开销,且把完整路由暴露在日志里 现在:GIN_MODE 未显式设置且 DEBUG!=true 时自动 SetMode(ReleaseMode), 需要调试仍可用 DEBUG=true 或 GIN_MODE=debug 覆盖。 === 三、实测 === GIN-debug 路由 dump 行数: 0 ✅(修复前 100+) JSON 访问日志: {"ts":"2026-10-27T14:49:28.53Z","level":"info","type":"access","bytes":828, "ip":"172.19.16.92","latency_ms":173.5,"method":"POST", "path":"/api/v1/auth/login","status":200,"ua":"curl/8.4.0"} ✅ 带用户信息: ...,"user_id":1,"username":"admin" ✅ health 日志行数: 0 ✅ 总日志 15 行 / JSON 7 行 / 非 JSON 8 行(全部是启动日志) health ok、Promtail 12/12、lokistack 1/1 ✅ 镜像:lghost/lokistack:latest + v0.1 = sha256:8b25b0a29efa
This commit is contained in:
1 parent
02705382f1
commit
7b600f7eee
3 files changed
+151
-1
No files matched your search
@@ -15,7 +15,12 @@ import (
|
||||
)
|
||||
|
||||
func SetupRouter() *gin.Engine {
|
||||
r := gin.Default()
|
||||
// 用 gin.New() 而不是 gin.Default():Default 自带文本格式的 gin.Logger(),
|
||||
// 这里换成结构化 JSON 访问日志(middleware.AccessLog),便于 Promtail→Loki
|
||||
// 按字段过滤,同时跳过健康检查/静态资源,避免探针轮询把日志量刷满。
|
||||
// Recovery 必须显式加回来(Default 里包含它),否则 panic 会打挂进程。
|
||||
r := gin.New()
|
||||
r.Use(middleware.AccessLog(), gin.Recovery())
|
||||
|
||||
// CORS
|
||||
cfg := cors.DefaultConfig()
|
||||
|
||||
Reference in new issue
Block a user