在 Debian 上采集 Golang 应用的日志,常见做法主要有 应用层日志输出 + 系统层采集 两部分。下面按“最常用、最稳妥”的方式给你一个完整方案。
log 或结构化日志库推荐:
log/slog(Go 1.21+,官方结构化日志)zap(Uber,高性能)logrus(老牌,但已不活跃)package main
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("server start", "port", 8080)
}
✅ 关键点:输出到 stdout / stderr
如果你用 systemd 管理 Golang 服务,这是最标准的方式。
# /etc/systemd/system/myapp.service
[Unit]
Description=Golang App
After=network.target
[Service]
ExecStart=/usr/local/bin/myapp
Restart=always
User=appuser
WorkingDirectory=/opt/myapp
# 日志自动进入 journald
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
journalctl -u myapp -f
✅ 优点
f, _ := os.OpenFile("/var/log/myapp/app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
log.SetOutput(f)
⚠️ 不推荐直接写文件,除非你有特殊需求。
示例(rsyslog):
# /etc/rsyslog.d/myapp.conf
input(type="imfile" File="/var/log/myapp/app.log" Tag="myapp")
docker logs <container_id>
kubectl logs pod-name
✅ 容器里一定要输出到 stdout/stderr
| 场景 | 推荐方案 |
|---|---|
| Debian 物理机 / 虚拟机 | systemd + journald |
| 需要集中采集 | journald → filebeat → ELK |
| 容器 | stdout + Docker / K8s |
| 结构化日志 | slog / zap(JSON) |
❌ Golang 写文件 + 自己 rotate
❌ 日志不输出时间戳
❌ 日志量大不限制
Golang → stdout (JSON)
↓
systemd service
↓
journald
↓
filebeat → Elasticsearch / Loki
如果你愿意,可以告诉我:
我可以直接给你 一套可复制的完整配置。