温馨提示×

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 StackGraylog 做集中管理与检索分析。

五 快速排查清单与最小示例

  • 排查清单
    • 确认日志路径与权限:应用是否有权写 /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 后确认新日志生成。

0