
Prometheus Loki 全栈实战:标签共享下的日志与指标融合可观测性
在现代可观测性体系中,Metrics(指标) 告诉我们系统哪里出了问题,Logs(日志) 则解释问题发生的原因。Prometheus 负责指标,而 Grafana Loki 是专门为 Prometheus 生态设计的轻量级日志聚合系统。二者最大的协同秘密在于:Loki 使用与 Prometheus 完全相同的标签模型来索引和查询日志。这意味着你可以用一模一样的 {job="nginx", env="prod"} 标签选择器,在 Grafana 中无缝地从指标跳转到日志,真正实现“指标发现问题,日志定位根因”的闭环。本文将带你从零部署 Loki 与 Promtail,配置标签映射,在 Grafana 中构建联动看板,并落地针对日志本身的监控与告警,让你的日志管道也具备完整的可观测性。
1. Loki + Prometheus:标签共享的本质
| 索引模型 | Loki 不索引日志全文,而是索引元数据标签(如 job, instance, env) |
| 标签来源 | Promtail 或客户端自动为日志附加标签,通常来自服务发现和文件路径 |
| Prometheus 兼容 | 标签名完全兼容 Prometheus 规则(字母、数字、下划线),查询语法相同 |
| 关联查询 | 在 Grafana 中,可通过相同标签值直接跳转(例如 {job="api"} 查看日志,rate(http_requests_total{job="api"}[5m]) 查看指标) |
这种设计让 Loki 成为一个“指标般的日志系统”,几乎不需要学习新语言,也大大降低了与 Prometheus 集成的门槛。
2. Loki 架构简介
Loki 采用类似 Prometheus 的读写路径:
- Distributor:接收日志,验证并分发到 Ingester。
- Ingester:缓存日志并写入对象存储。
- Querier:处理查询,从 Ingester 和存储中获取日志。
- Ruler(可选):用于日志告警规则评估(自 2.0 起支持)。
- Promtail:部署在每台机器上,采集日志并推送到 Loki,同时自动附加标签。
3. 部署 Loki 与 Promtail
推荐使用 Docker Compose 快速搭建,或基于 Helm 部署在 Kubernetes 中。
3.1 Docker Compose 方案
docker-compose.yml:
version: "3"
services:
loki:
image: grafana/loki:2.9.0
ports:
– "3100:3100"
command: –config.file=/etc/loki/loki–config.yaml
volumes:
– ./loki–config.yaml:/etc/loki/loki–config.yaml
– loki_data:/loki
promtail:
image: grafana/promtail:2.9.0
volumes:
– ./promtail–config.yaml:/etc/promtail/promtail–config.yaml
– /var/log:/var/log
command: –config.file=/etc/promtail/promtail–config.yaml
# 可选:添加 Grafana
grafana:
image: grafana/grafana:latest
ports:
– "3000:3000"
environment:
– GF_AUTH_ANONYMOUS_ENABLED=true
volumes:
loki_data:
3.2 Loki 配置 (loki-config.yaml)
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
chunk_idle_period: 5m
chunk_retain_period: 30s
max_transfer_retries: 0
schema_config:
configs:
– from: 2024-01-01
store: boltdb–shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
cache_ttl: 24h
filesystem:
directory: /loki/chunks
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
max_entries_limit_per_query: 5000
3.3 Promtail 配置 (promtail-config.yaml)
server:
http_listen_port: 9080
grpc_listen_port: 0
clients:
– url: http://loki:3100/loki/api/v1/push
scrape_configs:
– job_name: system
static_configs:
– targets:
– localhost
labels:
job: varlogs
__path__: /var/log/*.log
– job_name: docker
static_configs:
– targets:
– localhost
labels:
job: docker
__path__: /var/lib/docker/containers/*/*.log
# 可针对特定应用添加更细粒度的标签
– job_name: nginx
static_configs:
– targets:
– localhost
labels:
job: nginx
app: web
__path__: /var/log/nginx/*.log
关键点:Promtail 的 labels 中的 job、app 等会直接成为 Loki 的索引标签,而 __path__ 是内部发现标签,不会进入日志流。
4. 与 Prometheus 标签对齐的最佳实践
为了让 Loki 与 Prometheus 无缝联动,标签命名和取值应与 Prometheus 完全一致:
| job="nginx" | job="nginx" | 二者抓取配置的 job 名应一致 |
| instance="web-01" | instance="web-01" | 主机名或实例 ID |
| env="prod" | env="prod" | 环境标签 |
| app="order-service" | app="order-service" | 应用名称 |
在 Promtail 的 static_configs 或 kubernetes_sd_configs 中,从目标元数据提取这些标签并重命名,确保与 Prometheus 抓取的标签相同。
示例:Kubernetes 环境下的标签对齐
# Promtail 在 K8s 中的采集配置
scrape_configs:
– job_name: kubernetes–pods
kubernetes_sd_configs:
– role: pod
relabel_configs:
– source_labels:
– __meta_kubernetes_pod_label_app
target_label: app
– source_labels:
– __meta_kubernetes_namespace
target_label: namespace
– action: replace
source_labels:
– __meta_kubernetes_pod_name
target_label: instance
– action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
这样,Loki 中的 {app="order-service", namespace="production"} 就能匹配 Prometheus 中 app="order-service", namespace="production" 的指标。
5. 在 Grafana 中实现指标与日志联动
5.1 添加 Loki 数据源
在 Grafana 配置中添加 Loki 数据源,URL 指向 http://loki:3100。保存后即可在 Explore 中查询日志。
5.2 创建联动仪表盘
在监控面板中,可以直接从指标图形跳转到 Loki 查询:
- 编辑 Prometheus 面板,在 Links 中添加一条:
- 类型:Data link
- URL:/explore?left={"datasource":"Loki","queries":[{"expr":"{app=\\"${app:queryparam}\\", job=\\"${job:queryparam}\\"}"}]}
- 这样点击图形上某个时间点,就会打开对应标签的日志上下文。
或者在 Grafana 8+ 版本中,使用 Logs 面板 直接放在指标面板下方,过滤相同标签。
Grafana 内置的 Loki 查询变量 可以从 Prometheus 指标的值动态生成,例如查询 {job="nginx"} 中的唯一 host 标签。
6. 监控 Loki 自身:让日志管道也透明
Loki 暴露 Prometheus 指标端点(默认 http://loki:3100/metrics),包含组件健康、请求延迟、Ingester 内存、存储操作等。Promtail 也暴露端点(http://promtail:9080/metrics)。
6.1 配置 Prometheus 抓取 Loki 指标
scrape_configs:
– job_name: 'loki'
scrape_interval: 15s
static_configs:
– targets: ['loki:3100']
labels:
component: 'loki'
– job_name: 'promtail'
scrape_interval: 15s
static_configs:
– targets: ['promtail:9080']
labels:
component: 'promtail'
6.2 核心 Loki 指标与 PromQL
| loki_distributor_lines_received_total | 接收到的日志行数 |
| loki_ingester_chunks_flushed_total | 刷盘到存储的块数量 |
| loki_ingester_memory_streams | 内存中的日志流数量 |
| loki_request_duration_seconds_bucket | Loki API 请求延迟直方图 |
| promtail_read_lines_total | Promtail 读取的日志行数 |
| promtail_dropped_lines_total | 丢弃的行数(如因速率限制) |
| promtail_file_fd_open_total | 打开的文件描述符数 |
PromQL 示例:
- Loki 日志接收速率:rate(loki_distributor_lines_received_total[5m])
- Ingester 内存压力:loki_ingester_memory_streams > 10000
- Promtail 是否有日志丢弃:rate(promtail_dropped_lines_total[5m]) > 0
6.3 Grafana 仪表盘推荐
- Loki Dashboard:ID 14055(官方发布),全面展示 Loki 各组件状态。
- Loki Metrics:ID 13639,聚焦写入、查询、存储性能。
- Promtail Dashboard:ID 10880,监控采集代理健康。
导入后选择数据源,用 component 变量过滤。
7. 基于 Loki 日志的告警规则
从 Loki 2.0 开始,内置了 Ruler 组件,可以像 Prometheus 一样定义基于日志流量的告警规则,并由 Alertmanager 发送通知。
7.1 启用 Loki Ruler
在 loki-config.yaml 中添加:
ruler:
storage:
type: local
local:
directory: /loki/rules
rule_path: /loki/rules/fake
alertmanager_url: http://alertmanager:9093
ring:
kvstore:
store: inmemory
7.2 定义日志告警规则
在 /loki/rules/fake/rules.yml 中编写:
groups:
– name: loki–log–alerts
rules:
– alert: HighErrorLogRate
expr: sum(rate({job="nginx"} |~ "500|error" [5m])) > 0.5
for: 5m
labels:
severity: critical
annotations:
summary: "Nginx 错误日志速率过高"
description: "过去 5 分钟平均每秒 {{ $value }} 条错误日志"
– alert: NoLogsFromInstance
expr: absent_over_time({job="myapp"}[10m])
for: 10m
labels:
severity: critical
annotations:
summary: "实例 {{ $labels.instance }} 已 10 分钟无日志,可能已宕机"
这些规则使用 LogQL(类似 PromQL 但针对日志),可以对特定标签的日志速率、模式进行告警。Alertmanager 收到的告警同样包含标签,可与 Prometheus 告警统一路由。
8. 进阶:多租户、长期存储与性能调优
8.1 多租户隔离
Loki 支持通过 X-Scope-OrgID 头实现多租户。在配置中启用 auth_enabled: true,并在 Promtail 的 client 部分添加 tenant_id 字段即可。不同租户的日志和指标完全隔离。
8.2 长期存储
将 storage_config 中的 object_store 改为 s3, gcs, azure 等云对象存储,配合 boltdb_shipper,实现日志无限留存且低成本。
8.3 控制标签基数
Loki 的标签数量不能过高,否则索引膨胀。避免将高基数字段(如 user_id, request_id)作为标签,而是使用日志过滤(LogQL 的 |~ 正则)进行全文搜索。保留核心标签(job, instance, app)即可。
8.4 与 Tempo 追踪集成
Loki 可与 Grafana Tempo 集成,通过 Trace ID 直接从日志跳转到 trace,实现 指标 → 日志 → 追踪 的完整链路。
9. 总结
Loki 的设计哲学——像 Prometheus 一样处理日志——让日志和指标之间的鸿沟消失。通过共享标签,Grafana 中一条点击就能从 CPU 尖刺的监控图跳转到相关时间段的应用日志,运维效率成倍提升。而 Loki 自身的监控与基于日志的告警,又保证了日志管道本身的健康。部署这套方案,你的可观测性将不再分裂为“指标看板”和“日志搜索”两个孤岛,而是成为一个标签统一、联动流畅的全景视图,真正实现“1+1 > 2”的融合力量。
网硕互联帮助中心





评论前必须登录!
注册