菜单
开源

配置 Promtail 进行服务发现

注意

Promtail 已被弃用,并将在 2026 年 2 月 28 日前进入长期支持 (LTS) 阶段。Promtail 将于 2026 年 3 月 2 日终止生命周期 (EOL)。您可以在此处找到迁移资源。

Promtail 当前支持从以下来源抓取日志:

Azure Event Hubs

Promtail 支持从 Azure Event Hubs 读取消息。目标可以使用 azure_event_hubs 节进行配置

yaml
- job_name: azure_event_hubs
  azure_event_hubs:
    group_id: "mygroup"
    fully_qualified_namespace: my-namespace.servicebus.windows.net:9093
    connection_string: "my-connection-string"
    event_hubs:
      - event-hub-name
    labels:
      job: azure_event_hub
  relabel_configs:
    - action: replace
      source_labels:
        - __azure_event_hubs_category
      target_label: category

只有 fully_qualified_namespaceconnection_stringevent_hubs 是必填字段。阅读配置部分了解更多信息。

Cloudflare

Promtail 支持使用 Logpull API 从 Cloudflare 拉取 HTTP 日志消息。Cloudflare 目标可以使用 cloudflare 块进行配置

yaml
scrape_configs:
- job_name: cloudflare
  cloudflare:
    api_token: REDACTED
    zone_id: REDACTED
    fields_type: all
    labels:
      job: cloudflare-foo.com

只需要 api_tokenzone_id。请参考 Cloudflare 配置部分了解详情。

文件目标发现

Promtail 通过 config YAML 文件中的 scrape_configs 节发现日志文件位置并从中提取标签。其语法与 Prometheus 使用的语法完全相同。

scrape_configs 包含一个或多个条目,这些条目会针对每个发现的目标(即,实例中运行的每个新 Pod 中的每个容器)执行

scrape_configs:
  - job_name: local
    static_configs:
      - ...

  - job_name: kubernetes
    kubernetes_sd_config:
      - ...

如果多个抓取配置部分匹配您的日志,您将获得重复的条目,因为日志可能以略有不同的标签发送到不同的流中。

Promtail 中存在不同类型的标签

  • __(两个下划线)开头的标签是内部标签。它们通常来自服务发现等动态源。重新标记完成后,它们将从标签集中移除。要保留内部标签以便将其发送到 Grafana Loki,请重命名它们,使其不以 __ 开头。有关详细信息,请参阅重新标记

  • __meta_kubernetes_pod_label_* 开头的标签是“元标签”,它们是根据您的 Kubernetes Pod 的标签生成的。

    例如,如果您的 Kubernetes Pod 有一个名为 name 的标签,其值设置为 foobar,那么 scrape_configs 节将收到一个内部标签 __meta_kubernetes_pod_label_name,其值设置为 foobar

  • 其他以 __meta_kubernetes_* 开头的标签是基于其他 Kubernetes 元数据存在的,例如 Pod 的命名空间 (__meta_kubernetes_namespace) 或 Pod 内容器的名称 (__meta_kubernetes_pod_container_name)。请参考 Prometheus 文档获取完整的 Kubernetes 元标签列表。

  • __path__ 标签是一个特殊标签,Promtail 在发现后使用它来确定要读取的文件位置。允许使用通配符,例如 /var/log/*.log 用于获取指定目录中所有扩展名为 log 的文件,/var/log/**/*.log 用于递归匹配文件和目录。有关完整选项列表,请查阅 Promtail 使用的文档。

  • __path_exclude__ 标签是 Promtail 在发现后使用的另一个特殊标签,用于从当前 scrape_config 块读取的文件中排除使用 __path__ 发现的子集文件。它使用相同的来支持通配符和 glob 模式。

  • __path__ 中发现的每个文件添加了 filename 标签,以确保流的唯一性。它设置为读取该行的文件的绝对路径。

文件发现示例

要在机器上手动抓取一组定义的日志文件,可以使用 static_configsfile_sd_configs。使用 static_configs 需要重新加载 Promtail 以应用修改。使用 file_sd_configs 则无需重新加载。Promtail 会在发现文件更新时重新加载它们。

下面是 Promtail 配置的摘录,展示了用于抓取 aptdpkg 日志的 file_sd_configs

yaml
scrape_configs:
 - job_name: apt-dpkg
    file_sd_configs:
      - files:
        - /etc/promtail/dpkg-apt.yaml
    refresh_interval: 5m

