在 Prometheus 中重新标记

Relabeling in Prometheus

设置

Prometheus 节点导出器已注册为具有各种标签的领事代理服务。提供给领事代理的示例服务定义:

{
  "service":{
      "id": "server-stats",
      "name": "server-stats",
      "tags": [
        "a=1_meow",
        "b=2_woof",
        "c=3_moo",
        "monkey"
      ],
      "port": 9100,
      "checks": [
        {
          "name": "Process #1",
          "script": "/path/to/healthcheck/script.sh",
          "interval": "5s"
        }
      ]
    }
}

Prometheus 设置为查找此 server-stats 服务并使用 Consul 提供的配置(主机地址和端口)从服务器抓取统计信息。以上标签在 __meta_consul_tags 中以逗号分隔的列表形式提供,可用于重新标记。

Prometheus 重新标记配置:

relabel_configs:
- source_labels: [__meta_consul_tags]
  separator:     ','
  #regex:         '(.+)=(.+)'
  regex:         '([a-z_]+)=([a-z_]+|\d+)'
  target_label:  
  replacement:   

问题

我正在尝试向 Prometheus 公开标签,以便我们可以根据标签获取统计信息和图表。牢记上述服务配置,除了 Prometheus 内部所做的任何事情之外,我希望每个指标都有以下标签: a=1_meowb=2_woofc=3_moo 并忽略 monkey,因为它只是一个字符串。如果有需要 = 的解决方案,我可以从我的标签列表中删除 monkey。上面写的 relabel 配置根本不会导致暴露任何标签,而且似乎被忽略了。 运行 日志级别设置为调试的 Prometheus 也没有产生任何结果。

相关文档

https://www.robustperception.io/extracting-full-labels-from-consul-tags/ 展示了如何执行此操作,尤其是最后一个示例。

理解不正确

我认为我对 prometheus 中标签工作原理的理解有误。我的不正确理解是:

  1. 在应用 regex 之前,字符串将首先在 separator 上拆分(否则它的目的是什么?),
  2. 每个子字符串都有 regex 对其进行评估,
  3. 如果声明并找到匹配组,它们将作为索引值可用,可用于 target_labelreplacement 字段。
  4. 如果 regex 不匹配,则该子字符串将被忽略。
  5. 因为regex希望在拆分后应用于每个子串,所以会导致多个子串有多个标签。

正确理解

但是,从 brian-brazil's post linked in his 和 Prometheus 的文档来看,似乎发生了以下情况:

  1. 所有 __meta 标签合并为一长 separator 分隔线。
  2. regex 仅在该行应用一次。
  3. 如果 regex 匹配并包含组,它们的索引从 1 开始,可用于 target_labelreplacement
  4. separator 似乎在本节中被忽略,即使您提到它也是如此。

根据更正的理解配置

根据这个想法并遵循问题中的示例,我能够进行以下有效配置

relabel_configs:
- source_labels: [__meta_consul_tags]
  regex:         '.*,a=([a-z0-9_]+),.+'
  target_label:  'a'
  replacement:   

- source_labels: [__meta_consul_tags]
  regex:         '.*,b=([a-z0-9_]+),.+'
  target_label:  'b'
  replacement:   

- source_labels: [__meta_consul_tags]
  regex:         '.*,c=([a-z0-9_]+),.+'
  target_label:  'c'
  replacement:   

- source_labels: [__meta_consul_tags]
  regex:         '.*,d=([a-z0-9_]+),.+'
  target_label:  'd'
  replacement:   

注意事项

我相信这两种方法(brian-brazil 在 his blogpost 中写的方法以及我在上面使用的方法)都有警告 - 我们要么需要事先知道我们想要的所有标签,要么有一个固定的数字他们中的。这意味着如果开发人员想要将不同的或更多标签与 his/her 服务相关联,s/he 将需要与 ops 一起工作,因为一般流程将无法处理它。我认为这是一个应该解决的小问题。

以下重新标记规则可用于从 __meta_consul_tags 中提取特定的 tag 并将其放置到 destination_label:

relabel_configs:
- source_labels: [__meta_consul_tags]
  regex:         '.*,tag=([^,]+),.*'
  target_label:  destination_label

不需要指定replacement选项,因为它默认为</code>。</p> <p>如果必须将多个标签从 <code>__meta_consul_tags 中提取到多个标签中,则只需为每个需要的标签重复重新标记规则即可。例如,以下重新标记规则将 a 标签提取到 a 标签,将 b 标签提取到 b 标签:

relabel_configs:
- source_labels: [__meta_consul_tags]
  regex: '.*,a=([^,]+),.*'
  target_label: a
- source_labels: [__meta_consul_tags]
  regex: '.*,b=([^,]+),.*'
  target_label: b

有关 Prometheus 中重新标记规则的更多信息,请参阅 this article