在 Debian 上用 Go 写服务时,“日志怎么定位错”通常可以从 日志内容、日志位置、错误堆栈、系统日志 几个层面来做。下面给你一套比较实用的定位思路。
Go 程序一般用:
loglog/slogzaplogrus常见输出位置:
/var/log/yourapp.log先看程序是怎么初始化的:
log.SetOutput(os.Stdout)
// 或
log.SetOutput(&lumberjack.Logger{
Filename: "/var/log/yourapp.log",
})
如果是 systemd 启动:
journalctl -u yourapp.service -f
journalctl -u yourapp.service --since "10 min ago"
查看是否报错:
journalctl -u yourapp.service -p err
Go 的错误通常只是一行字符串:
if err != nil {
log.Println("db query failed:", err)
}
重点看:
用 pkg/errors 或 fmt.Errorf + %w:
import "github.com/pkg/errors"
err := errors.Wrap(err, "failed to connect db")
log.Println(err)
或 Go 1.13+:
err := fmt.Errorf("failed to connect db: %w", err)
这样日志里能看到:
failed to connect db: dial tcp 127.0.0.1:5432: connect: connection refused
panic: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
main.main()
/home/user/app/main.go:23 +0x45
关键信息:
main.go:23 → 出错代码行goroutine 1 → 主协程在 Debian 服务里建议加:
defer func() {
if r := recover(); r != nil {
log.Println("panic:", r)
}
}()
dmesg | tail
常见:
ls -l /var/log/yourapp.log
ss -tulnp | grep 8080
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Error("db query failed",
slog.String("sql", "select * from user"),
slog.Int("uid", 123),
slog.Any("error", err),
)
好处:
✅ 看 systemd 日志
✅ 看应用日志文件
✅ 找 error / panic 关键字
✅ 看错误前后上下文
✅ 确认端口 / 权限 / 配置
✅ 本地用相同参数跑一次
如果你愿意,可以把 具体错误日志贴出来(脱敏后),我可以直接帮你定位是哪一类问题。