- 首页 >
- 问答 >
-
编程语言 >
- CentOS上Golang日志如何进行故障排查
CentOS上Golang日志如何进行故障排查
小樊
40
2025-12-23 13:04:47
CentOS上Golang日志故障排查实操指南
一 定位日志来源与实时查看
- 若应用由 systemd 托管,优先用 journalctl 查看服务日志,便于获取启动参数、标准输出/错误、崩溃堆栈与 systemd 自身事件:
- 实时跟踪:journalctl -u your_golang_app.service -f
- 按时间筛选:journalctl -u your_golang_app.service --since “2025-12-23 10:00:00”
- 只看错误级别:journalctl -u your_golang_app.service -p err -b
- 若应用直接写文件,使用 tail 实时查看并配合常用命令分析:
- 实时跟踪:tail -f /var/log/myapp/*.log
- 关键字过滤:grep -i “error|panic|fatal” /var/log/myapp/app.log
- 时间窗口:awk ‘/2025-12-23 10:00:00/,/2025-12-23 10:30:00/’ /var/log/myapp/app.log
- 错误频次统计:grep -i error /var/log/myapp/app.log | sort | uniq -c | sort -nr
- 以上命令覆盖本地文件与 systemd 场景,适合快速定位异常时间点与高频错误。
二 应用侧日志配置与分级
- 使用标准库 log 的基础做法(便于快速接入):
- 输出到控制台并带源文件和行号:log.SetOutput(os.Stdout); log.SetFlags(log.LstdFlags | log.Lshortfile)
- 输出到文件:logFile, _ := os.OpenFile(“/var/log/myapp/app.log”, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); log.SetOutput(logFile)
- 使用 logrus(结构化、易读):
- 设置级别与格式:logrus.SetLevel(logrus.DebugLevel); logrus.SetFormatter(&logrus.JSONFormatter{})
- 多目标输出(控制台+文件):multiWriter := io.MultiWriter(os.Stdout, logFile); logrus.SetOutput(multiWriter)
- 使用 zap(高性能、结构化生产常用):
- 生产配置示例(JSON、时间 ISO8601、输出到 stdout/stderr):
- config := zap.Config{ Level: zap.NewAtomicLevelAt(zap.InfoLevel), Encoding: “json”, EncoderConfig: zapcore.EncoderConfig{ TimeKey: “ts”, LevelKey: “level”, MessageKey: “msg”, StacktraceKey: “stacktrace”, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder }, OutputPaths: []string{“stdout”}, ErrorOutputPaths: []string{“stderr”} }
- logger, _ := config.Build(); defer logger.Sync()
- 建议:在问题排查阶段将级别临时调为 DEBUG,上线后恢复 INFO/WARN;优先采用 JSON 结构化日志,便于检索与聚合。
三 日志轮转与保留策略
- 使用 logrotate 管理日志体积与保留期,创建 /etc/logrotate.d/myapp:
- 示例配置(按天轮转、保留 7 天、压缩、缺失不报错、空文件不轮转、权限 0640、属主 root:root):
- /var/log/myapp/*.log { daily missingok rotate 7 compress notifempty create 0640 root root }
- 手动强制执行一次(调试用):logrotate -f /etc/logrotate.d/myapp
- 说明:轮转可避免单文件过大、磁盘被占满,同时保留历史便于回溯。
四 集中化收集与可视化
- 小规模或快速接入可用 Fluentd 收集并写入 Elasticsearch,再用 Kibana 可视化:
- 安装:sudo yum install -y fluentd
- 配置 /etc/fluent/fluent.conf(示例):
- @type tail path /var/log/myapp/*.log pos_file /var/log/fluentd-myapp.log.pos tag myapp @type none
- <match myapp.> @type elasticsearch host localhost port 9200 logstash_format true flush_interval 10s **
- 启动:sudo systemctl start fluentd && sudo systemctl enable fluentd
- 复杂场景可选 ELK Stack 或 Graylog 做集中管理与检索分析。
五 快速排查清单与最小示例
- 排查清单
- 确认日志路径与权限:应用是否有权写 /var/log/myapp/,目录与文件权限是否合适(如 0640 root:root)。
- 确认运行方式与输出:是 systemd 还是直接运行;是否将 stdout/stderr 正确接入 journalctl 或日志文件。
- 提升日志级别到 DEBUG 并复现问题;在日志中打印关键上下文(如 request_id、trace_id、user_id、SQL/HTTP 参数)。
- 搜索错误与异常:按时间窗定位首次异常,关注 panic、fatal、timeout、connection refused 等关键词及堆栈。
- 检查轮转与磁盘:确认 logrotate 正常执行,避免因磁盘满导致写入失败或丢失日志。
- 需要跨机器分析时,先接入 Fluentd/ELK/Graylog 做统一检索与可视化。
- 最小可复现示例(标准库 + systemd + logrotate)
- 代码示例(写入 /var/log/myapp/app.log 并带源文件行号):
- package main
- import ( “log” “os” )
- func main() { f, _ := os.OpenFile(“/var/log/myapp/app.log”, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); defer f.Close(); log.SetOutput(f); log.SetFlags(log.LstdFlags | log.Lshortfile); log.Println(“app started”); log.Fatal(“something went wrong”) }
- systemd 单元示例(/etc/systemd/system/myapp.service):
- [Unit]
- Description=My Go App
- After=network.target
- [Service]
- ExecStart=/usr/local/bin/myapp
- Restart=on-failure
- StandardOutput=journal
- StandardError=journal
- [Install]
- WantedBy=multi-user.target
- 查看与排查:
- 启动/查看:sudo systemctl daemon-reload && sudo systemctl start myapp && sudo journalctl -u myapp -f
- 轮转验证:sudo logrotate -f /etc/logrotate.d/myapp 后确认新日志生成。