xref: /openbmc/telemetry/src/metric.cpp (revision 3a617023eacf8a7fcc49e15d5767b35f47c7c089)
1c8e3a64aSKrzysztof Grobelny #include "metric.hpp"
26ccfcbf5SKrzysztof Grobelny 
3dcc4e193SKrzysztof Grobelny #include "types/report_types.hpp"
4*3a617023SSzymon Dompke #include "utils/labeled_tuple.hpp"
56ccfcbf5SKrzysztof Grobelny #include "utils/transform.hpp"
66ccfcbf5SKrzysztof Grobelny 
76ccfcbf5SKrzysztof Grobelny #include <algorithm>
86ccfcbf5SKrzysztof Grobelny 
9dcc4e193SKrzysztof Grobelny Metric::Metric(Sensors sensorsIn, OperationType operationTypeIn,
10dcc4e193SKrzysztof Grobelny                std::string idIn, std::string metadataIn,
11dcc4e193SKrzysztof Grobelny                CollectionTimeScope timeScopeIn,
12dcc4e193SKrzysztof Grobelny                CollectionDuration collectionDurationIn) :
13dcc4e193SKrzysztof Grobelny     id(idIn),
14dcc4e193SKrzysztof Grobelny     metadata(metadataIn),
15dcc4e193SKrzysztof Grobelny     readings(sensorsIn.size(),
16dcc4e193SKrzysztof Grobelny              MetricValue{std::move(idIn), std::move(metadataIn), 0., 0u}),
17dcc4e193SKrzysztof Grobelny     sensors(std::move(sensorsIn)), operationType(operationTypeIn),
18dcc4e193SKrzysztof Grobelny     timeScope(timeScopeIn), collectionDuration(collectionDurationIn)
19dcc4e193SKrzysztof Grobelny {
20dcc4e193SKrzysztof Grobelny     tryUnpackJsonMetadata();
21dcc4e193SKrzysztof Grobelny }
226ccfcbf5SKrzysztof Grobelny 
236ccfcbf5SKrzysztof Grobelny void Metric::initialize()
246ccfcbf5SKrzysztof Grobelny {
25dcc4e193SKrzysztof Grobelny     for (const auto& sensor : sensors)
26dcc4e193SKrzysztof Grobelny     {
276ccfcbf5SKrzysztof Grobelny         sensor->registerForUpdates(weak_from_this());
286ccfcbf5SKrzysztof Grobelny     }
29dcc4e193SKrzysztof Grobelny }
30e8fc5751SKrzysztof Grobelny 
31dcc4e193SKrzysztof Grobelny const std::vector<MetricValue>& Metric::getReadings() const
32e8fc5751SKrzysztof Grobelny {
33dcc4e193SKrzysztof 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 {
52dcc4e193SKrzysztof Grobelny     auto it = std::find_if(
53dcc4e193SKrzysztof Grobelny         sensors.begin(), sensors.end(),
54dcc4e193SKrzysztof Grobelny         [&notifier](const auto& sensor) { return sensor.get() == &notifier; });
55dcc4e193SKrzysztof Grobelny     auto index = std::distance(sensors.begin(), it);
56dcc4e193SKrzysztof Grobelny     return readings.at(index);
576ccfcbf5SKrzysztof Grobelny }
586ccfcbf5SKrzysztof Grobelny 
59d2238194SKrzysztof Grobelny LabeledMetricParameters Metric::dumpConfiguration() const
606ccfcbf5SKrzysztof Grobelny {
61dcc4e193SKrzysztof Grobelny     auto sensorPath = utils::transform(sensors, [this](const auto& sensor) {
62dcc4e193SKrzysztof Grobelny         return LabeledSensorParameters(sensor->id().service, sensor->id().path);
63dcc4e193SKrzysztof Grobelny     });
64dcc4e193SKrzysztof Grobelny 
65dcc4e193SKrzysztof Grobelny     return LabeledMetricParameters(std::move(sensorPath), operationType, id,
66dcc4e193SKrzysztof Grobelny                                    metadata, timeScope, collectionDuration);
67dcc4e193SKrzysztof Grobelny }
68dcc4e193SKrzysztof Grobelny 
69dcc4e193SKrzysztof Grobelny void Metric::tryUnpackJsonMetadata()
70dcc4e193SKrzysztof Grobelny {
71*3a617023SSzymon Dompke     using MetricMetadata =
72*3a617023SSzymon Dompke         utils::LabeledTuple<std::tuple<std::vector<std::string>>,
73*3a617023SSzymon Dompke                             utils::tstring::MetricProperties>;
74*3a617023SSzymon Dompke 
75*3a617023SSzymon Dompke     using ReadingMetadata =
76*3a617023SSzymon Dompke         utils::LabeledTuple<std::tuple<std::string, std::string>,
77*3a617023SSzymon Dompke                             utils::tstring::SensorDbusPath,
78*3a617023SSzymon Dompke                             utils::tstring::SensorRedfishUri>;
79dcc4e193SKrzysztof Grobelny     try
80dcc4e193SKrzysztof Grobelny     {
81*3a617023SSzymon Dompke         const MetricMetadata parsedMetadata =
82*3a617023SSzymon Dompke             nlohmann::json::parse(metadata).get<MetricMetadata>();
83*3a617023SSzymon Dompke 
84*3a617023SSzymon Dompke         if (readings.size() == parsedMetadata.at_index<0>().size())
85dcc4e193SKrzysztof Grobelny         {
86dcc4e193SKrzysztof Grobelny             for (size_t i = 0; i < readings.size(); ++i)
87dcc4e193SKrzysztof Grobelny             {
88*3a617023SSzymon Dompke                 ReadingMetadata readingMetadata{
89*3a617023SSzymon Dompke                     sensors[i]->id().path, parsedMetadata.at_index<0>()[i]};
90*3a617023SSzymon Dompke                 readings[i].metadata = readingMetadata.dump();
91dcc4e193SKrzysztof Grobelny             }
92dcc4e193SKrzysztof Grobelny         }
93dcc4e193SKrzysztof Grobelny     }
94*3a617023SSzymon Dompke     catch (const nlohmann::json::parse_error&)
95dcc4e193SKrzysztof Grobelny     {}
966ccfcbf5SKrzysztof Grobelny }
97