Browse Source

Move timestamp registry to a sharable 'header' module

The timestamp registry is going to be used by other parsers
in the future. Thus it seems reasonable to move if from ipmi
to something sharable.

Conceptually, `timestamp_registry` operates on Oslo message
header - perhaps we can have a dedicated parser module for
such common things - 'header'.

Change-Id: I2ba2f0ae28f09dbccd818c82005d47c7a515dfd4
tags/1.0.0
Ilya Etingof 1 month ago
parent
commit
46e50fb56f

+ 2
- 1
ironic_prometheus_exporter/messaging.py View File

@@ -14,6 +14,7 @@ import logging
14 14
 import os
15 15
 
16 16
 from ironic_prometheus_exporter.parsers import ipmi
17
+from ironic_prometheus_exporter.parsers import header
17 18
 from oslo_config import cfg
18 19
 from oslo_messaging.notify import notifier
19 20
 from prometheus_client import write_to_textfile, CollectorRegistry
@@ -45,7 +46,7 @@ class PrometheusFileDriver(notifier.Driver):
45 46
             if message['event_type'] == 'hardware.ipmi.metrics':
46 47
                 registry = CollectorRegistry()
47 48
                 node_message = message['payload']
48
-                ipmi.timestamp_registry(node_message, registry)
49
+                header.timestamp_registry(node_message, registry)
49 50
                 ipmi.category_registry(node_message, registry)
50 51
                 nodeFile = os.path.join(self.location,
51 52
                                         node_message['node_name'])

+ 28
- 0
ironic_prometheus_exporter/parsers/header.py View File

@@ -0,0 +1,28 @@
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 datetime import datetime
14
+from prometheus_client import Gauge
15
+
16
+
17
+def timestamp_registry(node_information, ipmi_metric_registry):
18
+    metric = 'baremetal_last_payload_timestamp_seconds'
19
+    labels = {'node_name': node_information['node_name'],
20
+              'node_uuid': node_information['node_uuid'],
21
+              'instance_uuid': node_information['instance_uuid']}
22
+    dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
23
+    dt_timestamp = datetime.strptime(node_information['timestamp'],
24
+                                     '%Y-%m-%dT%H:%M:%S.%f')
25
+    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)
28
+    g.labels(**labels).set(value)

+ 0
- 15
ironic_prometheus_exporter/parsers/ipmi.py View File

@@ -15,7 +15,6 @@ import logging
15 15
 import pkg_resources
16 16
 import re
17 17
 
18
-from datetime import datetime
19 18
 from prometheus_client import Gauge
20 19
 
21 20
 # NOTE (iurygregory): most of the sensor readings come in the ipmi format
@@ -243,19 +242,5 @@ def category_registry(node_message, ipmi_metric_registry):
243 242
                               available_metrics)
244 243
 
245 244
 
246
-def timestamp_registry(node_information, ipmi_metric_registry):
247
-    metric = 'baremetal_last_payload_timestamp_seconds'
248
-    labels = {'node_name': node_information['node_name'],
249
-              'node_uuid': node_information['node_uuid'],
250
-              'instance_uuid': node_information['instance_uuid']}
251
-    dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
252
-    dt_timestamp = datetime.strptime(node_information['timestamp'],
253
-                                     '%Y-%m-%dT%H:%M:%S.%f')
254
-    value = int((dt_timestamp - dt_1970).total_seconds())
255
-    g = Gauge(metric, get_metric_description(metric),
256
-              labelnames=list(labels), registry=ipmi_metric_registry)
257
-    g.labels(**labels).set(value)
258
-
259
-
260 245
 def get_metric_description(metric_name):
261 246
     return IPMI_METRICS_DESCRIPTION.get(metric_name, '')

+ 17
- 0
ironic_prometheus_exporter/tests/json_samples/notification-header.json View File

@@ -0,0 +1,17 @@
1
+{
2
+    "priority": "INFO",
3
+    "event_type": "hardware.redfish.metrics",
4
+    "timestamp": "2019-03-29 20:12:26.885347",
5
+    "publisher_id": "None.localhost.localdomain",
6
+    "payload": {
7
+        "instance_uuid": "ac2aa2fd-6e1a-41c8-a114-2084c8705228",
8
+        "node_uuid": "ac2aa2fd-6e1a-41c8-a114-2084c8705228",
9
+        "event_type": "hardware.redfish.metrics.update",
10
+        "timestamp": "2019-03-29T20:12:22.989020",
11
+        "node_name": "knilab-master-u9",
12
+        "message_id": "85d6b2c8-fe57-432d-868a-330e0e28cf34",
13
+        "payload": {
14
+        }
15
+    },
16
+    "message_id": "2c0da1e8-1958-484f-9bdd-9117d717f7fa"
17
+}

+ 48
- 0
ironic_prometheus_exporter/tests/test_header_parser.py View File

@@ -0,0 +1,48 @@
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
+import json
14
+import os
15
+import unittest
16
+
17
+import ironic_prometheus_exporter
18
+from ironic_prometheus_exporter.parsers import header
19
+from prometheus_client import CollectorRegistry
20
+
21
+
22
+sample_file = os.path.join(
23
+    os.path.dirname(ironic_prometheus_exporter.__file__),
24
+    'tests', 'json_samples', 'notification-header.json')
25
+
26
+DATA = json.load(open(sample_file))
27
+
28
+
29
+class TestPayloadsParser(unittest.TestCase):
30
+
31
+    def setUp(self):
32
+        self.node_message = DATA['payload']
33
+        self.node_name = DATA['payload']['node_name']
34
+        self.node_uuid = DATA['payload']['node_uuid']
35
+        self.instance_uuid = DATA['payload']['instance_uuid']
36
+        self.timestamp = DATA['payload']['timestamp']
37
+        self.payload = DATA['payload']['payload']
38
+        self.metric_registry = CollectorRegistry()
39
+
40
+    def test_timestamp_metric(self):
41
+        header.timestamp_registry(self.node_message, self.metric_registry)
42
+
43
+        self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
44
+            'baremetal_last_payload_timestamp_seconds',
45
+            {'node_name': self.node_name,
46
+             'node_uuid': self.node_uuid,
47
+             'instance_uuid': self.instance_uuid}
48
+        ))

+ 0
- 10
ironic_prometheus_exporter/tests/test_ipmi_parser.py View File

@@ -559,16 +559,6 @@ class TestPayloadsParser(unittest.TestCase):
559 559
              'entity_id': '7.1 (System Board)',
560 560
              'status': 'ok'}))
561 561
 
562
-    def test_timestamp_metric(self):
563
-        ipmi.timestamp_registry(self.node_message, self.metric_registry)
564
-
565
-        self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
566
-            'baremetal_last_payload_timestamp_seconds',
567
-            {'node_name': self.node_name,
568
-             'node_uuid': self.node_uuid,
569
-             'instance_uuid': self.instance_uuid}
570
-        ))
571
-
572 562
     def test_voltage_manager(self):
573 563
         voltage_category_info = ipmi.CATEGORY_PARAMS['voltage'].copy()
574 564
         voltage_category_info['data'] = \

Loading…
Cancel
Save