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 5 months ago
parent
commit
46e50fb56f
6 changed files with 95 additions and 26 deletions
  1. +2
    -1
      ironic_prometheus_exporter/messaging.py
  2. +28
    -0
      ironic_prometheus_exporter/parsers/header.py
  3. +0
    -15
      ironic_prometheus_exporter/parsers/ipmi.py
  4. +17
    -0
      ironic_prometheus_exporter/tests/json_samples/notification-header.json
  5. +48
    -0
      ironic_prometheus_exporter/tests/test_header_parser.py
  6. +0
    -10
      ironic_prometheus_exporter/tests/test_ipmi_parser.py

+ 2
- 1
ironic_prometheus_exporter/messaging.py View File

@@ -14,6 +14,7 @@ import logging
import os

from ironic_prometheus_exporter.parsers import ipmi
from ironic_prometheus_exporter.parsers import header
from oslo_config import cfg
from oslo_messaging.notify import notifier
from prometheus_client import write_to_textfile, CollectorRegistry
@@ -45,7 +46,7 @@ class PrometheusFileDriver(notifier.Driver):
if message['event_type'] == 'hardware.ipmi.metrics':
registry = CollectorRegistry()
node_message = message['payload']
ipmi.timestamp_registry(node_message, registry)
header.timestamp_registry(node_message, registry)
ipmi.category_registry(node_message, registry)
nodeFile = os.path.join(self.location,
node_message['node_name'])

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

@@ -0,0 +1,28 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from datetime import datetime
from prometheus_client import Gauge


def timestamp_registry(node_information, ipmi_metric_registry):
metric = 'baremetal_last_payload_timestamp_seconds'
labels = {'node_name': node_information['node_name'],
'node_uuid': node_information['node_uuid'],
'instance_uuid': node_information['instance_uuid']}
dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
dt_timestamp = datetime.strptime(node_information['timestamp'],
'%Y-%m-%dT%H:%M:%S.%f')
value = int((dt_timestamp - dt_1970).total_seconds())
g = Gauge(metric, 'Timestamp of the last received payload',
labelnames=labels.keys(), registry=ipmi_metric_registry)
g.labels(**labels).set(value)

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

@@ -15,7 +15,6 @@ import logging
import pkg_resources
import re

from datetime import datetime
from prometheus_client import Gauge

# NOTE (iurygregory): most of the sensor readings come in the ipmi format
@@ -243,19 +242,5 @@ def category_registry(node_message, ipmi_metric_registry):
available_metrics)


def timestamp_registry(node_information, ipmi_metric_registry):
metric = 'baremetal_last_payload_timestamp_seconds'
labels = {'node_name': node_information['node_name'],
'node_uuid': node_information['node_uuid'],
'instance_uuid': node_information['instance_uuid']}
dt_1970 = datetime(1970, 1, 1, 0, 0, 0)
dt_timestamp = datetime.strptime(node_information['timestamp'],
'%Y-%m-%dT%H:%M:%S.%f')
value = int((dt_timestamp - dt_1970).total_seconds())
g = Gauge(metric, get_metric_description(metric),
labelnames=list(labels), registry=ipmi_metric_registry)
g.labels(**labels).set(value)


def get_metric_description(metric_name):
return IPMI_METRICS_DESCRIPTION.get(metric_name, '')

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

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

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

@@ -0,0 +1,48 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import json
import os
import unittest

import ironic_prometheus_exporter
from ironic_prometheus_exporter.parsers import header
from prometheus_client import CollectorRegistry


sample_file = os.path.join(
os.path.dirname(ironic_prometheus_exporter.__file__),
'tests', 'json_samples', 'notification-header.json')

DATA = json.load(open(sample_file))


class TestPayloadsParser(unittest.TestCase):

def setUp(self):
self.node_message = DATA['payload']
self.node_name = DATA['payload']['node_name']
self.node_uuid = DATA['payload']['node_uuid']
self.instance_uuid = DATA['payload']['instance_uuid']
self.timestamp = DATA['payload']['timestamp']
self.payload = DATA['payload']['payload']
self.metric_registry = CollectorRegistry()

def test_timestamp_metric(self):
header.timestamp_registry(self.node_message, self.metric_registry)

self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
'baremetal_last_payload_timestamp_seconds',
{'node_name': self.node_name,
'node_uuid': self.node_uuid,
'instance_uuid': self.instance_uuid}
))

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

@@ -559,16 +559,6 @@ class TestPayloadsParser(unittest.TestCase):
'entity_id': '7.1 (System Board)',
'status': 'ok'}))

def test_timestamp_metric(self):
ipmi.timestamp_registry(self.node_message, self.metric_registry)

self.assertEqual(1553890342.0, self.metric_registry.get_sample_value(
'baremetal_last_payload_timestamp_seconds',
{'node_name': self.node_name,
'node_uuid': self.node_uuid,
'instance_uuid': self.instance_uuid}
))

def test_voltage_manager(self):
voltage_category_info = ipmi.CATEGORY_PARAMS['voltage'].copy()
voltage_category_info['data'] = \

Loading…
Cancel
Save