用 Golang 日志定位 CentOS 问题的实操流程
一 日志采集与输出规范
示例 最小可用配置
package main
import (
"github.com/sirupsen/logrus"
"os"
)
func main() {
logger := logrus.New()
logger.SetLevel(logrus.InfoLevel)
logger.SetFormatter(&logrus.JSONFormatter{})
f, _ := os.OpenFile("/var/log/myapp.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
defer f.Close()
logger.SetOutput(f)
logger.WithFields(logrus.Fields{"svc": "order"}).Info("service started")
}
package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
cfg := 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, _ := cfg.Build()
defer logger.Sync()
logger.Info("service started")
}
# /etc/systemd/system/myapp.service
[Unit]
Description=My Go App
After=network.target
[Service]
ExecStart=/usr/local/bin/myapp
Restart=always
StandardOutput=journal
StandardError=journal
User=myapp
Group=myapp
[Install]
WantedBy=multi-user.target
# /etc/logrotate.d/myapp
/var/log/myapp.log {
daily
rotate 7
compress
missingok
notifempty
create 0644 myapp myapp
}
二 定位问题的排查路径
三 常见症状 日志关键字 与处置要点
| 症状 | 优先查看 | 关键字与判断 | 快速处置 |
|---|---|---|---|
| 服务启动失败 | 应用日志、journalctl -u | “failed to bind”、“permission denied”、“config error” | 检查端口占用、运行用户权限、配置路径与语法 |
| 运行期 5xx/panic | 应用日志 | “panic”、“recover”、“stacktrace”、“timeout” | 抓取堆栈与请求上下文,开启更详细日志或调试环境复现 |
| 高延迟/超时 | 应用日志、system日志 | “context deadline exceeded”、“i/o timeout”、“slow query” | 结合数据库/下游依赖日志与网络延迟,定位瓶颈 |
| 进程意外退出 | journalctl -xe、应用日志 | “exited with code”、“killed”、“oom-killer” | 检查 OOM、资源限制(ulimit)、依赖崩溃 |
| 磁盘写满导致日志中断 | /var/log、df、dmesg | “no space left on device”、“disk full” | 清理旧日志、加速轮转、扩容磁盘或改写入路径 |
提示:
四 性能与可用性增强
示例 pprof 接入
import (
_ "net/http/pprof"
"log"
"net/http"
)
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// 业务代码
}