服务挂了能自动重启,这只是第一步。
上一篇写过最低成本的告警与自愈(systemd + Docker + Uptime Kuma + 飞书/微信推送),很多人反馈:知道挂了、能自己起来,但到底为什么挂,还是得靠日志和指标。
这篇文章继续同一个原则——几乎零额外费用、私有部署、国内可访问。不推 ELK 全家桶,不推需要一堆内存的商业 SaaS,只讲能在 1~2 核、2~4G 内存的小机器上长期跑得动的方案。
一、先把“免费已经有的”用好
1. journald 是你的默认日志中心
如果你已经按之前的建议把服务交给了 systemd(或者 Docker 容器用 journald 驱动),那你其实已经有了一套集中日志:
# 看某个服务最近日志
journalctl -u your-service -f --no-pager
# 看 Docker 相关
journalctl -u docker -f
# 按优先级过滤
journalctl -p err..alert -b
把 Docker 日志驱动改成 journald 是性价比最高的一步:
// /etc/docker/daemon.json
{
"log-driver": "journald",
"log-opts": {
"tag": "{{.Name}}"
}
}
重启 Docker 后,所有容器日志都会进 journald,后续可以用 journalctl CONTAINER_NAME=xxx 直接查。
优点:零额外进程、零额外存储配置、和 systemd 重启策略天然一体。
缺点:查询体验一般,跨主机不方便,没有漂亮的 Web 界面。
2. Cockpit 作为“系统自带面板”
如果机器上已经装了 Cockpit(很多发行版默认有或一键安装),它自带日志查看器,能看 journald、能过滤、能导出。对单机私有部署来说已经够用。
二、最低成本 Web 日志查看:Dozzle
只想快速看 Docker 容器实时日志,不想折腾复杂栈,Dozzle 是目前最轻的选择之一。
- 单二进制 / 单容器
- 纯前端,几乎不占资源
- 支持多主机(加 agent)
- 国内镜像拉取友好
# docker-compose.yml 片段
services:
dozzle:
image: amir20/dozzle:latest
container_name: dozzle
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "8080:8080"
restart: unless-stopped
访问 http://你的IP:8080 就能实时刷所有容器日志。配合前面的 journald 驱动,效果已经很好。
国内建议先配置 Docker 镜像加速(例如 https://docker.xuanyuan.me 等当前可用源),避免拉官方镜像超时。
三、指标侧最低成本:Netdata 或 Beszel
日志解决“发生了什么”,指标解决“机器现在健康吗”。
方案 A:Netdata(成熟、功能全)
一键安装,自动发现 Docker、磁盘、网络、进程,自带漂亮仪表盘和告警。
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh --stable-channel
资源占用比以前低很多,单机 100~300MB 内存级别。对私有小站完全够用。
方案 B:Beszel(更轻)
如果你追求极致低资源,可以看 Beszel(agent 约 10~15MB)。适合“只想知道 CPU/内存/磁盘/负载是否正常”的场景。
两者都可以和之前的 Uptime Kuma 告警互补:Uptime Kuma 管“服务活着没”,Netdata/Beszel 管“资源用到什么程度了”。
四、真正想要“可观测性”时:Loki + Grafana(仍然可控)
当 journalctl 和 Dozzle 不够用(需要按标签查询、跨服务关联、长期保留、漂亮看板)时,再上 Loki + Grafana。
为什么选它而不是 ELK:
- Loki 只索引标签,不索引全文,磁盘和内存友好得多
- 官方支持单二进制 / 单 Docker 运行
- 和 Grafana 原生集成,LogQL 学习成本低
- 国内已有中文文档站点(grafana.org.cn)
最小可运行 Compose 示例(本地文件系统存储)
version: "3.8"
services:
loki:
image: grafana/loki:3.0.0
command: -config.file=/etc/loki/local-config.yaml
ports:
- "3100:3100"
volumes:
- ./loki-data:/loki
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=你的强密码
volumes:
- ./grafana-data:/var/lib/grafana
depends_on:
- loki
restart: unless-stopped
# 推荐用 Alloy 或 Vector 采集,这里用简单的 promtail 示例
promtail:
image: grafana/promtail:3.0.0
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki
restart: unless-stopped
Promtail 配置里把 Docker 容器日志和 journal 都送过去即可。Grafana 添加 Loki 数据源(URL 填 http://loki:3100),就可以用 LogQL 查了。
资源建议:
- 单机私有服务:Loki 给 256~512MB 内存限制就够起步
- 日志保留 7~15 天对大多数个人/小团队已经足够
- 定期用
docker system prune和 Loki 的 retention 配置控制磁盘
国内部署注意点
- 镜像加速:务必配置 Docker registry-mirrors,推荐当前可用的国内源(如轩辕镜像等),否则 grafana/loki、grafana/grafana 拉取会很痛苦。
- 中文文档:优先看 grafana.org.cn 的 Loki 安装文档,比官方英文站更友好。
- 反向代理 + 认证:Grafana 和 Dozzle 都不要直接暴露公网,前面挂 Nginx/Caddy + 基础认证或 SSO。
- 告警闭环:Grafana 告警可以继续推到飞书/微信/Webhook,和之前的 Uptime Kuma 形成互补。
五、渐进推荐路径(按投入排序)
| 阶段 | 方案 | 额外资源 | 解决什么 |
|---|---|---|---|
| 0 | journald + systemd | 0 | 基础日志、和自愈联动 |
| 1 | + Dozzle | 极低 | Docker 实时日志 Web 查看 |
| 2 | + Netdata / Beszel | 低 | 系统/容器指标 + 简单告警 |
| 3 | + Loki + Grafana | 中低 | 结构化查询、看板、长期保留 |
| 4 | + Alloy/Vector + 更多 exporter | 中 | 更完整的可观测性 |
大多数私有部署到阶段 2 或 3 就已经足够。别一上来就上完整的 Prometheus + Tempo + Mimir 全家桶,那是给真正有 SRE 团队的规模用的。
六、和之前告警方案怎么配合
- Uptime Kuma:管“活着没、响应时间、证书过期”
- systemd 自愈:管“挂了自动起来”
- 本篇日志 + 指标:管“为什么挂、现在资源怎么样、最近有没有异常日志”
三者叠在一起,基本就是一套能长期自己用的私有可观测闭环,成本几乎只有机器本身的电费和带宽。
结语
可观测性不是“上了某套著名开源项目”才叫可观测性。对个人和小型私有部署来说,能快速回答三个问题就够了:
- 服务现在活着吗?
- 它最近为什么挂过?
- 机器资源还撑得住吗?
journald + Dozzle + Netdata(或轻量替代)已经能回答大部分问题。真需要更强查询和看板时,再上 Loki + Grafana,并且用国内镜像源把门槛降下来。
下次如果服务又挂了,至少不用再两眼一抹黑。
(完)
Docker / systemd 之外,日志与可观测性最低成本怎么搭
https://wangling.hauchet.cn/archives/low-cost-logging-observability-beyond-docker-systemd
评论