Go中Zero日志使用指南
一、日志基礎(chǔ)使用
1.1 日志輸出方法
import "github.com/zeromicro/go-zero/core/logx"
// 普通日志
logx.Info("普通信息日志")
logx.Infof("格式化信息: %s", "內(nèi)容")
logx.Infow("結(jié)構(gòu)化日志", logx.Field("key", "value"))
// 錯(cuò)誤日志
logx.Error("錯(cuò)誤日志")
logx.Errorf("錯(cuò)誤: %v", err)
logx.Errorw("結(jié)構(gòu)化錯(cuò)誤", logx.Field("error", err))
// 調(diào)試日志(需要開啟 Debug 模式)
logx.Debug("調(diào)試日志")
logx.Debugf("調(diào)試: %s", "內(nèi)容")
// 慢日志
logx.Slow("慢操作日志")
logx.Slowf("慢操作: %dms", 1000)
logx.Sloww("結(jié)構(gòu)化慢日志", logx.Field("duration", "1s"))
// 統(tǒng)計(jì)日志
logx.Stat("統(tǒng)計(jì)信息")
logx.Statf("統(tǒng)計(jì): %s", "內(nèi)容")
// 嚴(yán)重錯(cuò)誤日志
logx.Severe("嚴(yán)重錯(cuò)誤")
logx.Severef("嚴(yán)重錯(cuò)誤: %v", err)
1.2 帶 Context 的日志
// 推薦使用,可以追蹤鏈路
logx.WithContext(ctx).Info("帶上下文的日志")
logx.WithContext(ctx).Infow("結(jié)構(gòu)化日志", logx.Field("user", "張三"))
logx.WithContext(ctx).Error("帶上下文的錯(cuò)誤日志")
二、日志配置
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 # 單個(gè)日志文件最大大?。∕B) MaxBackups: 5 # 保留的舊日志文件最大數(shù)量 MaxAge: 30 # 保留舊日志文件的最大天數(shù) Compress: true # 是否壓縮舊日志文件 # 日志打印調(diào)用位置 KeepDays: 7 # 日志保留天數(shù) # 是否記錄調(diào)用堆棧 StackCooldownMillis: 100 # 堆棧冷卻時(shí)間(毫秒)
2.2 配置項(xiàng)詳細(xì)說明
| 配置項(xiàng) | 類型 | 默認(rèn)值 | 說明 |
|---|---|---|---|
| Mode | string | console | console-控制臺輸出,file-文件輸出,volume-容器卷 |
| Level | string | info | debug、info、error、severe,級別越低輸出越詳細(xì) |
| Encoding | string | json | json-JSON格式,plain-純文本格式 |
| Path | string | logs | 日志文件存放路徑(相對或絕對路徑) |
| MaxSize | int | 100 | 單個(gè)日志文件最大大?。∕B) |
| MaxBackups | int | 5 | 保留的舊日志文件最大數(shù)量 |
| MaxAge | int | 30 | 保留舊日志文件的最大天數(shù) |
| Compress | bool | false | 是否壓縮歸檔的日志文件 |
| KeepDays | int | 7 | 日志保留天數(shù)(優(yōu)先級高于MaxAge) |
| StackCooldownMillis | int | 100 | 堆棧冷卻時(shí)間,避免頻繁打印堆棧 |
2.3 不同環(huán)境的日志配置建議
開發(fā)環(huán)境
Log: Mode: console # 控制臺輸出,方便查看 Level: debug # 詳細(xì)日志,便于調(diào)試 Encoding: plain # 純文本,易讀
測試環(huán)境
Log: Mode: file # 文件輸出,方便問題追溯 Level: info # 標(biāo)準(zhǔn)日志級別 Encoding: json # JSON格式,便于日志分析 Path: logs KeepDays: 3
生產(chǎn)環(huán)境
Log: Mode: file # 文件輸出 Level: info # 只記錄重要日志(或 error) Encoding: json # JSON格式,便于日志收集系統(tǒng)解析 Path: /var/log/app # 絕對路徑 MaxSize: 500 # 大容量 MaxBackups: 10 MaxAge: 30 Compress: true # 壓縮節(jié)省空間 KeepDays: 30
三、配置與不配置 Log 的區(qū)別
3.1 不配置 Log(使用默認(rèn)配置)
# 配置文件中不寫 Log 配置項(xiàng) Name: user-api Host: 0.0.0.0 Port: 8888
默認(rèn)行為:
- 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
行為:
- 日志輸出到文件
- 日志持久化保存
- 可以配置日志輪轉(zhuǎn)、壓縮等
- 可以通過日志收集系統(tǒng)統(tǒng)一管理
3.3 最佳實(shí)踐
// 在 main.go 中根據(jù)環(huán)境動態(tài)配置
var c config.Config
conf.MustLoad(*configFile, &c)
// 如果配置文件沒有 Log 配置,可以代碼中設(shè)置
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
? 請求開始時(shí)間
? 請求方法和路徑
? 請求耗時(shí)
? HTTP狀態(tài)碼
? 請求體大小
? 錯(cuò)誤信息(如果有)
// 日志示例
{
"@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方法名 ? 調(diào)用耗時(shí) ? 錯(cuò)誤信息 ? 調(diào)用參數(shù)(可選)
3. 數(shù)據(jù)庫操作日志
// sqlx 自動記錄慢查詢 // 慢查詢閾值:默認(rèn) 500ms ? SQL語句 ? 執(zhí)行耗時(shí) ? 受影響行數(shù)
4. 緩存操作日志
// redis/cache 自動記錄慢操作 // 慢操作閾值:可配置 ? Redis命令 ? 執(zhí)行耗時(shí) ? 緩存鍵
4.2 手動日志收集場景
// 業(yè)務(wù)邏輯層
func (l *UserLogic) GetUser(req *types.GetUserReq) (*types.User, error) {
// 關(guān)鍵業(yè)務(wù)操作記錄
logx.WithContext(l.ctx).Infow("開始獲取用戶信息",
logx.Field("userId", req.UserId))
user, err := l.svcCtx.UserModel.FindOne(l.ctx, req.UserId)
if err != nil {
// 錯(cuò)誤日志
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 日志收集最佳實(shí)踐
// ? 推薦:關(guān)鍵業(yè)務(wù)節(jié)點(diǎn)記錄 - 用戶登錄/登出 - 訂單創(chuàng)建/支付 - 重要數(shù)據(jù)的增刪改 - 外部API調(diào)用 - 異常錯(cuò)誤 // ? 不推薦:過度日志 - 循環(huán)內(nèi)的日志 - 高頻調(diào)用的接口日志 - 敏感信息(密碼、token等)
五、日志文件存儲規(guī)則
5.1 日志文件命名規(guī)則
logs/ ├── access.log # 當(dāng)前訪問日志 ├── error.log # 當(dāng)前錯(cuò)誤日志 ├── severe.log # 當(dāng)前嚴(yán)重錯(cuò)誤日志 ├── slow.log # 當(dāng)前慢日志 ├── stat.log # 當(dāng)前統(tǒng)計(jì)日志 ├── access.log.2025122901 # 歸檔的訪問日志 ├── access.log.2025122902 └── error.log.2025122901 # 歸檔的錯(cuò)誤日志
5.2 日志分類存儲
| 日志類型 | 文件名 | 觸發(fā)條件 | 用途 |
|---|---|---|---|
| access.log | 訪問日志 | Info、Infof、Infow | 記錄正常業(yè)務(wù)流程 |
| error.log | 錯(cuò)誤日志 | Error、Errorf、Errorw | 記錄業(yè)務(wù)錯(cuò)誤 |
| severe.log | 嚴(yán)重錯(cuò)誤 | Severe、Severef、Severew | 記錄系統(tǒng)級嚴(yán)重錯(cuò)誤 |
| slow.log | 慢日志 | Slow、Slowf、Sloww | 記錄耗時(shí)操作 |
| stat.log | 統(tǒng)計(jì)日志 | Stat、Statf、Statw | 記錄統(tǒng)計(jì)信息 |
5.3 什么時(shí)候會存文件
存文件條件:
Log.Mode = "file"或"volume"- 配置了
Log.Path
不存文件條件:
Log.Mode = "console"- 只輸出到控制臺- 不配置 Log - 默認(rèn) console 模式
# ? 會存文件 Log: Mode: file Path: logs # ? 會存文件(容器環(huán)境) Log: Mode: volume Path: /var/log/app # ? 不會存文件 Log: Mode: console # ? 不會存文件(默認(rèn)配置) # 不配置 Log
5.4 日志輪轉(zhuǎn)機(jī)制
Log: Path: logs MaxSize: 100 # 單文件 100MB 后輪轉(zhuǎn) MaxBackups: 5 # 最多保留 5 個(gè)備份 MaxAge: 30 # 保留 30 天 KeepDays: 7 # 優(yōu)先級更高,保留 7 天 Compress: true # 壓縮舊文件為 .gz
輪轉(zhuǎn)觸發(fā)條件(滿足任一):
- 文件大小超過 MaxSize
- 文件創(chuàng)建時(shí)間超過 KeepDays
- 達(dá)到每日午夜(自動輪轉(zhuǎn))
六、日志查看與問題排查
6.1 查看日志的方式
方式一:tail 實(shí)時(shí)查看
# 實(shí)時(shí)查看所有日志 tail -f logs/access.log # 實(shí)時(shí)查看錯(cuò)誤日志 tail -f logs/error.log # 同時(shí)查看多個(gè)日志 tail -f logs/access.log logs/error.log
方式二:grep 過濾查看
# 查找特定用戶的日志 grep "userId\":\"123" logs/access.log # 查找錯(cuò)誤日志 grep "error" logs/access.log # 查找特定時(shí)間段的日志 grep "2025-12-29T10:" logs/access.log # 查找并顯示上下文 grep -C 5 "error" logs/access.log # 顯示前后5行
方式三:less 分頁查看
# 分頁查看日志 less logs/access.log # 在 less 中搜索:按 / 然后輸入關(guān)鍵詞 # 下一個(gè):n # 上一個(gè):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 追蹤整個(gè)請求鏈路
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 # 統(tǒng)計(jì)最慢的10個(gè)操作 cat logs/slow.log | jq '.duration' | sort | tail -10
高頻錯(cuò)誤排查
# 統(tǒng)計(jì)錯(cuò)誤類型 cat logs/error.log | jq '.error' | sort | uniq -c | sort -rn # 查找特定錯(cuò)誤 grep "connection timeout" logs/error.log
6.4 典型問題排查流程
問題1:接口響應(yīng)慢
# 1. 查看 slow.log tail -f logs/slow.log # 2. 找到慢請求的 trace_id grep "duration\":\"[0-9]\+s" logs/slow.log # 3. 根據(jù) trace_id 追蹤完整鏈路 grep "trace:abc123" logs/*.log # 4. 分析瓶頸:數(shù)據(jù)庫?外部API?
問題2:接口返回 500 錯(cuò)誤
# 1. 查看 error.log tail -f logs/error.log # 2. 找到錯(cuò)誤信息和堆棧 grep -A 10 "500" logs/error.log # 3. 根據(jù)時(shí)間和路徑定位代碼 # 4. 查看相關(guān)業(yè)務(wù)日志
問題3:找不到某個(gè)請求的日志
# 可能原因: # 1. 日志級別太高(設(shè)置為 error,但請求是 info) # 2. 日志已被輪轉(zhuǎn)或刪除 # 3. 時(shí)間不對(注意時(shí)區(qū)) # 解決: # 1. 檢查 Log.Level 配置 # 2. 查看歸檔日志 access.log.2025122901 # 3. 檢查服務(wù)器時(shí)區(qū)設(shè)置
七、日志使用建議
7.1 什么時(shí)候開啟日志
| 場景 | 是否開啟 | 建議配置 |
|---|---|---|
| 開發(fā)環(huán)境 | ? 必須 | Mode: console, Level: debug |
| 測試環(huán)境 | ? 必須 | Mode: file, Level: info |
| 預(yù)發(fā)環(huán)境 | ? 必須 | Mode: file, Level: info |
| 生產(chǎn)環(huán)境 | ? 必須 | Mode: file, Level: info/error |
| 性能測試 | ?? 可選 | Mode: file, Level: error(減少IO) |
| 壓力測試 | ?? 可選 | Level: error(減少日志量) |
結(jié)論:建議一直開啟日志,根據(jù)環(huán)境調(diào)整級別和輸出方式。
7.2 日志級別選擇
// debug - 開發(fā)調(diào)試(生產(chǎn)不建議)
logx.Debug("調(diào)試信息:變量值為 xxx")
// info - 正常業(yè)務(wù)流程(推薦)
logx.Info("用戶登錄成功")
// error - 業(yè)務(wù)錯(cuò)誤(必須)
logx.Error("獲取用戶信息失敗")
// severe - 嚴(yán)重系統(tǒng)錯(cuò)誤(必須)
logx.Severe("數(shù)據(jù)庫連接失敗")
7.3 日志性能優(yōu)化
// ? 不推薦:高頻日志
for i := 0; i < 10000; i++ {
logx.Info("處理中:", i) // 會產(chǎn)生大量日志
}
// ? 推薦:批量記錄
logx.Infof("批量處理完成,共處理 %d 條", 10000)
// ? 不推薦:復(fù)雜對象序列化
logx.Infow("用戶信息", logx.Field("user", largeUserObject))
// ? 推薦:只記錄關(guān)鍵字段
logx.Infow("用戶信息",
logx.Field("userId", user.Id),
logx.Field("userName", user.Name))
7.4 敏感信息處理
// ? 危險(xiǎn):記錄敏感信息
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(推薦生產(chǎn)環(huán)境)
# 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 日志查看命令速查
# 實(shí)時(shí)查看 tail -f logs/access.log # 查看最近100行 tail -n 100 logs/access.log # 搜索關(guān)鍵詞 grep "error" logs/*.log # 搜索并高亮顯示 grep --color "error" logs/access.log # 統(tǒng)計(jì)日志行數(shù) wc -l logs/access.log # 按時(shí)間范圍篩選 sed -n '/2025-12-29 10:00/,/2025-12-29 11:00/p' logs/access.log # JSON 日志美化 cat logs/access.log | jq '.' # 統(tǒng)計(jì)錯(cuò)誤類型 cat logs/error.log | jq '.error' | sort | uniq -c # 找出最慢的10個(gè)請求 cat logs/slow.log | jq '.duration' | sort -rn | head -10
九、完整配置示例
9.1 API 服務(wù)配置
# api/etc/user.yaml Name: user-api Host: 0.0.0.0 Port: 8888 # 生產(chǎn)環(huán)境日志配置 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 服務(wù)配置
# 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 超時(shí)配置 Timeout: 30000 # 30秒 # RPC 日志配置 RpcLog: Stat: true # 開啟統(tǒng)計(jì)日志 Slow: true # 開啟慢日志
9.3 Docker 環(huán)境配置
# docker-compose.yaml 中的日志配置
services:
user-api:
image: user-api:latest
volumes:
- ./logs:/app/logs # 掛載日志目錄
environment:
- LOG_MODE=file
- LOG_LEVEL=info
十、總結(jié)與檢查清單
? 日志配置檢查清單
- 是否配置了 Log.Mode(開發(fā)用console,生產(chǎn)用file)
- 是否配置了合適的 Log.Level(開發(fā)用debug,生產(chǎn)用info)
- 是否配置了 Log.Path(生產(chǎn)環(huán)境)
- 是否配置了日志輪轉(zhuǎn)(MaxSize、MaxBackups、KeepDays)
- 是否開啟了日志壓縮(Compress: true)
- 是否配置了鏈路追蹤(Telemetry)
? 日志使用檢查清單
- 關(guān)鍵業(yè)務(wù)操作是否有日志記錄
- 錯(cuò)誤處理是否記錄了詳細(xì)錯(cuò)誤信息
- 日志是否使用了 WithContext 以便鏈路追蹤
- 日志是否包含了足夠的上下文信息
- 是否避免了記錄敏感信息
- 高頻操作是否控制了日志數(shù)量
- 是否使用了結(jié)構(gòu)化日志(Infow、Errorw)
? 問題排查檢查清單
- 是否能通過 trace_id 追蹤完整請求鏈路
- 是否能快速定位錯(cuò)誤日志
- 是否能分析慢查詢和性能瓶頸
- 是否配置了日志收集系統(tǒng)(生產(chǎn)環(huán)境)
- 是否定期清理舊日志文件
- 是否有日志監(jiān)控告警(嚴(yán)重錯(cuò)誤)
附錄:常見問題
Q1: 日志文件太大怎么辦?
- 調(diào)整 MaxSize 和 KeepDays
- 提高日志級別(info -> error)
- 減少不必要的日志輸出
- 開啟 Compress 壓縮
Q2: 找不到某個(gè)請求的日志?
- 檢查日志級別配置
- 確認(rèn)日志是否被輪轉(zhuǎn)
- 檢查時(shí)區(qū)是否正確
- 確認(rèn)該請求是否真的到達(dá)了服務(wù)
Q3: 日志亂碼怎么辦?
- 確保使用 UTF-8 編碼
- 檢查 Encoding 配置
- 使用
cat -A查看特殊字符
Q4: 如何在代碼中動態(tài)修改日志級別?
// 運(yùn)行時(shí)修改日志級別(不推薦生產(chǎn)環(huán)境) logx.SetLevel(logx.ErrorLevel)
Q5: 容器環(huán)境日志如何收集?
# 使用 volume 模式 Log: Mode: volume Path: /var/log/app # Docker 掛載 volumes: - ./logs:/var/log/app
到此這篇關(guān)于Go中Zero日志使用指南的文章就介紹到這了,更多相關(guān)Go Zero日志使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang實(shí)現(xiàn)基于角色的訪問控制(RBAC)的項(xiàng)目實(shí)踐
基于角色的訪問控制(RBAC)是一種安全機(jī)制,通過角色來管理用戶權(quán)限,本文介紹了一種可落地、易擴(kuò)展的Golang?RBAC實(shí)現(xiàn)方案,具有一定的參考價(jià)值,感興趣的可以了解一下2025-12-12
Go語言實(shí)現(xiàn)請求頻率限制的方法實(shí)踐
本文介紹了Go語言中四種主流的請求限流方案,包括計(jì)數(shù)器法、Redis滑動窗口、令牌桶算法和使用成熟中間件,每種方案都有優(yōu)缺點(diǎn),適用于不同的場景,下面就來詳細(xì)的介紹一下,感興趣的可以了解一下2026-04-04
淺析Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作
這篇文章主要為大家詳細(xì)介紹了Go項(xiàng)目中的依賴包管理與Go?Module常規(guī)操作,文中的示例代碼講解詳細(xì),對我們深入了解Go語言有一定的幫助,需要的可以跟隨小編一起學(xué)習(xí)一下2023-10-10

