Loki日志聚合本质是标签驱动的轻量方案,依赖Promtail注入高基数标签、LogQL管道表达式过滤提取、Grafana将带聚合函数的LogQL转为指标图表。

在 Kubernetes 中用 Loki 做日志聚合,本质是“标签驱动”的轻量级方案——它不索引日志内容,而是靠高基数标签(如 namespace、pod、container)快速筛选日志流,再结合 LogQL 查询语言做条件过滤和简单聚合。查指标的关键不在“全文搜索”,而在“按标签切片 + 提取模式 + 统计计数/延迟/分布”。
确保日志已带关键标签并写入 Loki
Loki 不解析日志内容,所以采集端(如 Promtail)必须把结构化元数据作为标签注入。常见缺失点:
- Promtail 的
pipeline_stages要配置docker或kubernetes模块,自动提取namespace、pod_name、container_name - 避免在
static_labels里硬编码环境名,改用labelmap从日志行或文件路径动态提取 - 确认 Promtail 日志目标(
scrape_configs)中__path__匹配容器日志路径(如/var/log/pods/*/*.log),否则日志根本进不来
用 LogQL 写出可统计的日志查询(不是纯 grep)
LogQL 分两部分:左边是日志流选择器(决定查哪些日志流),右边是管道表达式(做内容过滤和指标提取)。例如:
- {job="kubernetes-pods"} |~ "error|Exception" → 返回含关键字的原始日志行(无聚合)
- {job="kubernetes-pods", namespace="prod"} | json | duration > 2000 | __error__ =="" | count_over_time([1h]) → 先解析 JSON,过滤 duration 超 2s 且无 error 字段的日志,再按小时统计条数
-
{container="api-server"} | pattern "
→ 用 pattern 提取字段,再按 ERROR 级别算每秒错误率" | __level__ == "ERROR" | rate([5m])
注意:count_over_time、rate、avg_over_time 这类函数才是生成“指标”的核心,必须配合时间范围(如 [5m])使用。
在 Grafana 中把日志查询转成监控图表
Loki 查询本身不存指标,但 Grafana 支持将 LogQL 查询结果当数据源画图:
- 新建 Panel,数据源选 Loki,Query 类型切到 “Metrics”(不是 Logs)
- 输入带聚合函数的 LogQL(如
sum by (pod) (count_over_time({job="kubernetes-pods"} |~ "timeout" [1h]))),Grafana 自动渲染为折线图/柱状图 - 开启 “Instant” 模式可查当前值;关掉则显示时间序列 —— 这是看趋势的关键
- 利用变量(如
$namespace)让图表支持下拉切换,比硬编码标签更实用
排查查不到指标的三个高频原因
不是语法错,往往是链路断在中间:
-
标签不匹配:用 Grafana Explore 查一条真实日志,展开 “Labels”,确认你查询里的
{namespace="xxx"}和实际标签完全一致(大小写、连字符、有无前缀) - 时间范围过窄:Loki 默认保留日志 7 天,但查询时间范围若设为 “Last 5 minutes”,而错误刚发生,可能还没被 Promtail 采集推送(Promtail 默认 1s 扫描一次,但压缩上传有延迟)
-
LogQL 函数位置错:聚合函数(如
count_over_time)必须放在整条管道末尾,不能写在| json前面,否则报错 “expected expression”










