xref: /openbmc/telemetry/src/report_factory.cpp (revision 8069771c0db62887b72aa2b8c51cd64eb5f99b2d)
1 #include "report_factory.hpp"
2 
3 #include "metric.hpp"
4 #include "report.hpp"
5 #include "sensor.hpp"
6 #include "utils/clock.hpp"
7 #include "utils/conversion.hpp"
8 #include "utils/dbus_mapper.hpp"
9 #include "utils/transform.hpp"
10 
11 ReportFactory::ReportFactory(
12     std::shared_ptr<sdbusplus::asio::connection> bus,
13     const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
14     SensorCache& sensorCache) :
15     bus(std::move(bus)),
16     objServer(objServer), sensorCache(sensorCache)
17 {}
18 
19 std::unique_ptr<interfaces::Report> ReportFactory::make(
20     const std::string& name, const std::string& reportingType,
21     bool emitsReadingsSignal, bool logToMetricReportsCollection,
22     Milliseconds period, interfaces::ReportManager& reportManager,
23     interfaces::JsonStorage& reportStorage,
24     std::vector<LabeledMetricParameters> labeledMetricParams) const
25 {
26     std::vector<std::shared_ptr<interfaces::Metric>> metrics = utils::transform(
27         labeledMetricParams,
28         [this](const LabeledMetricParameters& param)
29             -> std::shared_ptr<interfaces::Metric> {
30             namespace ts = utils::tstring;
31 
32             return std::make_shared<Metric>(
33                 getSensors(param.at_label<ts::SensorPath>()),
34                 param.at_label<ts::OperationType>(), param.at_label<ts::Id>(),
35                 param.at_label<ts::MetricMetadata>(),
36                 param.at_label<ts::CollectionTimeScope>(),
37                 param.at_label<ts::CollectionDuration>(),
38                 std::make_unique<Clock>());
39         });
40 
41     return std::make_unique<Report>(
42         bus->get_io_context(), objServer, name, reportingType,
43         emitsReadingsSignal, logToMetricReportsCollection, period,
44         reportManager, reportStorage, std::move(metrics));
45 }
46 
47 Sensors ReportFactory::getSensors(
48     const std::vector<LabeledSensorParameters>& sensorPaths) const
49 {
50     using namespace utils::tstring;
51 
52     return utils::transform(sensorPaths,
53                             [this](const LabeledSensorParameters& sensorPath)
54                                 -> std::shared_ptr<interfaces::Sensor> {
55                                 return sensorCache.makeSensor<Sensor>(
56                                     sensorPath.at_label<Service>(),
57                                     sensorPath.at_label<Path>(),
58                                     bus->get_io_context(), bus);
59                             });
60 }
61 
62 std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
63     boost::asio::yield_context& yield,
64     const ReadingParameters& metricParams) const
65 {
66     auto tree = utils::getSubTreeSensors(yield, bus);
67 
68     return utils::transform(metricParams, [&tree](const auto& item) {
69         const auto& [sensorPaths, operationType, id, metadata,
70                      collectionTimeScope, collectionDuration] = item;
71 
72         std::vector<LabeledSensorParameters> sensorParameters;
73 
74         for (const auto& sensorPath : sensorPaths)
75         {
76             auto it = std::find_if(
77                 tree.begin(), tree.end(),
78                 [&sensorPath](const auto& v) { return v.first == sensorPath; });
79 
80             if (it != tree.end() && it->second.size() == 1)
81             {
82                 const auto& [service, ifaces] = it->second.front();
83                 sensorParameters.emplace_back(service, sensorPath);
84             }
85         }
86 
87         if (sensorParameters.size() != sensorPaths.size())
88         {
89             throw sdbusplus::exception::SdBusError(
90                 static_cast<int>(std::errc::invalid_argument),
91                 "Could not find service for provided sensors");
92         }
93 
94         return LabeledMetricParameters(
95             std::move(sensorParameters),
96             utils::stringToOperationType(operationType), id, metadata,
97             utils::stringToCollectionTimeScope(collectionTimeScope),
98             CollectionDuration(Milliseconds(collectionDuration)));
99     });
100 }
101