Ente 基础设施日志采集实战:用 Promtail 将实例日志接入 Grafana Loki
【免费下载链接】ente💚 End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/ente
本文以 Ente 仓库infra/services/promtail目录下的官方部署文档及配套的 systemd 单元文件、Promtail 配置为骨架,完整讲解 Promtail 在 Ente 托管基础设施中的定位、安装流程与配置原理。读完本文,你将掌握在任意运行着需要监控的服务的实例上,通过 systemd + Docker 方式部署 Promtail、改写client.url与scrape_configs、并把日志送入 Grafana(Loki)的完整实操方案。
一、Promtail 在 Ente 基础设施中的角色
Ente 仓库的 infra/README.md 明确指出:infra目录承载的是"运营 Ente 托管基础设施所需的附加服务与工具",这些服务并非运行或自托管 Ente 本身所必需。换句话说,Promtail 属于团队内部运维栈的一部分,与 Grafana、Prometheus、Sentry、Metabase 等并列。
其中日志观测链路的分工是:
- Grafana:日志与指标的可视化前端,数据存放在名为
grafana-storage的 Docker 持久卷中(见 infra/services/grafana/README.md); - Promtail:负责在目标实例上采集日志并推送到 Loki(Grafana 的日志存储后端)。
官方 README 用一句话定义了 Promtail 的部署条件:
Install
promtail.serviceon an instance if it is running something whose logs we want in Grafana.
即:只要某个实例上运行着"我们希望其日志出现在 Grafana 中"的服务,就在该实例上安装 promtail 服务。这也是判断是否需要部署 Promtail 的唯一标准。
二、部署文件组成
infra/services/promtail/目录下共三个文件,构成了完整的可部署单元:
| 文件 | 作用 |
|---|---|
| README.md | 安装说明文档 |
| promtail.service | systemd 单元文件,负责拉起并守护 Promtail 的 Docker 容器 |
| promtail.yaml | Promtail 采集配置:Loki 推送地址与各日志源的 scrape 任务 |
安装的核心思路是:把这两个文件分别放置到系统路径下(配置放/root/promtail.yaml,单元文件放/etc/systemd/system/promtail.service),随后交给 systemd 管理。
三、完整安装步骤
按 README 的流程,安装分两步:先传文件并改配置,再让 systemd 接管服务。
3.1 传输文件并修改配置
scp services/promtail/promtail.* <instance>: nano promtail.yaml sudo mv promtail.yaml /root/promtail.yaml sudo mv promtail.service /etc/systemd/system/promtail.service三个动作各司其职:
scp把promtail.service与promtail.yaml两个文件拷贝到目标实例的用户主目录;nano promtail.yaml要求你手工替换client.url——即把配置中 Loki 地址改为 Promtail 应当连接的那个 Loki URL(这是 README 明确强调的唯一必改项,详见下文配置解析);- 两个
sudo mv把文件放到约定位置:配置在/root/promtail.yaml,systemd 单元在/etc/systemd/system/promtail.service。路径与单元文件中的挂载点一一对应,不能随意更换。
3.2 让 systemd 接管服务
sudo systemctl daemon-reload sudo systemctl enable --now promtaildaemon-reload:让 systemd 重新读取新放入的服务定义文件;enable --now promtail:同时完成"开机自启"(enable)与"立即启动"(now)两个动作,避免分两步操作。
四、systemd 单元文件剖析
promtail.service 完整内容如下:
[Unit] Documentation=https://grafana.com/docs/loki/latest/clients/promtail/ Requires=docker.service After=docker.service [Install] WantedBy=multi-user.target [Service] ExecStartPre=docker pull grafana/promtail ExecStartPre=-docker stop promtail ExecStartPre=-docker rm promtail ExecStart=docker run --name promtail \ --hostname "%H" \ -v /root/promtail.yaml:/config.yaml:ro \ -v /var/log:/var/log \ -v /root/var/logs:/var/logs:ro \ -v /var/lib/docker/containers:/var/lib/docker/containers:ro \ grafana/promtail -config.file=/config.yaml -config.expand-env=true几个值得注意的实现细节:
- 依赖 Docker:
Requires=docker.service+After=docker.service声明 Promtail 容器依赖 Docker 守护进程,保证启动顺序正确; - 启动前自愈:
ExecStartPre依次执行docker pull grafana/promtail(拉取最新镜像)、docker stop promtail与docker rm promtail。后两条命令前缀的-表示即使执行失败也不阻断服务启动——首次安装时容器不存在,stop/rm 失败是预期行为,这是幂等部署的典型写法; - 四个挂载点各有用途:
/root/promtail.yaml:/config.yaml:ro:把宿主机上改好的配置以只读方式注入容器,容器内以/config.yaml路径使用;/var/log:/var/log:暴露系统日志目录(可写),用于按需采集;/root/var/logs:/var/logs:ro:暴露 Ente 各服务的自写日志目录(只读),这正是promtail.yaml中__path__: /var/logs/*.log的宿主机来源;/var/lib/docker/containers:/var/lib/docker/containers:ro:暴露 Docker 容器日志目录(只读),用于采集所有容器的 JSON 日志;
--hostname "%H":把容器主机名设为 systemd 单元所在机器的宿主机名(%H是 systemd specifier),为后续host标签提供来源;-config.expand-env=true:开启 Promtail 配置中的环境变量展开,使得promtail.yaml里的${HOSTNAME}得以被替换为真实主机名。
五、Promtail 配置深度解析
promtail.yaml 完整内容如下:
server: disable: true clients: - url: http://loki:3100/loki/api/v1/push # Manually add entries for all our services. This is a bit cumbersome, but # - Retains flexibility in file names. # - Makes adding job labels easy. # - Does not get in the way of logrotation. scrape_configs: - job_name: museum static_configs: - labels: job: museum host: ${HOSTNAME} __path__: /var/logs/museum.log - job_name: copycat-db static_configs: - labels: job: copycat-db host: ${HOSTNAME} __path__: /var/logs/copycat-db.log - job_name: phoenix static_configs: - labels: job: phoenix host: ${HOSTNAME} __path__: /var/logs/phoenix.log - job_name: docker static_configs: - labels: job: docker host: ${HOSTNAME} __path__: /var/lib/docker/containers/*/*-json.log5.1 server 与 clients
server.disable: true:关闭 Promtail 自带的 HTTP 服务(它本身不对外暴露端口,纯采集推送角色);clients[0].url:Loki 的推送端点,即 README 要求替换的那一项。默认值http://loki:3100/loki/api/v1/push是典型的 Docker 网络内主机名写法,实际部署时应改为目标环境真实可达的 Loki 地址。
5.2 scrape_configs 的设计哲学
配置中注释明确解释了为什么采用手工逐个添加日志源,而不是用 glob 通配一把抓:
- 保留文件名的灵活性(不同服务日志文件名各异);
- 添加 job 标签非常容易(每个 job 直接对应一个
job标签); - 不会干扰 logrotate 轮转(固定路径采集,避免通配导致重复读取或误读轮转中的文件)。
5.3 四个预置采集任务
| job_name | 采集路径 | 日志内容 |
|---|---|---|
museum | /var/logs/museum.log | 照片服务后端 museum 的运行日志 |
copycat-db | /var/logs/copycat-db.log | 数据库备份服务日志 |
phoenix | /var/logs/phoenix.log | 备份可恢复性验证服务日志 |
docker | /var/lib/docker/containers/*/*-json.log | 实例上所有 Docker 容器的标准 JSON 日志 |
前三个任务共用相同的模式:host标签通过${HOSTNAME}取自环境变量(依赖单元文件中的-config.expand-env=true),job标签固定为服务名,__path__指向/var/logs/下对应的.log文件——该目录在单元文件里以只读卷挂载进容器。第四个docker任务则直接采集 Docker 守护进程落盘的*-json.log容器日志文件。
5.4 环境变量展开的工程意义
一个值得对比的细节:Prometheus 的 README(infra/services/prometheus/README.md)特意提醒"Prometheus 目前不支持配置文件中的环境变量,因此除了添加remote_write配置外,还要记得修改硬编码的XX-HOSTNAME";而 Promtail 通过-config.expand-env=true原生支持${HOSTNAME}展开。这意味着同一份promtail.yaml可以不加修改地部署到多台实例,host标签会自动区分日志来源——这正是该设计要解决的问题。
六、如何为某个服务接入日志采集
将一个新服务的日志纳入 Grafana,在 Ente 的运维模式中只需三步:
- 确保服务把日志写入
/root/var/logs/下的固定文件。以数据库备份服务 copycat-db 为例,其 README(infra/copycat-db/README.md)明确写到:"服务将日志写到标准输出与标准错误,systemd 单元把这些输出重定向到/root/var/logs/copycat-db.log",并提示"本地查看sudo tail /root/var/logs/copycat-db.log,日志同样会出现在 Grafana 上"——后者正是经由 Promtail 的copycat-db采集任务实现的; - 在
promtail.yaml的scrape_configs中按既有模式新增一个 job:指定job_name、job/host标签与__path__; - 重启 Promtail 使配置生效:
sudo systemctl restart promtail。
新任务沿用host: ${HOSTNAME}的写法,即可自动带上实例标识,在 Grafana 中按实例 + 服务两个维度过滤日志。
七、运维与注意事项小结
- 配置改动后必须重启:Promtail 不会热加载配置文件,修改
promtail.yaml后需sudo systemctl restart promtail; - 只读挂载防误改:配置、
/var/logs、Docker 容器日志三处以:ro只读挂载,容器内无法意外篡改数据源; - 幂等部署:
ExecStartPre中的 stop/rm 配合-容错前缀,使重复执行安装/重启都安全; - 采集范围与 logrotate 兼容:固定文件路径的手工任务设计,避免了通配采集在日志轮转时产生的重复或丢失问题;
- 适用范围:Promtail 属于 infra 托管运维栈,仅服务于 Ente 官方托管基础设施的日志观测;自托管 Ente 时并不需要部署它。
通过这套 systemd + Docker 包装的 Promtail 方案,Ente 团队实现了"在任意实例上两三条命令即可接入日志观测体系"的标准化流程,也为需要自建 Grafana Loki 日志栈的开发者提供了一个简洁、可复用的参考模板。
【免费下载链接】ente💚 End-to-end encrypted cloud for everything.项目地址: https://gitcode.com/GitHub_Trending/en/ente
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考