xref: /openbmc/telemetry/src/metric.cpp (revision dcc4e1936173a93251a02066432bc2bcbc386240)
1c8e3a64aSKrzysztof Grobelny #include "metric.hpp"
26ccfcbf5SKrzysztof Grobelny 
3*dcc4e193SKrzysztof Grobelny #include "types/report_types.hpp"
4*dcc4e193SKrzysztof Grobelny #include "utils/json.hpp"
56ccfcbf5SKrzysztof Grobelny #include "utils/transform.hpp"
66ccfcbf5SKrzysztof Grobelny 
76ccfcbf5SKrzysztof Grobelny #include <algorithm>
86ccfcbf5SKrzysztof Grobelny 
9*dcc4e193SKrzysztof Grobelny Metric::Metric(Sensors sensorsIn, OperationType operationTypeIn,
10*dcc4e193SKrzysztof Grobelny                std::string idIn, std::string metadataIn,
11*dcc4e193SKrzysztof Grobelny                CollectionTimeScope timeScopeIn,
12*dcc4e193SKrzysztof Grobelny                CollectionDuration collectionDurationIn) :
13*dcc4e193SKrzysztof Grobelny     id(idIn),
14*dcc4e193SKrzysztof Grobelny     metadata(metadataIn),
15*dcc4e193SKrzysztof Grobelny     readings(sensorsIn.size(),
16*dcc4e193SKrzysztof Grobelny              MetricValue{std::move(idIn), std::move(metadataIn), 0., 0u}),
17*dcc4e193SKrzysztof Grobelny     sensors(std::move(sensorsIn)), operationType(operationTypeIn),
18*dcc4e193SKrzysztof Grobelny     timeScope(timeScopeIn), collectionDuration(collectionDurationIn)
19*dcc4e193SKrzysztof Grobelny {
20*dcc4e193SKrzysztof Grobelny     tryUnpackJsonMetadata();
21*dcc4e193SKrzysztof Grobelny }
226ccfcbf5SKrzysztof Grobelny 
236ccfcbf5SKrzysztof Grobelny void Metric::initialize()
246ccfcbf5SKrzysztof Grobelny {
25*dcc4e193SKrzysztof Grobelny     for (const auto& sensor : sensors)
26*dcc4e193SKrzysztof Grobelny     {
276ccfcbf5SKrzysztof Grobelny         sensor->registerForUpdates(weak_from_this());
286ccfcbf5SKrzysztof Grobelny     }
29*dcc4e193SKrzysztof Grobelny }
30e8fc5751SKrzysztof Grobelny 
31*dcc4e193SKrzysztof Grobelny const std::vector<MetricValue>& Metric::getReadings() const
32e8fc5751SKrzysztof Grobelny {
33*dcc4e193SKrzysztof Grobelny     return readings;
346ccfcbf5SKrzysztof Grobelny }
356ccfcbf5SKrzysztof Grobelny 
36e8fc5751SKrzysztof Grobelny void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp)
376ccfcbf5SKrzysztof Grobelny {
38e8fc5751SKrzysztof Grobelny     MetricValue& mv = findMetric(notifier);
396ccfcbf5SKrzysztof Grobelny     mv.timestamp = timestamp;
406ccfcbf5SKrzysztof Grobelny }
416ccfcbf5SKrzysztof Grobelny 
42e8fc5751SKrzysztof Grobelny void Metric::sensorUpdated(interfaces::Sensor& notifier, uint64_t timestamp,
436ccfcbf5SKrzysztof Grobelny                            double value)
446ccfcbf5SKrzysztof Grobelny {
45e8fc5751SKrzysztof Grobelny     MetricValue& mv = findMetric(notifier);
466ccfcbf5SKrzysztof Grobelny     mv.timestamp = timestamp;
476ccfcbf5SKrzysztof Grobelny     mv.value = value;
486ccfcbf5SKrzysztof Grobelny }
496ccfcbf5SKrzysztof Grobelny 
50e8fc5751SKrzysztof Grobelny MetricValue& Metric::findMetric(interfaces::Sensor& notifier)
516ccfcbf5SKrzysztof Grobelny {
52*dcc4e193SKrzysztof Grobelny     auto it = std::find_if(
53*dcc4e193SKrzysztof Grobelny         sensors.begin(), sensors.end(),
54*dcc4e193SKrzysztof Grobelny         [&notifier](const auto& sensor) { return sensor.get() == &notifier; });
55*dcc4e193SKrzysztof Grobelny     auto index = std::distance(sensors.begin(), it);
56*dcc4e193SKrzysztof Grobelny     return readings.at(index);
576ccfcbf5SKrzysztof Grobelny }
586ccfcbf5SKrzysztof Grobelny 
59d2238194SKrzysztof Grobelny LabeledMetricParameters Metric::dumpConfiguration() const
606ccfcbf5SKrzysztof Grobelny {
61*dcc4e193SKrzysztof Grobelny     auto sensorPath = utils::transform(sensors, [this](const auto& sensor) {
62*dcc4e193SKrzysztof Grobelny         return LabeledSensorParameters(sensor->id().service, sensor->id().path);
63*dcc4e193SKrzysztof Grobelny     });
64*dcc4e193SKrzysztof Grobelny 
65*dcc4e193SKrzysztof Grobelny     return LabeledMetricParameters(std::move(sensorPath), operationType, id,
66*dcc4e193SKrzysztof Grobelny                                    metadata, timeScope, collectionDuration);
67*dcc4e193SKrzysztof Grobelny }
68*dcc4e193SKrzysztof Grobelny 
69*dcc4e193SKrzysztof Grobelny void Metric::tryUnpackJsonMetadata()
70*dcc4e193SKrzysztof Grobelny {
71*dcc4e193SKrzysztof Grobelny     try
72*dcc4e193SKrzysztof Grobelny     {
73*dcc4e193SKrzysztof Grobelny         const nlohmann::json parsedMetadata = nlohmann::json::parse(metadata);
74*dcc4e193SKrzysztof Grobelny         if (const auto metricProperties =
75*dcc4e193SKrzysztof Grobelny                 utils::readJson<std::vector<std::string>>(parsedMetadata,
76*dcc4e193SKrzysztof Grobelny                                                           "MetricProperties"))
77*dcc4e193SKrzysztof Grobelny         {
78*dcc4e193SKrzysztof Grobelny             if (readings.size() == metricProperties->size())
79*dcc4e193SKrzysztof Grobelny             {
80*dcc4e193SKrzysztof Grobelny                 for (size_t i = 0; i < readings.size(); ++i)
81*dcc4e193SKrzysztof Grobelny                 {
82*dcc4e193SKrzysztof Grobelny                     readings[i].metadata = (*metricProperties)[i];
83*dcc4e193SKrzysztof Grobelny                 }
84*dcc4e193SKrzysztof Grobelny             }
85*dcc4e193SKrzysztof Grobelny         }
86*dcc4e193SKrzysztof Grobelny     }
87*dcc4e193SKrzysztof Grobelny     catch (const nlohmann::json::parse_error& e)
88*dcc4e193SKrzysztof Grobelny     {}
896ccfcbf5SKrzysztof Grobelny }
90