Promtail 要抓取的目标定义在 /etc/promtail/dpkg-apt.yaml 中。实际上,Promtail 会读取 files 下提供的文件列表中的抓取目标。

以下是 /etc/promtail/dpkg-apt.yaml 的内容。

yaml
- targets: ["localhost"]
  labels:
    job: dpkg
    __path__: /var/log/dpkg.log
- targets: ["localhost"]
  labels:
    job: apt
    __path__: /var/log/apt/*.log

正如您所见,/etc/promtail/dpkg-apt.yaml 包含了我们本可以在static_configs 下定义的目标列表。
它定义了两个目标。第一个目标的 job 标签设置为 dpkg__path__ 指定了 dpkg 的日志文件:/var/log/dpkg.log。第二个目标有两个标签:job 标签和再次出现的 __path__,指定了 APT 日志文件的路径。此 __path__ 包含一个 glob 模式。每个匹配该正则表达式的日志文件都将在此目标下进行抓取。
总而言之,上面的 /etc/promtail/dpkg-apt.yaml 展示了 file_sd_config 发现文件的 YAML 格式。其 JSON 格式可以在此处查看,

Kubernetes 发现

虽然 Promtail 可以使用 Kubernetes API 来发现 Pod 作为目标,但它只能读取运行在与 Promtail 相同节点上的 Pod 的日志文件。Promtail 会在每个目标上查找 __host__ 标签,并验证其是否设置为与 Promtail 相同的主机名(使用 `$HOSTNAME` 或内核报告的主机名,如果环境变量未设置)。

这意味着无论何时使用 Kubernetes 服务发现,都必须有一个 relabel_config,它从 __meta_kubernetes_pod_node_name 创建中间标签 __host__

yaml
relabel_configs:
  - source_labels: ['__meta_kubernetes_pod_node_name']
    target_label: '__host__'

有关详细信息,请参阅重新标记。有关如何配置服务发现的更多信息,请参阅Kubernetes 服务发现配置

GCP 日志抓取

Promtail 支持从 GCP 抓取云资源日志,例如 GCS 存储桶日志、负载均衡器日志和 Kubernetes 集群日志。配置在 scrape_config 中的 gcplog 节中指定。

有两种抓取策略:pull(拉取)和 push(推送)。

拉取

yaml
  - job_name: gcplog
    gcplog:
      subscription_type: "pull" # If the `subscription_type` field is empty, defaults to `pull`
      project_id: "my-gcp-project"
      subscription: "my-pubsub-subscription"
      use_incoming_timestamp: false # default rewrite timestamps.
      use_full_line: false # default use textPayload as log line.
      labels:
        job: "gcplog"
    relabel_configs:
      - source_labels: ['__gcp_resource_type']
        target_label: 'resource_type'
      - source_labels: ['__gcp_resource_labels_project_id']
        target_label: 'project'

这里 project_idsubscription 是唯二必填字段。

  • project_id 是 GCP 项目 ID。
  • subscription 是 Promtail 可以从中消费日志条目的 GCP Pub/Sub 订阅。

在使用 gcplog 目标之前,应配置 GCP 以使用 Pub/Sub 订阅接收日志。配置

它也支持重新标记和 pipeline 阶段,就像其他目标一样。

当 Promtail 接收 GCP 日志时,各种内部标签可用于重新标记

  • __gcp_logname
  • __gcp_severity
  • __gcp_resource_type
  • __gcp_resource_labels_<NAME>
  • __gcp_labels_<NAME> 在上面的示例中,通过 relabel_configs 将 GCP 资源的 project_id 标签转换为名为 project 的标签。

推送

yaml
  - job_name: gcplog
    gcplog:
      subscription_type: "push"
      use_incoming_timestamp: false
      labels:
        job: "gcplog-push"
      server:
        http_listen_address: 0.0.0.0
        http_listen_port: 8080
    relabel_configs:
      - source_labels: ['__gcp_message_id']
        target_label: 'message_id'
      - source_labels: ['__gcp_attributes_logging_googleapis_com_timestamp']
        target_label: 'incoming_ts'

配置 GCP Log 推送目标时,Promtail 将启动一个 HTTP 服务器,监听端口 8080,如 server 节中配置。此服务器暴露 `/gcp/api/v1/push` 单个端点,负责接收来自 GCP 的日志。

为了让 Google Pub/Sub 能够发送日志,Promtail 服务器必须可公开访问,并支持 HTTPS。为此,Promtail 可以作为 Kubernetes 等大型编排服务的一部分部署,通过入口处理 HTTPS 流量,或者可以托管在代理/网关后,将 HTTPS 卸载到该组件并将请求路由到 Promtail。解决此问题后,即可配置 GCP 向 Promtail 发送日志。

它也支持重新标记和 pipeline 阶段。

当 Promtail 接收 GCP 日志时,各种内部标签可用于重新标记

  • __gcp_message_id
  • __gcp_subscription_name
  • __gcp_attributes_<NAME>
  • __gcp_logname
  • __gcp_severity
  • __gcp_resource_type
  • __gcp_resource_labels_<NAME>
  • __gcp_labels_<NAME>

在上面的示例中,通过 relabel_configs__gcp_message_id__gcp_attributes_logging_googleapis_com_timestamp 标签转换为 message_idincoming_ts。所有其他内部标签,例如某些其他属性,如果在转换中未指定,将被目标丢弃。

GELF

Promtail 支持使用 GELF UDP 协议监听消息。GELF 目标可以使用 gelf 节进行配置

yaml
scrape_configs:
- job_name: gelf
  gelf:
    listen_address: "0.0.0.0:12201"
    use_incoming_timestamp: true
    labels:
      job: gelf
  relabel_configs:
      - action: replace
        source_labels:
          - __gelf_message_host
        target_label: host
      - action: replace
        source_labels:
          - __gelf_message_level
        target_label: level
      - action: replace
        source_labels:
          - __gelf_message_facility
        target_label: facility

Heroku Drain

Promtail 支持使用 Heroku HTTPS Drain 接收来自 Heroku 应用程序的日志。配置在 Promtail scrape_config 配置中的 heroku_drain 块中指定。

yaml
- job_name: heroku_drain
    heroku_drain:
      server:
        http_listen_address: 0.0.0.0
        http_listen_port: 8080
      labels:
        job: heroku_drain_docs
      use_incoming_timestamp: true
    relabel_configs:
      - source_labels: ['__heroku_drain_host']
        target_label: 'host'
      - source_labels: ['__heroku_drain_app']
        target_label: 'source'
      - source_labels: ['__heroku_drain_proc']
        target_label: 'proc'
      - source_labels: ['__heroku_drain_log_id']
        target_label: 'log_id'

在 Heroku Drain 目标的 scrape_configs 配置中,job_name 必须是 Prometheus 兼容的指标名称

server 节配置用于接收日志的 HTTP 服务器。labels 定义了添加到每个接收到的日志条目的静态标签值集。use_incoming_timestamp 可用于传递从 Heroku 收到的时间戳。

在使用 heroku_drain 目标之前,应配置 Heroku 以使用 Promtail 实例将监听的 URL。遵循 Heroku HTTPS Drain 文档中的步骤,使用如下命令进行配置

heroku drains:add [http|https]://HOSTNAME:8080/heroku/api/v1/drain -a HEROKU_APP_NAME

获取 Heroku 应用程序名称

请注意,__heroku_drain_app 标签将包含日志行的源,可以是 appheroku,而不是 Heroku 应用程序的名称。

提供实际应用程序名称的最简单方法是在创建 Heroku Drain 时包含一个查询参数,然后在抓取配置中重新标记该参数,例如

heroku drains:add [http|https]://HOSTNAME:8080/heroku/api/v1/drain?app_name=HEROKU_APP_NAME -a HEROKU_APP_NAME

然后在 relabel_config

yaml
    relabel_configs:
      - source_labels: ['__heroku_drain_param_app_name']
        target_label: 'app'

它也支持重新标记和 pipeline 阶段,就像其他目标一样。

当 Promtail 接收 Heroku Drain 日志时,各种内部标签可用于重新标记

  • __heroku_drain_host
  • __heroku_drain_app
  • __heroku_drain_proc
  • __heroku_drain_log_id 在上面的示例中,通过 relabel_configs 将 GCP 资源的 project_id 标签转换为名为 project 的标签。

HTTP 客户端

Promtail 对 Loki 的所有调用都使用 Prometheus HTTP 客户端实现。因此,可以使用 clients 节进行配置,在该节中可以建立一个或多个与 Loki 的连接

yaml
clients:
  - [ <client_option> ]

请参考 Promtail 配置参考中的 client_config,获取所有可用选项。

Journal 抓取(仅限 Linux)

在带有 systemd 的系统上,Promtail 也支持从 Journal 读取。与在 static_configs 节中定义的文件抓取不同,Journal 抓取在 journal 节中定义

yaml
scrape_configs:
  - job_name: journal
    journal:
      json: false
      max_age: 12h
      path: /var/log/journal
      matches: _TRANSPORT=kernel
      labels:
        job: systemd-journal
    relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: 'unit'

journal 节中定义的所有字段都是可选的,仅在此处提供供参考。max_age 字段确保不会将早于指定时间的条目发送到 Loki;这可以规避“条目太旧”的错误。path 字段告诉 Promtail 从哪里读取 Journal 条目。labels 映射定义了一个常量标签列表,添加到 Promtail 读取的每个 Journal 条目中。matches 字段添加 Journal 过滤器。如果指定了匹配不同字段的多个过滤器,则日志条目将同时被这两个过滤器过滤;如果两个过滤器应用于同一字段,则它们会自动匹配为备选项。

json 字段设置为 true 时,来自 Journal 的消息将作为 JSON 通过 pipeline 传递,保留 Journal 条目中的所有原始字段。当您不想索引某些字段但仍想知道它们包含的值时,这非常有用。

默认情况下,Promtail 通过查找 `/var/log/journal` 和 `/run/log/journal` 路径从 Journal 读取。如果在 Docker 容器内运行 Promtail,应将适用于您的分发版的路径以及 `/etc/machine-id` 绑定挂载到 Promtail 内部。将 `/etc/machine-id` 绑定挂载到同名路径对于 Journal 读取器了解要读取哪个特定的 Journal 至关重要。例如

bash
docker run \
  -v /var/log/journal/:/var/log/journal/ \
  -v /run/log/journal/:/run/log/journal/ \
  -v /etc/machine-id:/etc/machine-id \
  grafana/promtail:latest \
  -config.file=/path/to/config/file.yaml

当 Promtail 从 Journal 读取时,它会将被 __journal_ 前缀的所有字段作为内部标签引入。就像上面的示例中一样,通过 relabel_configs 将 Journal 中的 _SYSTEMD_UNIT 字段转换为名为 unit 的标签。有关更多信息,请参阅重新标记,还可以查看 systemd man 手册页,了解 Journal 暴露的字段列表。

这里是一个示例,其中 SYSTEMD_UNITHOSTNAMESYSLOG_IDENTIFIER 被重新标记以在 Loki 中使用。

请记住,以 __ 为前缀的标签将被丢弃,因此需要重新标记以保留这些标签。

yaml
- job_name: systemd-journal
  journal:
    labels:
      cluster: ops-tools1
      job: default/systemd-journal
    path: /var/log/journal
  relabel_configs:
  - source_labels:
    - __journal__systemd_unit
    target_label: systemd_unit
  - source_labels:
    - __journal__hostname
    target_label: nodename
  - source_labels:
    - __journal_syslog_identifier
    target_label: syslog_identifier

Kafka

Promtail 支持使用消费者组从 Kafka 读取消息。Kafka 目标可以使用 kafka 节进行配置

yaml
scrape_configs:
- job_name: kafka
  kafka:
    brokers:
    - my-kafka-0.org:50705
    - my-kafka-1.org:50705
    topics:
    - ^promtail.*
    - some_fixed_topic
    labels:
      job: kafka
  relabel_configs:
      - action: replace
        source_labels:
          - __meta_kafka_topic
        target_label: topic
      - action: replace
        source_labels:
          - __meta_kafka_partition
        target_label: partition
      - action: replace
        source_labels:
          - __meta_kafka_group_id
        target_label: group
      - action: replace
        source_labels:
          - __meta_kafka_message_key
        target_label: message_key

只有 brokerstopics 是必需的。阅读配置部分了解更多信息。

重新标记

每个 scrape_configs 条目都可以包含一个 relabel_configs 节。relabel_configs 是一个操作列表,用于将发现的标签转换为另一种形式。

relabel_configs 中的单个条目也可以通过执行 action: drop 来拒绝目标,如果标签值匹配指定的正则表达式。当目标被丢弃时,拥有该目标的 scrape_config 将不会处理来自该特定源的日志。其他没有丢弃操作的 scrape_configs 如果从同一目标读取,可能仍然会使用并转发日志到 Loki。

relabel_configs 的一个常见用例是将内部标签(如 __meta_kubernetes_*)转换为中间内部标签(如 __service__)。然后可以根据值丢弃中间内部标签,或将其转换为最终的外部标签,例如 __job__

示例

  • 如果标签(示例中为 __service__)为空,则丢弃目标
yaml
  - action: drop
    regex: ''
    source_labels:
    - __service__
  • 如果任何 source_labels 包含值,则丢弃目标
yaml
  - action: drop
    regex: .+
    separator: ''
    source_labels:
    - __meta_kubernetes_pod_label_name
    - __meta_kubernetes_pod_label_app
  • 通过重命名内部标签来保留它,以便将其发送到 Loki
yaml
  - action: replace
    source_labels:
    - __meta_kubernetes_namespace
    target_label: namespace
  • 通过映射来保留所有 Kubernetes Pod 标签,例如将 __meta_kube__meta_kubernetes_pod_label_foo 映射到 foo
yaml
  - action: labelmap
    regex: __meta_kubernetes_pod_label_(.+)

延伸阅读

Syslog 接收器

Promtail 支持从 TCP 或 UDP 流接收 IETF Syslog (RFC5424) 消息。接收 Syslog 消息在 syslog 节中定义

yaml
scrape_configs:
  - job_name: syslog
    syslog:
      listen_address: 0.0.0.0:1514
      listen_protocol: tcp
      idle_timeout: 60s
      label_structured_data: yes
      labels:
        job: "syslog"
    relabel_configs:
      - source_labels: ['__syslog_message_hostname']
        target_label: 'host'

Syslog 节中唯一的必填字段是 listen_address 字段,必须提供一个有效的网络地址。接收消息的默认协议是 TCP。要更改协议,可以将 listen_protocol 字段更改为 udp。请注意,UDP 不支持 TLS。idle_timeout 有助于清理陈旧的 Syslog 连接。如果设置了 label_structured_data,Syslog 标头中的结构化数据将转换为形如 __syslog_message_sd__ 的内部标签。labels 映射定义了一个常量标签列表,添加到 Promtail 读取的每个 Journal 条目中。

请注意,建议在 Promtail 前部署专用的 Syslog 转发器,如 syslog-ngrsyslog。转发器可以处理现有的各种规范和传输(UDP、BSD syslog 等)。请参阅 syslog-ngrsyslog 的推荐输出配置。

当 Promtail 接收到 Syslog 消息时,它会将从接收到的消息中解析出的所有标头字段,以 __syslog_ 为前缀作为内部标签引入。就像上面的示例中一样,通过 relabel_configs 将 Journal 中的 __syslog_message_hostname 字段转换为名为 host 的标签。有关更多信息,请参阅重新标记

Syslog-NG 输出配置

destination d_loki {
  syslog("localhost" transport("tcp") port(<promtail_port>));
};

Rsyslog 输出配置

通过 TCP 发送消息

*.* action(type="omfwd" protocol="tcp" target="<promtail_host>" port="<promtail_port>" Template="RSYSLOG_SyslogProtocol23Format" TCP_Framing="octet-counted" KeepAlive="on")

通过 UDP 发送消息

*.* action(type="omfwd" protocol="udp" target="<promtail_host>" port="<promtail_port>" Template="RSYSLOG_SyslogProtocol23Format")

Windows 事件日志

在 Windows 上,Promtail 支持从事件日志读取。Windows 事件目标可以使用 windows_events 节进行配置

yaml
scrape_configs:
- job_name: windows
  windows_events:
    use_incoming_timestamp: false
    bookmark_path: "./bookmark.xml"
    eventlog_name: "Application"
    xpath_query: '*'
    labels:
      job: windows
  relabel_configs:
    - source_labels: ['computer']
      target_label: 'host'

当 Promtail 接收到事件时,它将附加 channelcomputer 标签,并将事件序列化为 JSON。如果需要,您可以通过重新标记来重新标记默认标签。

提供书签路径是强制性的,它将用于保留处理的最后一个事件,并允许在不跳过日志的情况下恢复目标。

阅读配置部分了解更多信息。

请参阅eventlogmessage 阶段,了解如何从消息中提取数据。