Loki 日志聚合:轻量级、Promtail 与 Grafana 集成

FreeGuideOnline 最新 2026-06-13

什么是 Loki?

Loki 是一款受 Prometheus 启发的轻量级日志聚合系统,由 Grafana Labs 开源。与全文索引的日志方案不同,Loki 只为每个日志流(如应用标签)建立少量索引,其余元数据以键值对形式存储,极大降低了资源消耗,因此它被称为“云原生的、类似 Prometheus 的日志系统”。它通常与 Promtail(日志采集代理)、Grafana(可视化)一起使用,形成日志领域的 PLG 技术栈。

为什么选择 Loki?

  • 资源高效:不索引日志全文,只索引标签,内存和磁盘使用都显著低于 Elasticsearch 等方案。
  • 无缝集成:与 Prometheus、Grafana 天然配合,标签体系一致,可在同一仪表板中关联指标与日志。
  • 水平扩展:支持多租户、动态分片,可轻松应对每日 TB 级日志量。
  • 成本可控:尤其适合将日志存储在对象存储(如 S3、GCS)中,适合长期保留。
  • 使用 LogQL:查询语言类似 PromQL,学习曲线平缓。

核心组件

Loki

负责存储日志数据并处理查询。它有两种运行模式:

  • 单机模式(all-in-one):适合开发和小规模环境。
  • 微服务模式:将写入、读取、查询器等拆分为独立服务,便于水平扩展。

Promtail

运行在每个节点上的日志采集代理,专门为 Loki 设计。它会定期读取指定的日志文件(如 /var/log/*.log),自动发现新行,为日志附加标签(如 job, environment, host),并通过 HTTP 推送到 Loki。

Grafana

可视化平台。在 Grafana 中通过 Explore 视图直接查询并展示 Loki 中的日志,支持与指标面板联动。

快速部署 PLG 栈(Docker Compose 方式)

以下步骤将在单机上启动 Loki、Promtail 和 Grafana,适合快速体验。

1. 准备环境

确保已安装 Docker 和 Docker Compose。创建一个项目目录,如 plg-stack

mkdir plg-stack && cd plg-stack

2. 编写 Compose 文件

创建 docker-compose.yml

version: "3"

networks:
  loki:

services:
  loki:
    image: grafana/loki:3.0.0
    container_name: loki
    command: -config.file=/etc/loki/local-config.yaml
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml
      - loki_data:/loki
    ports:
      - "3100:3100"
    networks:
      - loki

  promtail:
    image: grafana/promtail:3.0.0
    container_name: promtail
    volumes:
      - /var/log:/var/log               # 采集宿主机系统日志
      - ./promtail-config.yaml:/etc/promtail/config.yml
    command: -config.file=/etc/promtail/config.yml
    depends_on:
      - loki
    networks:
      - loki

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    depends_on:
      - loki
    networks:
      - loki

volumes:
  loki_data:

3. 编写 Loki 配置

创建 loki-config.yaml(与 docker-compose.yml 中的挂载路径对应):

auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 5m
  chunk_retain_period: 30s

schema_config:
  configs:
    - from: 2023-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

storage_config:
  tsdb_shipper:
    active_index_directory: /loki/tsdb-index
    cache_location: /loki/tsdb-cache
  filesystem:
    directory: /loki/chunks

compactor:
  working_directory: /loki/compactor
  retention_enabled: true
  retention_delete_delay: 2h
  delete_request_store: filesystem

limits_config:
  retention_period: 744h          # 保留 31 天日志
  allow_structured_metadata: false

4. 编写 Promtail 配置

创建 promtail-config.yaml

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml   # 记录文件读取位置

clients:
  - url: http://loki:3100/loki/api/v1/push  # Loki 推送地址

scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          host: ${HOSTNAME}
          __path__: /var/log/*.log          # 采集所有 .log 文件

5. 启动服务

docker compose up -d

确认三个容器都在运行:

docker compose ps

集成 Grafana 与 Loki

  1. 浏览器访问 http://localhost:3000(匿名登录已启用)。
  2. 左侧菜单点击 Connections > Data sources
  3. 点击 Add data source,搜索并选择 Loki
  4. 在 URL 栏填入 http://loki:3100(因为 Grafana 与 Loki 在同一 Docker 网络)。
  5. 点击 Save & Test,应当看到绿色提示 “Data source connected and labels found.”。
  6. 现在进入 Explore 视图(左侧指南针图标),数据源选择刚刚添加的 Loki,即可查询日志。

使用 LogQL 查询日志

Loki 的查询语言称为 LogQL,分为两个阶段:

  • 流选择器:通过标签过滤日志流。
  • 过滤表达式:对选中的流进行进一步筛选或转换。

基本查询示例

  1. 查看所有 varlogs 作业的日志

    {job="varlogs"}
    

    这将返回宿主机 /var/log/*.log 的所有行。

  2. 关键词搜索

    {job="varlogs"} |= "error"
    

    |= 表示包含(大小写敏感),类似 grep。还可以用 !=|~(正则匹配) 等。

  3. 结合标签与过滤

    {host="my-server"} |~ "(?i)exception|fail"
    

    (?i) 开启不区分大小写。

  4. 统计日志量

    rate({job="varlogs"}[5m])
    

    计算 5 分钟内每秒日志条数,类似 PromQL 的 rate 函数。

  5. 聚合与分析

    topk(5, sum by (host) (count_over_time({job="varlogs"}[1h])))
    

    显示过去 1 小时内日志量前 5 的主机。

从指标跳转日志

如果已经配置了 Prometheus 数据源,在 Grafana 面板上点击一个时间点的指标,选择 “View logs” 即可跳转到对应时刻的 Loki 日志,条件是标签体系一致(如 job 名称相同)。

实际生产建议

  • 持久化存储:将 Loki 的 chunks 和索引改为对象存储(S3/GCS/Azure Blob),配置文件需调整 storage_config
  • 标签规划:避免高基数标签(如 user_id),尽量使用有限的枚举值,否则会拖慢性能。
  • 结构化日志:若日志为 JSON,可在 Promtail 阶段使用 - json 解析,使字段可过滤。
  • 安全加固:生产环境务必启用认证(如 basic_auth、OAuth2)和 TLS。

总结

通过 Loki + Promtail + Grafana 的组合,你可以快速搭建起一套轻量、易用的日志聚合与分析平台。本教程从核心概念到动手实践,覆盖了最小部署、配置采集、可视化集成以及 LogQL 基础查询。下一步建议深入探索 LogQL 的解析器、聚合函数,并将日志系统与指标、告警打通,构建完整的可观测性回路。