Skip to content

Commit

Permalink
add labels_mapper option to kubernetes_state to allow tag renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
xvello committed Aug 2, 2017
1 parent fbf8ad8 commit 33a0bbc
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
3 changes: 2 additions & 1 deletion kubernetes_state/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

### Changes

* [FEATURE] Support for StatefulSet metrics
* [FEATURE] Support for StatefulSet metrics. See [#561][]
* [FEATURE] Support tag renaming via the labels_mapper option. See [#651][]

1.2.0 / 2017-07-18
==================
Expand Down
4 changes: 4 additions & 0 deletions kubernetes_state/auto_conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ docker_images:
- kube-state-metrics

init_config:
# Tags are reported as set by kube-state-metrics. If you want to translate
# them to other tags, you can use the labels_mapper dictionary
# labels_mapper:
# namespace: kube_namespace
instances:
# To enable Kube State metrics you must specify the url exposing the API
- kube_state_url: http://%%host%%:%%port%%/metrics
25 changes: 19 additions & 6 deletions kubernetes_state/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ def __init__(self, name, init_config, agentConfig, instances=None):
super(KubernetesState, self).__init__(name, init_config, agentConfig, instances)
self.NAMESPACE = 'kubernetes_state'

if 'labels_mapper' in init_config:
if isinstance(init_config['labels_mapper'], dict):
self.labels_mapper = init_config['labels_mapper']
else:
self.log.warning("labels_mapper should be a dictionnary")

self.pod_phase_to_status = {
'pending': self.WARNING,
'running': self.OK,
Expand Down Expand Up @@ -169,6 +175,13 @@ def _extract_label_value(self, name, labels):
return label.value
return None

def _format_tag(self, name, value):
"""
Lookups the labels_mapper table to see if replacing the tag name is
necessary, then returns a "name:value" tag string
"""
return '%s:%s' % (self.labels_mapper.get(name, name), value)

def _label_to_tag(self, name, labels, tag_name=None):
"""
Search for `name` in labels name and returns corresponding tag string.
Expand All @@ -177,7 +190,7 @@ def _label_to_tag(self, name, labels, tag_name=None):
"""
value = self._extract_label_value(name, labels)
if value:
return '%s:%s' % (tag_name or name, value)
return self._format_tag(tag_name or name, value)
else:
return None

Expand All @@ -194,7 +207,7 @@ def kube_pod_status_phase(self, message, **kwargs):
if label.name == 'phase':
phase = label.value.lower()
else:
tags.append('{}:{}'.format(label.name, label.value))
tags.append(self._format_tag(label.name, label.value))
#TODO: add deployment/replicaset?
status = self.pod_phase_to_status.get(phase, self.UNKNOWN)
self.service_check(check_basename + phase, status, tags=tags)
Expand All @@ -204,15 +217,15 @@ def kube_job_complete(self, message, **kwargs):
for metric in message.metric:
tags = []
for label in metric.label:
tags.append('{}:{}'.format(label.name, label.value))
tags.append(self._format_tag(label.name, label.value))
self.service_check(service_check_name, self.OK, tags=tags)

def kube_job_failed(self, message, **kwargs):
service_check_name = self.NAMESPACE + '.job.complete'
for metric in message.metric:
tags = []
for label in metric.label:
tags.append('{}:{}'.format(label.name, label.value))
tags.append(self._format_tag(label.name, label.value))
self.service_check(service_check_name, self.CRITICAL, tags=tags)

def kube_node_status_ready(self, message, **kwargs):
Expand Down Expand Up @@ -256,9 +269,9 @@ def kube_node_spec_unschedulable(self, message, **kwargs):
statuses = ('schedulable', 'unschedulable')
if message.type < len(METRIC_TYPES):
for metric in message.metric:
tags = ['{}:{}'.format(label.name, label.value) for label in metric.label]
tags = [self._format_tag(label.name, label.value) for label in metric.label]
status = statuses[int(getattr(metric, METRIC_TYPES[message.type]).value)] # value can be 0 or 1
tags.append('status:{}'.format(status))
tags.append(self._format_tag('status', status))
self.gauge(metric_name, 1, tags) # metric value is always one, value is on the tags
else:
self.log.error("Metric type %s unsupported for metric %s" % (message.type, message.name))
Expand Down
6 changes: 6 additions & 0 deletions kubernetes_state/conf.yaml.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
init_config:
# Tags are reported as set by kube-state-metrics. If you want to translate
# them to other tags, you can use the labels_mapper dictionary
# labels_mapper:
# namespace: kube_namespace

# Custom tags can be added to all metrics reported by this integration
# tags:
# - optional_tag1
# - optional_tag2
Expand Down

0 comments on commit 33a0bbc

Please sign in to comment.