xref: /openbmc/telemetry/src/metric.cpp (revision dcc4e1936173a93251a02066432bc2bcbc386240)
1 #include "metric.hpp"
2 
3 #include "types/report_types.hpp"
4 #include "utils/json.hpp"
5 #include "utils/transform.hpp"
6 
7 #include <algorithm>
8 
9 Metric::Metric(Sensors sensorsIn, OperationType operationTypeIn,
10                std::string idIn, std::string metadataIn,
11                CollectionTimeScope timeScopeIn,
12                CollectionDuration collectionDurationIn) :
13     id(idIn),
14     metadata(metadataIn),
15     readings(sensorsIn.size(),
16              MetricValue{std::move(idIn), std::move(metadataIn), 0., 0u}),
17     sensors(std::move(sensorsIn)), operationType(operationTypeIn),
18     timeScope(timeScopeIn), collectionDuration(collectionDurationIn)
19 {
20     tryUnpackJsonMetadata();
21 }
22 
23 void Metric::initialize()
24 {
25     for (const auto& sensor : sensors)
26     {
27         sensor->registerForUpdates(weak_from_this());
28     }
29 }
30 
31 const std::vector<MetricValue>& Metric::getReadings() const
32 {
33     return readings;
34 }
35 
36 void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp)
37 {
38     MetricValue& mv = findMetric(notifier);
39     mv.timestamp = timestamp;
40 }
41 
42 void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp,
43                            double value)
44 {
45     MetricValue& mv = findMetric(notifier);
46     mv.timestamp = timestamp;
47     mv.value = value;
48 }
49 
50 MetricValue& Metric::findMetric(interfaces::Sensor& notifier)
51 {
52     auto it = std::find_if(
53         sensors.begin(), sensors.end(),
54         [&notifier](const auto& sensor) { return sensor.get() == &notifier; });
55     auto index = std::distance(sensors.begin(), it);
56     return readings.at(index);
57 }
58 
59 LabeledMetricParameters Metric::dumpConfiguration() const
60 {
61     auto sensorPath = utils::transform(sensors, [this](const auto& sensor) {
62         return LabeledSensorParameters(sensor->id().service, sensor->id().path);
63     });
64 
65     return LabeledMetricParameters(std::move(sensorPath), operationType, id,
66                                    metadata, timeScope, collectionDuration);
67 }
68 
69 void Metric::tryUnpackJsonMetadata()
70 {
71     try
72     {
73         const nlohmann::json parsedMetadata = nlohmann::json::parse(metadata);
74         if (const auto metricProperties =
75                 utils::readJson<std::vector<std::string>>(parsedMetadata,
76                                                           "MetricProperties"))
77         {
78             if (readings.size() == metricProperties->size())
79             {
80                 for (size_t i = 0; i < readings.size(); ++i)
81                 {
82                     readings[i].metadata = (*metricProperties)[i];
83                 }
84             }
85         }
86     }
87     catch (const nlohmann::json::parse_error& e)
88     {}
89 }
90