Grafana Loki是水平可扩展的日志聚合系统,在网站运维和DevOps实践中,Loki相比ELK技术栈具有更低的存储成本和更简单的部署架构,通过仅索引日志标签而非全文内容实现高效日志检索。本文讲解Loki的架构设计、部署配置与LogQL查询语法。
Loki架构设计与核心组件
Loki采用微服务架构,核心组件包括Distributor、Ingester、Querier、Compactor和Ruler。日志数据通过Promtail采集后发送至Distributor,经哈希分片后写入Ingester,最终持久化到对象存储。
# docker-compose.yaml - Loki单节点部署
version: "3.8"
services:
loki:
image: grafana/loki:3.0.0
ports:
- "3100:3100"
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
command: -config.file=/etc/loki/local-config.yaml
restart: always
promtail:
image: grafana/promtail:3.0.0
volumes:
- /var/log:/var/log
- ./promtail-config.yaml:/etc/promtail/config.yaml
command: -config.file=/etc/promtail/config.yaml
restart: always
grafana:
image: grafana/grafana:10.2.0
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
restart: always
Distributor接收日志流后验证数据格式,计算租户和标签的哈希值,将日志分发到对应的Ingester实例。Ingester将日志压缩为chunk存入内存缓存,达到阈值后刷入对象存储。Querier处理查询请求,优先从Ingester读取实时数据,历史数据从存储后端加载。
Promtail日志采集与标签配置
Promtail是Loki的日志采集Agent,通过配置文件定义日志文件路径、标签提取规则和流水线处理阶段。
# promtail-config.yaml
server:
http_listen_port: 9080
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
# Nginx访问日志采集
- job_name: nginx
static_configs:
- targets:
- localhost
labels:
job: nginx
__path__: /var/log/nginx/*.log
pipeline_stages:
# 正则提取Nginx日志字段
- regex:
expression: '^(?P\d+\.\d+\.\d+\.\d+) - (?P\S+) \[(?P
pipeline_stages定义日志处理流水线,依次执行regex/json解析、标签提取、时间戳解析和输出格式化。labels阶段将字段提升为索引标签,标签基数(cardinality)不宜过高,避免影响查询性能。level、method、status等低基数字段适合作为标签,而trace_id等高基数字段不应设为标签。
Loki存储后端配置与数据保留策略
Loki支持多种存储后端,包括本地文件系统、S3兼容对象存储、GCS等。生产环境推荐使用S3兼容存储(如MinIO),配置数据保留期和压缩策略。
# loki-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /tmp/loki
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
tsdb_shipper:
active_index_directory: /tmp/loki/tsdb-index
cache_location: /tmp/loki/tsdb-cache
filesystem:
directory: /tmp/loki/chunks
limits_config:
# 日志保留期:30天
retention_period: 720h
# 每个租户每秒最大查询请求
max_query_series: 5000
# 拒绝高基数标签
reject_old_samples: true
reject_old_samples_max_age: 168h
compactor:
working_directory: /tmp/loki/compactor
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
retention_delete_worker_count: 150
delete_request_store: filesystem
TSDB存储引擎(schema v13)是Loki 3.x推荐的存储方案,相比旧的BoltDB Store提供更好的查询性能和更低的资源消耗。retention_period控制日志保留时长,Compactor组件定期清理过期数据。
LogQL查询语法与日志分析实战
LogQL是Loki的查询语言,语法类似PromQL,分为日志流选择器和过滤管道两部分。日志流选择器通过标签筛选日志流,过滤管道对日志内容进行解析和过滤。
# 基础日志查询:查找nginx job中所有日志
{job="nginx"}
# 多标签过滤
{job="nginx", status=~"5.."}
# status=~"5.." 匹配所有5xx状态码
# 正则过滤日志内容
{job="nginx"} |= "error"
{job="nginx"} |~ "timeout|refused"
{job="nginx"} != "192.168.1.1"
# JSON日志字段过滤
{job="application", level="ERROR"} | json | line_format "{{.msg}}"
{job="application"} | json | level="ERROR" | msg=~"database.*timeout"
# 日志指标查询:统计每分钟各状态码请求数
sum by (status) (rate({job="nginx"}[1m]))
# 计算错误率
sum(rate({job="nginx", status=~"5.."}[5m])) / sum(rate({job="nginx"}[5m])) * 100
# Top 10 访问路径
topk(10, sum by (path) (count_over_time({job="nginx"} | json | __error__="" [5m])))
# P99延迟(假设日志包含duration字段)
quantile_over_time(0.99, {job="application"} | json | unwrap duration [5m])
LogQL的两类查询:Log Query返回日志行,Metric Query返回数值指标。rate()和count_over_time()将日志流转换为时序数据。unwrap关键字用于提取数值字段进行聚合计算。
告警规则配置与Grafana可视化集成
Loki支持通过Ruler组件配置告警规则,当日志匹配特定条件时触发告警,通过Alertmanager发送通知。
# /tmp/loki/rules/alerting.yaml
groups:
- name: nginx_alerts
rules:
- alert: HighErrorRate
# 5分钟内5xx错误率超过5%
expr: |
sum(rate({job="nginx", status=~"5.."}[5m])) by (instance)
/ sum(rate({job="nginx"}[5m])) by (instance)
> 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Nginx error rate above 5%"
description: "{{ $labels.instance }} error rate is {{ $value | humanizePercentage }}"
- alert: LogVolumeAnomaly
# 日志量突然激增
expr: |
sum by (job) (rate({job="nginx"}[5m]))
> 10 * sum by (job) (rate({job="nginx"}[1h] offset 1h))
for: 5m
labels:
severity: warning
annotations:
summary: "Log volume spike detected for {{ $labels.job }}"
在Grafana中添加Loki数据源(URL设为http://loki:3100),即可在Dashboard中创建日志面板和指标面板。日志面板选择Loki数据源后输入LogQL查询语句,支持语法高亮和自动补全。配合Grafana Alerting功能可实现告警通知到Slack、钉钉、邮件等渠道。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/grafanaloki-ri-zhi-ju-he-xi-tong-da-jian-shi-zhan-ri-zhi/