4. Promtail 配置基础:日志采集、标签定义、静态与动态发现

Promtail 是 Loki 生态中的日志采集代理,负责从各类目标(文件、系统日志、容器 stdout)抓取日志流,附加标签后推送至 Loki。本章聚焦 Promtail 的核心配置模型:采集源定义、标签体系设计以及静态与动态发现机制,为后续 CI/CD 流水线 SLI 口径的日志接入打下基础。

4.1 Promtail 配置结构总览

Promtail 使用 YAML 配置文件,核心包含四个顶级段:

配置段 作用 必填
server Promtail 自身 HTTP/gRPC 监听端口,用于健康检查和日志推送 推荐
clients Loki 写入端点地址、认证、租户 ID 是
positions 记录已采集日志文件的偏移量,保证重启后不重复、不丢失 推荐
scrape_configs 采集任务列表:定义日志源、标签、发现方式、管道处理 是

其中 scrape_configs 是配置核心,每个采集任务包含 job_name、static_configs 或 kubernetes_sd_configs 等发现方式,以及 pipeline_stages 用于解析和转换日志行。

关键原则:Promtail 的标签设计直接影响 Loki 的索引效率与查询性能。高基数标签(如 request_id、user_ip)应避免直接作为索引标签,优先通过 pipeline 提取为日志行内的结构化字段。

4.2 日志采集源配置

Promtail 支持多种日志源,最常用的是文件采集和系统日志采集。文件采集通过 __path__ 通配符匹配日志文件路径。

4.2.1 文件采集基础示例

scrape_configs:
  - job_name: 'ci-pipeline-logs'
    static_configs:
      - targets: ['localhost']
        labels:
          job: 'ci-pipeline'
          __path__: '/var/log/ci/*.log'
    pipeline_stages:
      - regex:
          expression: '^(?P<level>\w+)\s+(?P<timestamp>\S+)\s+(?P<message>.*)$'
      - labels:
          level:
      - timestamp:
          source: timestamp
          format: RFC3339

配置要点:

  • __path__:支持 glob 模式,如 /var/log/**/*.log 递归匹配子目录。
  • pipeline_stages:通过 regex 提取字段,labels 将提取值附加为标签,timestamp 覆盖默认采集时间。
  • positions:默认写入 /var/log/positions.yaml,确保日志断点续采。

4.2.2 常见采集源对比

采集源类型 配置方式 适用场景 注意事项
文件(file) __path__ + static_configs 传统应用日志、CI 构建日志 需确保 Promtail 有文件读权限
Journald journal 配置段 系统服务日志、systemd 单元 需 journalctl 权限
Windows Event Log windows_events 配置段 Windows 服务器事件 仅 Windows 版本支持
gRPC 接收 server 段启用 gRPC 应用直接推送日志 需应用侧集成 gRPC 客户端

4.3 标签定义策略

标签是 Loki 的索引键,直接影响查询性能和存储成本。Promtail 在采集阶段通过 labels 映射为日志流附加元数据。

4.3.1 标签分类

  • 固定标签:在 static_configs 中直接定义,如 job: 'ci-pipeline'、env: 'production'。
  • 动态标签:通过 pipeline_stages 的 regex 或 json 解析器从日志行提取,如 level、service。
  • 自动发现标签:由服务发现机制注入,如 Kubernetes 的 __meta_kubernetes_pod_label_app。

4.3.2 标签设计最佳实践

原则 说明 示例
低基数优先 标签值组合数应小于 1000 level(info/warn/error)优于 user_id
区分索引与元数据 高基数字段放入日志行,不设标签 request_id 用 json 解析保留在行内
统一命名规范 全小写、下划线分隔 ci_stage、build_id
避免动态标签爆炸 限制动态标签数量,不超过 5 个 仅保留 level、service、env
实战提示:在 CI/CD 流水线场景中,推荐将 pipeline_name、stage_name、build_number 作为固定标签,将 status、duration_ms 作为动态标签,便于 SLI 聚合查询。

4.4 静态发现 vs 动态发现

Promtail 支持两种目标发现模式:静态发现适用于路径固定的日志文件;动态发现适用于容器化、自动扩缩容环境。

4.4.1 静态发现(static_configs)

静态发现直接指定日志文件路径和标签,配置简单、性能高,适合已知路径的 CI 构建日志、传统应用日志。

scrape_configs:
  - job_name: 'static-ci-logs'
    static_configs:
      - targets: ['localhost']
        labels:
          job: 'ci-pipeline'
          env: 'staging'
          __path__: '/data/ci/logs/*.log'

优点:无额外发现开销,配置可预测。缺点:文件路径变化时需要手动更新配置。

4.4.2 动态发现(Kubernetes SD)

Kubernetes 服务发现自动监听 Pod 变化,为每个容器日志流注入丰富的元数据标签。

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
      - source_labels: [__meta_kubernetes_pod_container_name]
        target_label: container
    pipeline_stages:
      - docker: {}

动态发现通过 relabel_configs 将 Kubernetes 元数据映射为 Loki 标签,实现自动标签注入。

4.4.3 静态 vs 动态对比

维度 静态发现 动态发现(Kubernetes SD)
配置复杂度 低,直接写路径 中,需配置 relabel 规则
标签丰富度 手动定义,固定 自动注入 Pod/Namespace/Container 元数据
适用环境 虚拟机、物理机、固定路径 Kubernetes、自动扩缩容
性能开销 低 中(需监听 API Server)
变更响应 需重启 Promtail 自动感知新 Pod

4.5 标签与发现流程架构

下图展示了 Promtail 从日志源到 Loki 的完整数据流,重点突出标签定义与发现机制的关系:

Promtail 日志采集与标签发现流程 日志源 文件 / Journald / 容器 静态发现 static_configs 动态发现 kubernetes_sd_configs 标签定义 固定标签:job, env 动态标签:level, service 发现标签:namespace, pod relabel_configs 映射 Pipeline 处理 regex / json 解析 timestamp 提取 标签注入 日志行转换 Loki 日志存储与查询 标签设计影响查询性能 避免高基数标签

4.6 实战:CI 流水线日志采集配置

以下是一个完整的 Promtail 配置,用于采集 CI/CD 流水线构建日志,结合静态发现与动态标签:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /var/log/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push
    tenant_id: ci

scrape_configs:
  - job_name: 'ci-build-logs'
    static_configs:
      - targets: ['localhost']
        labels:
          job: 'ci-pipeline'
          pipeline_name: 'backend-build'
          __path__: '/var/log/ci/builds/*.log'
    pipeline_stages:
      - regex:
          expression: '^(?P<level>\w+)\s+(?P<timestamp>\S+)\s+\[(?P<stage>\w+)\]\s+(?P<message>.*)$'
      - labels:
          level:
          stage:
      - timestamp:
          source: timestamp
          format: RFC3339
      - output:
          source: message
常见陷阱:
  • 标签基数失控:将 build_id 或 commit_sha 设为标签会导致 Loki 索引膨胀,应改为日志行内字段。
  • 路径通配符过宽:__path__: '/var/log/**/*' 可能采集无关文件,增加存储和网络开销。
  • 忽略 positions 文件:不配置 positions 会导致重启后重复采集或丢失日志。

4.7 本章小结

Promtail 的配置核心在于采集源定义、标签策略和发现机制的选择。静态发现适合路径固定的 CI 日志,动态发现适合 Kubernetes 环境。标签设计应遵循低基数原则,将高基数字段保留在日志行内。通过 pipeline_stages 的解析和标签注入,Promtail 能够为后续 SLI 口径计算提供结构化的日志数据。