Go中Zero日志使用指南
作者:卡尔特斯
本文主要介绍了Go中Zero日志使用指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
一、日志基础使用
1.1 日志输出方法
import "github.com/zeromicro/go-zero/core/logx"
// 普通日志
logx.Info("普通信息日志")
logx.Infof("格式化信息: %s", "内容")
logx.Infow("结构化日志", logx.Field("key", "value"))
// 错误日志
logx.Error("错误日志")
logx.Errorf("错误: %v", err)
logx.Errorw("结构化错误", logx.Field("error", err))
// 调试日志(需要开启 Debug 模式)
logx.Debug("调试日志")
logx.Debugf("调试: %s", "内容")
// 慢日志
logx.Slow("慢操作日志")
logx.Slowf("慢操作: %dms", 1000)
logx.Sloww("结构化慢日志", logx.Field("duration", "1s"))
// 统计日志
logx.Stat("统计信息")
logx.Statf("统计: %s", "内容")
// 严重错误日志
logx.Severe("严重错误")
logx.Severef("严重错误: %v", err)
1.2 带 Context 的日志
// 推荐使用,可以追踪链路
logx.WithContext(ctx).Info("带上下文的日志")
logx.WithContext(ctx).Infow("结构化日志", logx.Field("user", "张三"))
logx.WithContext(ctx).Error("带上下文的错误日志")
二、日志配置
2.1 配置文件示例(yaml)
Name: user-api Host: 0.0.0.0 Port: 8888 Log: # 日志模式:console(控制台)、file(文件)、volume(容器卷) Mode: file # 日志级别:debug、info、error、severe Level: info # 编码格式:json 或 plain Encoding: json # 文件日志配置 Path: logs # 日志文件存放目录 MaxSize: 100 # 单个日志文件最大大小(MB) MaxBackups: 5 # 保留的旧日志文件最大数量 MaxAge: 30 # 保留旧日志文件的最大天数 Compress: true # 是否压缩旧日志文件 # 日志打印调用位置 KeepDays: 7 # 日志保留天数 # 是否记录调用堆栈 StackCooldownMillis: 100 # 堆栈冷却时间(毫秒)
2.2 配置项详细说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| Mode | string | console | console-控制台输出,file-文件输出,volume-容器卷 |
| Level | string | info | debug、info、error、severe,级别越低输出越详细 |
| Encoding | string | json | json-JSON格式,plain-纯文本格式 |
| Path | string | logs | 日志文件存放路径(相对或绝对路径) |
| MaxSize | int | 100 | 单个日志文件最大大小(MB) |
| MaxBackups | int | 5 | 保留的旧日志文件最大数量 |
| MaxAge | int | 30 | 保留旧日志文件的最大天数 |
| Compress | bool | false | 是否压缩归档的日志文件 |
| KeepDays | int | 7 | 日志保留天数(优先级高于MaxAge) |
| StackCooldownMillis | int | 100 | 堆栈冷却时间,避免频繁打印堆栈 |
2.3 不同环境的日志配置建议
开发环境
Log: Mode: console # 控制台输出,方便查看 Level: debug # 详细日志,便于调试 Encoding: plain # 纯文本,易读
测试环境
Log: Mode: file # 文件输出,方便问题追溯 Level: info # 标准日志级别 Encoding: json # JSON格式,便于日志分析 Path: logs KeepDays: 3
生产环境
Log: Mode: file # 文件输出 Level: info # 只记录重要日志(或 error) Encoding: json # JSON格式,便于日志收集系统解析 Path: /var/log/app # 绝对路径 MaxSize: 500 # 大容量 MaxBackups: 10 MaxAge: 30 Compress: true # 压缩节省空间 KeepDays: 30
三、配置与不配置 Log 的区别
3.1 不配置 Log(使用默认配置)
# 配置文件中不写 Log 配置项 Name: user-api Host: 0.0.0.0 Port: 8888
默认行为:
- Mode:
console- 日志输出到控制台 - Level:
info- 只输出 info 及以上级别的日志 - Encoding:
json- JSON 格式输出 - 不会生成日志文件
- 日志只在控制台显示,重启后丢失
3.2 配置 Log
Name: user-api Host: 0.0.0.0 Port: 8888 Log: Mode: file Level: info Path: logs
行为:
- 日志输出到文件
- 日志持久化保存
- 可以配置日志轮转、压缩等
- 可以通过日志收集系统统一管理
3.3 最佳实践
// 在 main.go 中根据环境动态配置
var c config.Config
conf.MustLoad(*configFile, &c)
// 如果配置文件没有 Log 配置,可以代码中设置
if c.Log.Mode == "" {
logx.MustSetup(logx.LogConf{
Mode: "file",
Level: "info",
Encoding: "json",
Path: "logs",
})
}
四、日志收集场景与位置
4.1 自动日志收集场景
1. HTTP 中间件自动收集
// rest.Server 自动记录的日志
// 位置:rest/handler/loghandler.go
✅ 请求开始时间
✅ 请求方法和路径
✅ 请求耗时
✅ HTTP状态码
✅ 请求体大小
✅ 错误信息(如果有)
// 日志示例
{
"@timestamp": "2025-12-29T10:30:00.123Z",
"level": "info",
"content": "GET /api/users/1",
"duration": "15.2ms",
"code": 200
}
2. RPC 中间件自动收集
// zrpc.Server 自动记录的日志 // 位置:zrpc/internal/serverinterceptors/statinterceptor.go ✅ RPC方法名 ✅ 调用耗时 ✅ 错误信息 ✅ 调用参数(可选)
3. 数据库操作日志
// sqlx 自动记录慢查询 // 慢查询阈值:默认 500ms ✅ SQL语句 ✅ 执行耗时 ✅ 受影响行数
4. 缓存操作日志
// redis/cache 自动记录慢操作 // 慢操作阈值:可配置 ✅ Redis命令 ✅ 执行耗时 ✅ 缓存键
4.2 手动日志收集场景
// 业务逻辑层
func (l *UserLogic) GetUser(req *types.GetUserReq) (*types.User, error) {
// 关键业务操作记录
logx.WithContext(l.ctx).Infow("开始获取用户信息",
logx.Field("userId", req.UserId))
user, err := l.svcCtx.UserModel.FindOne(l.ctx, req.UserId)
if err != nil {
// 错误日志
logx.WithContext(l.ctx).Errorw("获取用户失败",
logx.Field("userId", req.UserId),
logx.Field("error", err.Error()))
return nil, err
}
// 成功日志
logx.WithContext(l.ctx).Infow("用户信息获取成功",
logx.Field("userId", req.UserId),
logx.Field("userName", user.Name))
return &types.User{
Id: user.Id,
Name: user.Name,
}, nil
}
4.3 日志收集最佳实践
// ✅ 推荐:关键业务节点记录 - 用户登录/登出 - 订单创建/支付 - 重要数据的增删改 - 外部API调用 - 异常错误 // ❌ 不推荐:过度日志 - 循环内的日志 - 高频调用的接口日志 - 敏感信息(密码、token等)
五、日志文件存储规则
5.1 日志文件命名规则
logs/ ├── access.log # 当前访问日志 ├── error.log # 当前错误日志 ├── severe.log # 当前严重错误日志 ├── slow.log # 当前慢日志 ├── stat.log # 当前统计日志 ├── access.log.2025122901 # 归档的访问日志 ├── access.log.2025122902 └── error.log.2025122901 # 归档的错误日志
5.2 日志分类存储
| 日志类型 | 文件名 | 触发条件 | 用途 |
|---|---|---|---|
| access.log | 访问日志 | Info、Infof、Infow | 记录正常业务流程 |
| error.log | 错误日志 | Error、Errorf、Errorw | 记录业务错误 |
| severe.log | 严重错误 | Severe、Severef、Severew | 记录系统级严重错误 |
| slow.log | 慢日志 | Slow、Slowf、Sloww | 记录耗时操作 |
| stat.log | 统计日志 | Stat、Statf、Statw | 记录统计信息 |
5.3 什么时候会存文件
存文件条件:
Log.Mode = "file"或"volume"- 配置了
Log.Path
不存文件条件:
Log.Mode = "console"- 只输出到控制台- 不配置 Log - 默认 console 模式
# ✅ 会存文件 Log: Mode: file Path: logs # ✅ 会存文件(容器环境) Log: Mode: volume Path: /var/log/app # ❌ 不会存文件 Log: Mode: console # ❌ 不会存文件(默认配置) # 不配置 Log
5.4 日志轮转机制
Log: Path: logs MaxSize: 100 # 单文件 100MB 后轮转 MaxBackups: 5 # 最多保留 5 个备份 MaxAge: 30 # 保留 30 天 KeepDays: 7 # 优先级更高,保留 7 天 Compress: true # 压缩旧文件为 .gz
轮转触发条件(满足任一):
- 文件大小超过 MaxSize
- 文件创建时间超过 KeepDays
- 达到每日午夜(自动轮转)
六、日志查看与问题排查
6.1 查看日志的方式
方式一:tail 实时查看
# 实时查看所有日志 tail -f logs/access.log # 实时查看错误日志 tail -f logs/error.log # 同时查看多个日志 tail -f logs/access.log logs/error.log
方式二:grep 过滤查看
# 查找特定用户的日志 grep "userId\":\"123" logs/access.log # 查找错误日志 grep "error" logs/access.log # 查找特定时间段的日志 grep "2025-12-29T10:" logs/access.log # 查找并显示上下文 grep -C 5 "error" logs/access.log # 显示前后5行
方式三:less 分页查看
# 分页查看日志 less logs/access.log # 在 less 中搜索:按 / 然后输入关键词 # 下一个:n # 上一个:N
方式四:cat 配合工具
# 查看最近100行 tail -n 100 logs/access.log # 查看前100行 head -n 100 logs/access.log # JSON格式美化 cat logs/access.log | jq '.'
6.2 通过 trace_id 追踪请求链路
# 提取 trace_id 追踪整个请求链路
grep "trace:abc123" logs/*.log
# 输出示例:
# logs/access.log:{"@timestamp":"...","trace":"abc123","content":"GET /api/users"}
# logs/access.log:{"@timestamp":"...","trace":"abc123","content":"query user from db"}
# logs/error.log:{"@timestamp":"...","trace":"abc123","content":"user not found"}
6.3 性能问题排查
慢查询排查
# 查看慢日志 cat logs/slow.log # 查找超过1秒的操作 grep "duration\":\"[0-9]\+s" logs/slow.log # 统计最慢的10个操作 cat logs/slow.log | jq '.duration' | sort | tail -10
高频错误排查
# 统计错误类型 cat logs/error.log | jq '.error' | sort | uniq -c | sort -rn # 查找特定错误 grep "connection timeout" logs/error.log
6.4 典型问题排查流程
问题1:接口响应慢
# 1. 查看 slow.log tail -f logs/slow.log # 2. 找到慢请求的 trace_id grep "duration\":\"[0-9]\+s" logs/slow.log # 3. 根据 trace_id 追踪完整链路 grep "trace:abc123" logs/*.log # 4. 分析瓶颈:数据库?外部API?
问题2:接口返回 500 错误
# 1. 查看 error.log tail -f logs/error.log # 2. 找到错误信息和堆栈 grep -A 10 "500" logs/error.log # 3. 根据时间和路径定位代码 # 4. 查看相关业务日志
问题3:找不到某个请求的日志
# 可能原因: # 1. 日志级别太高(设置为 error,但请求是 info) # 2. 日志已被轮转或删除 # 3. 时间不对(注意时区) # 解决: # 1. 检查 Log.Level 配置 # 2. 查看归档日志 access.log.2025122901 # 3. 检查服务器时区设置
七、日志使用建议
7.1 什么时候开启日志
| 场景 | 是否开启 | 建议配置 |
|---|---|---|
| 开发环境 | ✅ 必须 | Mode: console, Level: debug |
| 测试环境 | ✅ 必须 | Mode: file, Level: info |
| 预发环境 | ✅ 必须 | Mode: file, Level: info |
| 生产环境 | ✅ 必须 | Mode: file, Level: info/error |
| 性能测试 | ⚠️ 可选 | Mode: file, Level: error(减少IO) |
| 压力测试 | ⚠️ 可选 | Level: error(减少日志量) |
结论:建议一直开启日志,根据环境调整级别和输出方式。
7.2 日志级别选择
// debug - 开发调试(生产不建议)
logx.Debug("调试信息:变量值为 xxx")
// info - 正常业务流程(推荐)
logx.Info("用户登录成功")
// error - 业务错误(必须)
logx.Error("获取用户信息失败")
// severe - 严重系统错误(必须)
logx.Severe("数据库连接失败")
7.3 日志性能优化
// ❌ 不推荐:高频日志
for i := 0; i < 10000; i++ {
logx.Info("处理中:", i) // 会产生大量日志
}
// ✅ 推荐:批量记录
logx.Infof("批量处理完成,共处理 %d 条", 10000)
// ❌ 不推荐:复杂对象序列化
logx.Infow("用户信息", logx.Field("user", largeUserObject))
// ✅ 推荐:只记录关键字段
logx.Infow("用户信息",
logx.Field("userId", user.Id),
logx.Field("userName", user.Name))
7.4 敏感信息处理
// ❌ 危险:记录敏感信息
logx.Infow("用户登录",
logx.Field("password", password)) // 不要记录密码
logx.Infow("支付",
logx.Field("cardNo", cardNo)) // 不要记录完整卡号
// ✅ 安全:脱敏处理
logx.Infow("用户登录",
logx.Field("userId", userId))
logx.Infow("支付",
logx.Field("cardNo", maskCard(cardNo))) // 如:**** **** **** 1234
八、常用日志工具
8.1 日志分析工具
ELK Stack(推荐生产环境)
# Filebeat 配置示例
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
json.keys_under_root: true
json.add_error_key: true
output.elasticsearch:
hosts: ["localhost:9200"]
Loki(轻量级推荐)
# Promtail 配置示例
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: app
static_configs:
- targets:
- localhost
labels:
__path__: /var/log/app/*.log
8.2 日志查看命令速查
# 实时查看 tail -f logs/access.log # 查看最近100行 tail -n 100 logs/access.log # 搜索关键词 grep "error" logs/*.log # 搜索并高亮显示 grep --color "error" logs/access.log # 统计日志行数 wc -l logs/access.log # 按时间范围筛选 sed -n '/2025-12-29 10:00/,/2025-12-29 11:00/p' logs/access.log # JSON 日志美化 cat logs/access.log | jq '.' # 统计错误类型 cat logs/error.log | jq '.error' | sort | uniq -c # 找出最慢的10个请求 cat logs/slow.log | jq '.duration' | sort -rn | head -10
九、完整配置示例
9.1 API 服务配置
# api/etc/user.yaml Name: user-api Host: 0.0.0.0 Port: 8888 # 生产环境日志配置 Log: Mode: file Level: info Encoding: json Path: logs MaxSize: 500 MaxBackups: 10 MaxAge: 30 Compress: true KeepDays: 30 StackCooldownMillis: 100 # Telemetry 配置(链路追踪) Telemetry: Name: user-api Endpoint: http://jaeger:14268/api/traces Sampler: 1.0 Batcher: jaeger
9.2 RPC 服务配置
# rpc/etc/user.yaml Name: user-rpc ListenOn: 0.0.0.0:8080 Log: Mode: file Level: info Encoding: json Path: logs KeepDays: 30 # RPC 超时配置 Timeout: 30000 # 30秒 # RPC 日志配置 RpcLog: Stat: true # 开启统计日志 Slow: true # 开启慢日志
9.3 Docker 环境配置
# docker-compose.yaml 中的日志配置
services:
user-api:
image: user-api:latest
volumes:
- ./logs:/app/logs # 挂载日志目录
environment:
- LOG_MODE=file
- LOG_LEVEL=info
十、总结与检查清单
✅ 日志配置检查清单
- 是否配置了 Log.Mode(开发用console,生产用file)
- 是否配置了合适的 Log.Level(开发用debug,生产用info)
- 是否配置了 Log.Path(生产环境)
- 是否配置了日志轮转(MaxSize、MaxBackups、KeepDays)
- 是否开启了日志压缩(Compress: true)
- 是否配置了链路追踪(Telemetry)
✅ 日志使用检查清单
- 关键业务操作是否有日志记录
- 错误处理是否记录了详细错误信息
- 日志是否使用了 WithContext 以便链路追踪
- 日志是否包含了足够的上下文信息
- 是否避免了记录敏感信息
- 高频操作是否控制了日志数量
- 是否使用了结构化日志(Infow、Errorw)
✅ 问题排查检查清单
- 是否能通过 trace_id 追踪完整请求链路
- 是否能快速定位错误日志
- 是否能分析慢查询和性能瓶颈
- 是否配置了日志收集系统(生产环境)
- 是否定期清理旧日志文件
- 是否有日志监控告警(严重错误)
附录:常见问题
Q1: 日志文件太大怎么办?
- 调整 MaxSize 和 KeepDays
- 提高日志级别(info -> error)
- 减少不必要的日志输出
- 开启 Compress 压缩
Q2: 找不到某个请求的日志?
- 检查日志级别配置
- 确认日志是否被轮转
- 检查时区是否正确
- 确认该请求是否真的到达了服务
Q3: 日志乱码怎么办?
- 确保使用 UTF-8 编码
- 检查 Encoding 配置
- 使用
cat -A查看特殊字符
Q4: 如何在代码中动态修改日志级别?
// 运行时修改日志级别(不推荐生产环境) logx.SetLevel(logx.ErrorLevel)
Q5: 容器环境日志如何收集?
# 使用 volume 模式 Log: Mode: volume Path: /var/log/app # Docker 挂载 volumes: - ./logs:/var/log/app
到此这篇关于Go中Zero日志使用指南的文章就介绍到这了,更多相关Go Zero日志使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
