Loki日志收集配置:从零搭建Promtail采集与查询链路
Loki 日志收集配置的核心思路只有一句话:用 Promtail 读取服务器上的日志文件,打上标签后推送到 Loki,再用 Grafana 或 LogCLI 按标签查询。
它适合单机或小规模服务器场景,不需要像 Elasticsearch 那样占用大量内存。
下面按可直接照做的顺序讲清楚每一步。
准备条件与目录规划
开始前请确认服务器满足以下条件:
- Linux 系统(CentOS 7+、Ubuntu 20.04+ 均可),已安装 Docker 与 Docker Compose。
- 至少 1GB 可用内存,Loki 本身较轻,但 Grafana 会占一部分。
- 一个用于存放配置和数据的目录,例如
/opt/loki。 - 被采集的日志文件路径明确,例如 Nginx 的
/var/log/nginx/access.log。
创建目录结构:
mkdir -p /opt/loki/{config,data,logs}
cd /opt/loki
这里 config 放配置文件,data 放 Loki 数据,logs 用来做测试日志。
用 Docker Compose 启动 Loki 与 Promtail
先写 Loki 配置文件 /opt/loki/config/loki-config.yaml:
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 168h
retention_period: 168h 表示日志保留 7 天,可按磁盘容量调整。
接着写 Promtail 配置 /opt/loki/config/promtail-config.yaml:
server:
http_listen_port: 9080
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
host: my-server
__path__: /var/log/*.log
- job_name: nginx
static_configs:
- targets:
- localhost
labels:
job: nginx
host: my-server
__path__: /var/log/nginx/*.log
关键点说明:
clients.url里的loki是 Docker Compose 服务名,容器之间可直接解析。__path__决定采集哪些文件,支持通配符。labels中的job和host是后续查询的主要过滤条件,不要随意省略。
然后写 /opt/loki/docker-compose.yml:
services:
loki:
image: grafana/loki:3.0.0
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
volumes:
- ./config/loki-config.yaml:/etc/loki/local-config.yaml
- ./data:/loki
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:3.0.0
container_name: promtail
restart: unless-stopped
volumes:
- ./config/promtail-config.yaml:/etc/promtail/config.yml
- /var/log:/var/log:ro
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki
grafana:
image: grafana/grafana:10.4.0
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
启动服务:
docker compose up -d
docker compose ps
看到 loki、promtail、grafana 三个容器状态为 Up 即表示启动成功。
验证日志是否被采集
先造一条测试日志:
echo "hello loki test $(date)" >> /var/log/test.log
注意 Promtail 挂载的是宿主机 /var/log,所以写入宿主机即可。
然后用 Loki 的查询接口验证:
curl -G -s "http://localhost:3100/loki/api/v1/query" \
--data-urlencode 'query={job="varlogs"}' \
--data-urlencode 'limit=5'
如果返回 JSON 中包含 hello loki test,说明采集链路已经通了。
也可以进入 Grafana(浏览器访问 http:,
//服务器IP:
3000
默认账号密码均为 admin),
在左侧菜单选择 Connections → Data sources → Add data source → Loki,
URL 填 http:,
//loki:
3100
保存后到 Explore 页面选择该数据源,
输入 {job="nginx"} 查询 Nginx 日志。
避坑与常见报错
容器内路径和宿主机路径混淆:Promtail 配置里的 __path__ 是容器内路径,所以必须把宿主机日志目录挂载进容器。
上例中挂载了 /var/log:/var/log:ro,如果只采集某个应用日志,记得单独加挂载。
标签基数过高:不要把 request_id、user_id 这类每次都变化的值放进 labels,否则 Loki 会生成大量索引流,内存和查询都会出问题。
这类字段应留在日志正文里,用过滤表达式查。
时间戳解析失败:如果日志行不是标准格式,Promtail 可能无法自动识别时间。
可在 scrape_configs 中加 pipeline_stages 配置 timestamp 阶段,或先不解析、由 Loki 接收时间。
Promtail 报 connection refused:先执行 docker compose logs promtail 看报错,再确认 Loki 容器是否正常、端口是否被占用。
常见原因是 Loki 还没启动完成 Promtail 就抢先连接,等待重启后自动恢复。
磁盘增长过快:在 Loki 配置中设置 retention_period,并确认 limits_config 生效。
如果数据卷持续膨胀,检查是否有大量高基数标签导致索引异常。
查询与日常维护
日常查日志主要靠标签,常用查询示例:
{job="nginx"} |= "500"
{job="varlogs", host="my-server"} |~ "error|fail"
第一条查 Nginx 中包含 500 的日志行,第二条用正则匹配 error 或 fail。
LogQL 的过滤在标签筛选之后执行,所以先写 {job="..."} 能大幅减少扫描量。
维护上建议定期做两件事:查看 docker compose logs --tail=100 确认没有持续报错;
用 df -h 检查 /opt/loki/data 所在分区剩余空间。
Loki 本身不负责告警,如果需要异常通知,可在 Grafana 中基于 LogQL 查询配置 Alert rules。
如果后续要采集多台服务器,
把 Promtail 的 clients.url 改成 Loki 所在服务器的实际地址,
并在每台机器单独部署 Promtail 即可,
不需要每台都装 Loki。