From d73130972a78c7bd8de0eb7a2e66c7a14941fc7e Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Fri, 4 Oct 2019 01:20:16 +0200 Subject: [PATCH] feat(textfile_collectors): added IPMI textfile collector --- pillar.example | 6 +- .../textfile_collectors/files/ipmitool | 91 +++++++++++++++++++ .../textfile_collectors/ipmitool/clean.sls | 26 ++++++ .../textfile_collectors/ipmitool/init.sls | 32 +++++++ prometheus/defaults.yaml | 6 +- .../default/controls/config_spec.rb | 6 ++ 6 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 prometheus/config/node_exporter/textfile_collectors/files/ipmitool create mode 100644 prometheus/config/node_exporter/textfile_collectors/ipmitool/clean.sls create mode 100644 prometheus/config/node_exporter/textfile_collectors/ipmitool/init.sls diff --git a/pillar.example b/pillar.example index f47caf2..5da6b94 100644 --- a/pillar.example +++ b/pillar.example @@ -168,4 +168,8 @@ prometheus: exporters: node_exporter: - textfile_collectors: {} + textfile_collectors: + ipmitool: + # You must enable individual collectors + enable: true + # pkg: ipmitool diff --git a/prometheus/config/node_exporter/textfile_collectors/files/ipmitool b/prometheus/config/node_exporter/textfile_collectors/files/ipmitool new file mode 100644 index 0000000..c500c05 --- /dev/null +++ b/prometheus/config/node_exporter/textfile_collectors/files/ipmitool @@ -0,0 +1,91 @@ +#!/usr/bin/awk -f + +# Source: https://github.com/prometheus/node_exporter/blob/master/text_collector_examples/ipmitool + +# +# Converts output of `ipmitool sensor` to prometheus format. +# +# With GNU awk: +# ipmitool sensor | ./ipmitool > ipmitool.prom +# +# With BSD awk: +# ipmitool sensor | awk -f ./ipmitool > ipmitool.prom +# + +function export(values, name) { + if (values["metric_count"] < 1) { + return + } + delete values["metric_count"] + + printf("# HELP %s%s %s sensor reading from ipmitool\n", namespace, name, help[name]); + printf("# TYPE %s%s gauge\n", namespace, name); + for (sensor in values) { + printf("%s%s{sensor=\"%s\"} %f\n", namespace, name, sensor, values[sensor]); + } +} + +# Fields are Bar separated, with space padding. +BEGIN { + FS = "[ ]*[|][ ]*"; + namespace = "node_ipmi_"; + + # Friendly description of the type of sensor for HELP. + help["temperature_celsius"] = "Temperature"; + help["volts"] = "Voltage"; + help["power_watts"] = "Power"; + help["speed_rpm"] = "Fan"; + help["status"] = "Chassis status"; + + temperature_celsius["metric_count"] = 0; + volts["metric_count"] = 0; + power_watts["metric_count"] = 0; + speed_rpm["metric_count"] = 0; + status["metric_count"] = 0; +} + +# Not a valid line. +{ + if (NF < 3) { + next + } +} + +# $2 is value field. +$2 ~ /na/ { + next +} + +# $3 is type field. +$3 ~ /degrees C/ { + temperature_celsius[$1] = $2; + temperature_celsius["metric_count"]++; +} + +$3 ~ /Volts/ { + volts[$1] = $2; + volts["metric_count"]++; +} + +$3 ~ /Watts/ { + power_watts[$1] = $2; + power_watts["metric_count"]++; +} + +$3 ~ /RPM/ { + speed_rpm[$1] = $2; + speed_rpm["metric_count"]++; +} + +$3 ~ /discrete/ { + status[$1] = $2; + status["metric_count"]++; +} + +END { + export(temperature_celsius, "temperature_celsius"); + export(volts, "volts"); + export(power_watts, "power_watts"); + export(speed_rpm, "speed_rpm"); + export(status, "status"); +} diff --git a/prometheus/config/node_exporter/textfile_collectors/ipmitool/clean.sls b/prometheus/config/node_exporter/textfile_collectors/ipmitool/clean.sls new file mode 100644 index 0000000..4348815 --- /dev/null +++ b/prometheus/config/node_exporter/textfile_collectors/ipmitool/clean.sls @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +{%- set config = prometheus.exporters.node_exporter.textfile_collectors.ipmitool %} +{%- set dir = prometheus.service.node_exporter.args.get('collector.textfile.directory') %} +{%- set script = prometheus.dir.textfile_collectors ~ '/ipmitool' %} + +prometheus-exporters-node-textfile_collectors-ipmitool-pkg: + pkg.removed: + - name: {{ config.pkg }} + +prometheus-exporters-node-textfile_collectors-ipmitool-script: + file.absent: + - name: {{ script }} + +prometheus-exporters-node-textfile_collectors-ipmitool-output: + file.absent: + - name: {{ dir }}/ipmitool.prom + +prometheus-exporters-node-textfile_collectors-ipmitool-cronjob: + cron.absent: + - identifier: prometheus-exporters-node-textfile_collectors-ipmitool-cronjob diff --git a/prometheus/config/node_exporter/textfile_collectors/ipmitool/init.sls b/prometheus/config/node_exporter/textfile_collectors/ipmitool/init.sls new file mode 100644 index 0000000..ae7cfb6 --- /dev/null +++ b/prometheus/config/node_exporter/textfile_collectors/ipmitool/init.sls @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +{%- set config = prometheus.exporters.node_exporter.textfile_collectors.ipmitool %} +{%- set dir = prometheus.service.node_exporter.args.get('collector.textfile.directory') %} +{%- set script = prometheus.dir.textfile_collectors ~ '/ipmitool' %} +{%- set cmd_prefix = 'awk -f ' if grains.os_family in ['FreeBSD'] else '' %} + +prometheus-exporters-node-textfile_collectors-ipmitool-pkg: + pkg.installed: + - name: {{ config.pkg }} + +prometheus-exporters-node-textfile_collectors-ipmitool-script: + file.managed: + - name: {{ script }} + - source: salt://prometheus/config/node_exporter/textfile_collectors/files/ipmitool + - mode: 755 + - require: + - file: prometheus-node_exporter-textfile_collectors-dir + +prometheus-exporters-node-textfile_collectors-ipmitool-cronjob: + cron.present: + - identifier: prometheus-exporters-node-textfile_collectors-ipmitool-cronjob + - name: cd {{ dir }} && LANG=C ipmitool sensor | {{ cmd_prefix }}{{ script }} > .ipmitool.prom$$; mv .ipmitool.prom$$ ipmitool.prom + - minute: "{{ config.get('minute', '*') }}" + - comment: Prometheus' node_exporter's ipmitool textfile collector + - require: + - file: prometheus-exporters-node-textfile_collectors-ipmitool-script diff --git a/prometheus/defaults.yaml b/prometheus/defaults.yaml index 81bc72d..10d473a 100644 --- a/prometheus/defaults.yaml +++ b/prometheus/defaults.yaml @@ -122,4 +122,8 @@ prometheus: exporters: node_exporter: textfile_collectors_dependencies: [] - textfile_collectors: {} + textfile_collectors: + ipmitool: + enable: false + remove: false + pkg: ipmitool diff --git a/test/integration/default/controls/config_spec.rb b/test/integration/default/controls/config_spec.rb index aff7744..2eabf25 100644 --- a/test/integration/default/controls/config_spec.rb +++ b/test/integration/default/controls/config_spec.rb @@ -11,4 +11,10 @@ control 'Prometheus configuration' do its('content') { should include 'global:' } its('content') { should include 'alerting:' } end + + describe file('/opt/prometheus/textfile_collectors/ipmitool') do + it { should be_file } + it { should be_owned_by 'root' } + its('mode') { should cmp '0755' } + end end