Browse Source

Add metrics descriptions

Added inventories of known metrics on per-source basis to supply
along with the metric name and value to Prometheus.

Change-Id: I6ea466a332b220902071bb24e2eb1fd9c23f5aaf
changes/07/681007/6
Ilya Etingof 1 week ago
parent
commit
0ded99ebc9

+ 39
- 0
ironic_prometheus_exporter/parsers/descriptions.py View File

@@ -0,0 +1,39 @@
1
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+#    not use this file except in compliance with the License. You may obtain
3
+#    a copy of the License at
4
+#
5
+#         http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+#    Unless required by applicable law or agreed to in writing, software
8
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+#    License for the specific language governing permissions and limitations
11
+#    under the License.
12
+
13
+
14
+import json
15
+import logging
16
+import os
17
+import pkg_resources
18
+
19
+DESCRIPTIONS = {}
20
+
21
+LOG = logging.getLogger(__name__)
22
+
23
+
24
+def get_metric_description(source, metric_name):
25
+    if source not in DESCRIPTIONS:
26
+        try:
27
+            json_file = pkg_resources.resource_filename(
28
+                __name__, os.path.join(
29
+                    'metrics_information', source + '.json'))
30
+
31
+            with open(json_file) as fl:
32
+                DESCRIPTIONS[source] = json.load(fl)
33
+
34
+        except Exception as exc:
35
+            LOG.warning(
36
+                'Failed to load metrics descriptions '
37
+                'for metrics source %s: %s', source, exc)
38
+
39
+    return DESCRIPTIONS.get(source, {}).get(metric_name, '')

+ 10
- 2
ironic_prometheus_exporter/parsers/header.py View File

@@ -11,8 +11,11 @@
11 11
 #    under the License.
12 12
 
13 13
 from datetime import datetime
14
+
14 15
 from prometheus_client import Gauge
15 16
 
17
+from ironic_prometheus_exporter.parsers import descriptions
18
+
16 19
 
17 20
 def timestamp_registry(node_information, ipmi_metric_registry):
18 21
     metric = 'baremetal_last_payload_timestamp_seconds'
@@ -23,6 +26,11 @@ def timestamp_registry(node_information, ipmi_metric_registry):
23 26
     dt_timestamp = datetime.strptime(node_information['timestamp'],
24 27
                                      '%Y-%m-%dT%H:%M:%S.%f')
25 28
     value = int((dt_timestamp - dt_1970).total_seconds())
26
-    g = Gauge(metric, 'Timestamp of the last received payload',
27
-              labelnames=labels.keys(), registry=ipmi_metric_registry)
29
+
30
+    desc = descriptions.get_metric_description('header', metric)
31
+
32
+    g = Gauge(
33
+        metric, desc, labelnames=labels,
34
+        registry=ipmi_metric_registry)
35
+
28 36
     g.labels(**labels).set(value)

+ 5
- 5
ironic_prometheus_exporter/parsers/ipmi.py View File

@@ -17,6 +17,9 @@ import re
17 17
 
18 18
 from prometheus_client import Gauge
19 19
 
20
+from ironic_prometheus_exporter.parsers import descriptions
21
+
22
+
20 23
 # NOTE (iurygregory): most of the sensor readings come in the ipmi format
21 24
 # each type of sensor consider a different range of values that aren't integers
22 25
 # (eg: 0h, 2eh), 0h will be published as 0 and the other values as 1, this way
@@ -220,7 +223,8 @@ def prometheus_format(category_info, ipmi_metric_registry, available_metrics):
220 223
         values = extract_values(entries, category_info)
221 224
         if all(v is None for v in values.values()):
222 225
             continue
