-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(inputs.prometheus): pod_annotation_template and pod_label_template #10946
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,50 +10,56 @@ in Prometheus format. | |
[[inputs.prometheus]] | ||
## An array of urls to scrape metrics from. | ||
urls = ["http://localhost:9100/metrics"] | ||
|
||
## Metric version controls the mapping from Prometheus metrics into | ||
## Telegraf metrics. When using the prometheus_client output, use the same | ||
## value in both plugins to ensure metrics are round-tripped without | ||
## modification. | ||
## | ||
## example: metric_version = 1; | ||
## example: metric_version = 1; | ||
## metric_version = 2; recommended version | ||
# metric_version = 1 | ||
|
||
## Url tag name (tag containing scrapped url. optional, default is "url") | ||
# url_tag = "url" | ||
|
||
## Whether the timestamp of the scraped metrics will be ignored. | ||
## If set to true, the gather time will be used. | ||
# ignore_timestamp = false | ||
|
||
## An array of Kubernetes services to scrape metrics from. | ||
# kubernetes_services = ["http://my-service-dns.my-namespace:9100/metrics"] | ||
|
||
## Kubernetes config file to create client from. | ||
# kube_config = "/path/to/kubernetes.config" | ||
|
||
## Scrape Kubernetes pods for the following prometheus annotations: | ||
## - prometheus.io/scrape: Enable scraping for this pod | ||
## - prometheus.io/scheme: If the metrics endpoint is secured then you will need to | ||
## set this to 'https' & most likely set the tls config. | ||
## - prometheus.io/path: If the metrics path is not /metrics, define it with this annotation. | ||
## - prometheus.io/port: If port is not 9102 use this annotation | ||
# monitor_kubernetes_pods = true | ||
|
||
## Get the list of pods to scrape with either the scope of | ||
## - cluster: the kubernetes watch api (default, no need to specify) | ||
## - node: the local cadvisor api; for scalability. Note that the config node_ip or the environment variable NODE_IP must be set to the host IP. | ||
# pod_scrape_scope = "cluster" | ||
|
||
## Only for node scrape scope: node IP of the node that telegraf is running on. | ||
## Either this config or the environment variable NODE_IP must be set. | ||
# node_ip = "10.180.1.1" | ||
|
||
## Only for node scrape scope: interval in seconds for how often to get updated pod list for scraping. | ||
## Default is 60 seconds. | ||
# pod_scrape_interval = 60 | ||
|
||
|
||
## Pod label & annotation tag template | ||
## Default is "{{ . }}" | ||
## Useful to glob match labels & annotations in "tagexclude" or "taginclude" | ||
# pod_label_template = "{{ . }}" | ||
# pod_annotation_template = "{{ . }}" | ||
|
||
## Restricts Kubernetes monitoring to a single namespace | ||
## ex: monitor_kubernetes_pods_namespace = "default" | ||
# monitor_kubernetes_pods_namespace = "" | ||
|
@@ -63,7 +69,7 @@ in Prometheus format. | |
# eg. To scrape pods on a specific node | ||
# kubernetes_field_selector = "spec.nodeName=$HOSTNAME" | ||
|
||
# cache refresh interval to set the interval for re-sync of pods list. | ||
# cache refresh interval to set the interval for re-sync of pods list. | ||
# Default is 60 minutes. | ||
# cache_refresh_interval = 60 | ||
|
||
|
@@ -79,25 +85,25 @@ in Prometheus format. | |
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}' | ||
# [inputs.prometheus.consul.query.tags] | ||
# host = "{{.Node}}" | ||
|
||
## Use bearer token for authorization. ('bearer_token' takes priority) | ||
# bearer_token = "/path/to/bearer/token" | ||
## OR | ||
# bearer_token_string = "abc_123" | ||
|
||
## HTTP Basic Authentication username and password. ('bearer_token' and | ||
## 'bearer_token_string' take priority) | ||
# username = "" | ||
# password = "" | ||
|
||
## Specify timeout duration for slower prometheus clients (default is 3s) | ||
# response_timeout = "3s" | ||
|
||
## Optional TLS Config | ||
# tls_ca = /path/to/cafile | ||
# tls_cert = /path/to/certfile | ||
# tls_key = /path/to/keyfile | ||
|
||
## Use TLS but skip chain & host verification | ||
# insecure_skip_verify = false | ||
``` | ||
|
@@ -135,7 +141,7 @@ env: | |
valueFrom: | ||
fieldRef: | ||
fieldPath: status.hostIP | ||
``` | ||
``` | ||
|
||
If using node level scrape scope, `pod_scrape_interval` specifies how often (in seconds) the pod list for scraping should updated. If not specified, the default is 60 seconds. | ||
|
||
|
@@ -179,6 +185,18 @@ metadata: | |
name: telegraf-k8s-{{ .Release.Name }} | ||
``` | ||
|
||
### Excluding Annotation & Label Tags | ||
|
||
```diff | ||
[[inputs.prometheus]] | ||
metric_version = 2 | ||
monitor_kubernetes_pods = true | ||
pod_scrape_scope = "node" | ||
+ pod_label_template = 'pod.label/{{ . }}' | ||
+ pod_annotation_template = 'pod.annotation/{{ . }}' | ||
Comment on lines
+195
to
+196
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above, we could cover this with just pod_label_prefix = 'pod.label'
pod_annotation_prefix = 'pod.annotation' |
||
+ tagexclude = ["pod.annotation/*", "pod.label/*"] | ||
``` | ||
|
||
### Consul Service Discovery | ||
|
||
Enabling this option and configuring consul `agent` url will allow the plugin to query | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,14 +188,14 @@ func (p *Prometheus) getConsulServiceURL(q *ConsulQuery, s *api.CatalogService) | |
return nil, err | ||
} | ||
|
||
extraTags := make(map[string]string) | ||
extraTags := make(map[string]Tag) | ||
for tagName, tagTemplate := range q.serviceExtraTagsTemplate { | ||
buffer.Reset() | ||
err = tagTemplate.Execute(&buffer, s) | ||
if err != nil { | ||
return nil, err | ||
} | ||
extraTags[tagName] = buffer.String() | ||
extraTags[tagName] = Tag{Value: buffer.String()} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this necessary? |
||
} | ||
|
||
p.Log.Debugf("Will scrape metrics from Consul Service %s", serviceURL.String()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -368,16 +368,16 @@ func registerPod(pod *corev1.Pod, p *Prometheus) { | |
} | ||
|
||
p.Log.Debugf("will scrape metrics from %q", targetURL.String()) | ||
tags := map[string]Tag{} | ||
tags["pod_name"] = Tag{Value: pod.Name} | ||
tags["namespace"] = Tag{Value: pod.Namespace} | ||
// add annotation as metrics tags | ||
tags := pod.Annotations | ||
if tags == nil { | ||
tags = map[string]string{} | ||
for k, v := range pod.Annotations { | ||
tags[k] = Tag{Value: v, Template: p.podAnnotationTmpl} | ||
} | ||
tags["pod_name"] = pod.Name | ||
tags["namespace"] = pod.Namespace | ||
// add labels as metrics tags | ||
for k, v := range pod.Labels { | ||
tags[k] = v | ||
tags[k] = Tag{Value: v, Template: p.podLabelTmpl} | ||
Comment on lines
+371
to
+380
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better to directly apply the modification here instead of looping this through all the code? |
||
} | ||
podURL := p.AddressToURL(targetURL, targetURL.Hostname()) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really necessary to make this a template or can we get away with defining a prefix? I'm asking because this adds complexity that might not be required and furthermore it's not completely intuitive to use a template, usually use to generate stuff, for parsing...