From 9330da31952a4f7062bf7b1898eb414bccb66907 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 19 Dec 2022 12:55:49 -0800 Subject: [PATCH] lib/promscrape/discovery/consul: expose service tags in individual labels `__meta_consul_tag_` This simplifies copying service tags to target labels with the following relabeling rule: - action: labelmap regex: __meta_consul_tag_(.+) See https://stackoverflow.com/questions/44339461/relabeling-in-prometheus --- docs/CHANGELOG.md | 6 ++++++ docs/sd_configs.md | 7 +++++-- .../discovery/consul/service_node.go | 18 ++++++++++++++++++ .../discovery/consul/service_node_test.go | 8 ++++++-- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8c45f88af..2a055cd1a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,6 +17,12 @@ The following tip changes can be tested by building VictoriaMetrics components f * FEATURE: support overriding of `-search.latencyOffset` value via URL param `latency_offset` when performing requests to [/api/v1/query](https://docs.victoriametrics.com/keyConcepts.html#instant-query) and [/api/v1/query_range](https://docs.victoriametrics.com/keyConcepts.html#range-query). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3481). * FEATURE: allow changing field names in JSON logs if VictoriaMetrics components are started with `-loggerFormat=json` command-line flags. The field names can be changed with the `-loggerJSONFields` command-line flag. For example `-loggerJSONFields=ts:timestamp,msg:message` would rename `ts` and `msg` fields on the output JSON to `timestamp` and `message` fields. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2348). Thanks to @michal-kralik for [the pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3488). +* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): expose `__meta_consul_tag_` and `__meta_consul_tagpresent_` labels for targets discovered via [consul_sd_configs](https://docs.victoriametrics.com/sd_configs.html#consul_sd_configs). This simplifies converting [Consul service tags](https://developer.hashicorp.com/consul/docs/discovery/services#service-definition) to target labels with a simple [relabeling rule](https://docs.victoriametrics.com/vmagent.html#relabeling): +```yml +- action: labelmap + regex: __meta_consul_tag_(.+) +``` +This resolves [this StackOverflow question](https://stackoverflow.com/questions/44339461/relabeling-in-prometheus). * BUGFIX: properly return query results for time series, which stop receiving new samples after the rotation of `indexdb`. Previously such time series could be missing in query results. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3502). The issue has been introduced in [v1.83.0](https://docs.victoriametrics.com/CHANGELOG.html#v1830). * BUGFIX: allow specifying values bigger than 2GiB to the following command-line flag values on 32-bit architectures (`386` and `arm`): `-storage.minFreeDiskSpaceBytes` and `-remoteWrite.maxDiskUsagePerURL`. Previously values bigger than 2GiB were incorrectly truncated on these architectures. diff --git a/docs/sd_configs.md b/docs/sd_configs.md index 9125d890c..7fe4231e6 100644 --- a/docs/sd_configs.md +++ b/docs/sd_configs.md @@ -140,6 +140,7 @@ scrape_configs: # tag_separate is an optional string by which Consul tags are joined into the __meta_consul_tags label. # By default "," is used as a tag separator. + # Individual tags are also available via __meta_consul_tag_ labels - see below. # tag_separator: "..." # allow_stale is an optional config, which allows stale Consul results. @@ -166,7 +167,9 @@ The following meta labels are available on discovered targets during [relabeling * `__meta_consul_service_port`: the service port of the target * `__meta_consul_service`: the name of the service the target belongs to * `__meta_consul_tagged_address_`: each node tagged address key value of the target -* `__meta_consul_tags`: the list of tags of the target joined by the tag separator +* `__meta_consul_tag_`: the value for the given tag of the target +* `__meta_consul_tagpresent_`: "true" for every tag of the target +* `__meta_consul_tags`: the list of tags of the target joined by the tag_separator ## digitalocean_sd_configs @@ -631,7 +634,7 @@ The following meta labels are available on discovered targets during [relabeling * `__meta_gce_project`: the GCP project in which the instance is running * `__meta_gce_public_ip`: the public IP address of the instance, if present * `__meta_gce_subnetwork`: the subnetwork URL of the instance -* `__meta_gce_tags`: comma separated list of instance tags +* `__meta_gce_tags`: list of instance tags separated by tag_separator * `__meta_gce_zone`: the GCE zone URL in which the instance is running diff --git a/lib/promscrape/discovery/consul/service_node.go b/lib/promscrape/discovery/consul/service_node.go index 1f62201d4..cdc4505a7 100644 --- a/lib/promscrape/discovery/consul/service_node.go +++ b/lib/promscrape/discovery/consul/service_node.go @@ -95,6 +95,24 @@ func (sn *ServiceNode) appendTargetLabels(ms []*promutils.Labels, serviceName, t // in relabeling rules don't have to consider tag positions. m.Add("__meta_consul_tags", tagSeparator+strings.Join(sn.Service.Tags, tagSeparator)+tagSeparator) + // Expose individual tags via __meta_consul_tag_* labels, so users could move all the tags + // into the discovered scrape target with the following relabeling rule in the way similar to kubernetes_sd_configs: + // + // - action: labelmap + // regex: __meta_consul_tag_(.+) + // + // This solves https://stackoverflow.com/questions/44339461/relabeling-in-prometheus + for _, tag := range sn.Service.Tags { + k := tag + v := "" + if n := strings.IndexByte(tag, '='); n >= 0 { + k = tag[:n] + v = tag[n+1:] + } + m.Add(discoveryutils.SanitizeLabelName("__meta_consul_tag_"+k), v) + m.Add(discoveryutils.SanitizeLabelName("__meta_consul_tagpresent_"+k), "true") + } + for k, v := range sn.Node.Meta { m.Add(discoveryutils.SanitizeLabelName("__meta_consul_metadata_"+k), v) } diff --git a/lib/promscrape/discovery/consul/service_node_test.go b/lib/promscrape/discovery/consul/service_node_test.go index 81dec65d1..3991c326b 100644 --- a/lib/promscrape/discovery/consul/service_node_test.go +++ b/lib/promscrape/discovery/consul/service_node_test.go @@ -43,7 +43,7 @@ func TestParseServiceNodesSuccess(t *testing.T) { "Service": { "ID": "redis", "Service": "redis", - "Tags": ["primary"], + "Tags": ["primary","foo=bar"], "Address": "10.1.10.12", "TaggedAddresses": { "lan": { @@ -124,7 +124,11 @@ func TestParseServiceNodesSuccess(t *testing.T) { "__meta_consul_service_port": "8000", "__meta_consul_tagged_address_lan": "10.1.10.12", "__meta_consul_tagged_address_wan": "10.1.10.12", - "__meta_consul_tags": ",primary,", + "__meta_consul_tag_foo": "bar", + "__meta_consul_tag_primary": "", + "__meta_consul_tagpresent_foo": "true", + "__meta_consul_tagpresent_primary": "true", + "__meta_consul_tags": ",primary,foo=bar,", }), } discoveryutils.TestEqualLabelss(t, labelss, expectedLabelss)