223
-        g = Gauge(metric, get_metric_description(metric),
226
+        desc = descriptions.get_metric_description('ipmi', metric)
227
+        g = Gauge(metric, desc,
224 228
                   labelnames=list(labels.get(entries[0])),
225 229
                   registry=ipmi_metric_registry)
226 230
         for e in entries:
@@ -240,7 +244,3 @@ def category_registry(node_message, ipmi_metric_registry):
240 244
             available_metrics = metric_names(category_dict)
241 245
             prometheus_format(category_dict, ipmi_metric_registry,
242 246
                               available_metrics)
243
-
244
-
245
-def get_metric_description(metric_name):
246
-    return IPMI_METRICS_DESCRIPTION.get(metric_name, '')

+ 4
- 0
ironic_prometheus_exporter/parsers/metrics_information/header.json View File

@@ -0,0 +1,4 @@
1
+{
2
+    "baremetal_last_payload_timestamp_seconds":
3
+        "Timestamp of the last received payload"
4
+}

+ 54
- 0
ironic_prometheus_exporter/parsers/metrics_information/redfish.json View File

@@ -0,0 +1,54 @@
1
+{
2
+    "baremetal_power_status":
3
+        "Power supply unit health status (0 - OK, 1 - failure)",
4
+    "baremetal_temp_room_celsius":
5
+        "Room temperature expressed in Celsius",
6
+    "baremetal_temp_intake_celsius":
7
+        "Intake air temperature expressed in Celsius",
8
+    "baremetal_temp_exhaust_celsius":
9
+        "Exhaust air temperature expressed in Celsius",
10
+    "baremetal_temp_front_celsius":
11
+        "Front chassis temperature expressed in Celsius",
12
+    "baremetal_temp_back_celsius":
13
+        "Back chassis temperature expressed in Celsius",
14
+    "baremetal_temp_upper_celsius":
15
+        "Upper chassis temperature expressed in Celsius",
16
+    "baremetal_temp_lower_celsius":
17
+        "Lower chassis temperature expressed in Celsius",
18
+    "baremetal_temp_cpu_celsius":
19
+        "CPU temperature expressed in Celsius",
20
+    "baremetal_temp_gpu_celsius":
21
+        "GPU temperature expressed in Celsius",
22
+    "baremetal_temp_backplane_celsius":
23
+        "Backplane temperature expressed in Celsius",
24
+    "baremetal_temp_systemboard_celsius":
25
+        "System Board temperature expressed in Celsius",
26
+    "baremetal_temp_powersupply_celsius":
27
+        "Power Supply temperature expressed in Celsius",
28
+    "baremetal_temp_voltageregulator_celsius":
29
+        "Voltage Regulator temperature expressed in Celsius",
30
+    "baremetal_temp_storagedevice_celsius":
31
+        "Storage Device temperature expressed in Celsius",
32
+    "baremetal_temp_networkingdevice_celsius":
33
+        "Networking Device temperature expressed in Celsius",
34
+    "baremetal_temp_computebay_celsius":
35
+        "Compute Bay temperature expressed in Celsius",
36
+    "baremetal_temp_storagebay_celsius":
37
+        "Storage Bay temperature expressed in Celsius",
38
+    "baremetal_temp_networkbay_celsius":
39
+        "Network Bay temperature expressed in Celsius",
40
+    "baremetal_temp_expansionbay_celsius":
41
+        "Expansion Bay temperature expressed in Celsius",
42
+    "baremetal_temp_powersupplybay_celsius":
43
+        "Power Supply Bay temperature expressed in Celsius",
44
+    "baremetal_temp_memory_celsius":
45
+        "Memory unit temperature expressed in Celsius",
46
+    "baremetal_temp_chassis_celsius":
47
+        "Chassis temperature expressed in Celsius",
48
+    "baremetal_temp_fan_celsius":
49
+        "Cooling fan temperature expressed in Celsius",
50
+    "baremetal_fan_status":
51
+        "Cooling fan health status (0 - OK, 1 - failure)",
52
+    "baremetal_drive_status":
53
+        "Storage drive health status (0 - OK, 1 - failure)"
54
+}

+ 5
- 1
ironic_prometheus_exporter/parsers/redfish.py View File

@@ -15,6 +15,8 @@ import logging
15 15
 
16 16
 from prometheus_client import Gauge
17 17
 
18
+from ironic_prometheus_exporter.parsers import descriptions
19
+
18 20
 
19 21
 LOG = logging.getLogger(__name__)
20 22
 
@@ -250,7 +252,9 @@ def category_registry(node_message, metrics_registry):
250 252
 
251 253
         for value, labels in details:
252 254
 
253
-            gauge = Gauge(metric, '', labelnames=labels,
255
+            desc = descriptions.get_metric_description('redfish', metric)
256
+
257
+            gauge = Gauge(metric, desc, labelnames=labels,
254 258
                           registry=metrics_registry)
255 259
 
256 260
             gauge.labels(**labels).set(value)

+ 42
- 0
ironic_prometheus_exporter/tests/test_descriptions.py View File

@@ -0,0 +1,42 @@
1
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+#    not use this file except in compliance with the License. You may obtain
3
+#    a copy of the License at
4
+#
5
+#         http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+#    Unless required by applicable law or agreed to in writing, software
8
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+#    License for the specific language governing permissions and limitations
11
+#    under the License.
12
+
13
+from ironic_prometheus_exporter.parsers import descriptions
14
+
15
+from oslo_messaging.tests import utils as test_utils
16
+
17
+
18
+class TestMetricsDescriptions(test_utils.BaseTestCase):
19
+
20
+    def test_good_source_good_metrics(self):
21
+        desc = descriptions.get_metric_description(
22
+            'header', 'baremetal_last_payload_timestamp_seconds')
23
+
24
+        expected = 'Timestamp of the last received payload'
25
+
26
+        self.assertEqual(expected, desc)
27
+
28
+    def test_good_source_bad_metrics(self):
29
+        desc = descriptions.get_metric_description(
30
+            'header', 'bad_metrics')
31
+
32
+        expected = ''
33
+
34
+        self.assertEqual(expected, desc)
35
+
36
+    def test_bad_source_bad_metrics(self):
37
+        desc = descriptions.get_metric_description(
38
+            'bad_source', 'bad_metrics')
39
+
40
+        expected = ''
41
+
42
+        self.assertEqual(expected, desc)

Loading…
Cancel
Save