xref: /openbmc/telemetry/src/report_factory.cpp (revision b8cc78ddf9cc87c83176c7bda575ceef2678d00f)
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& id, const std::string& name,
21     const ReportingType reportingType,
22     const std::vector<ReportAction>& reportActions, Milliseconds period,
23     uint64_t appendLimit, const ReportUpdates reportUpdates,
24     interfaces::ReportManager& reportManager,
25     interfaces::JsonStorage& reportStorage,
26     std::vector<LabeledMetricParameters> labeledMetricParams,
27     bool enabled) const
28 {
29     std::vector<std::shared_ptr<interfaces::Metric>> metrics = utils::transform(
30         labeledMetricParams,
31         [this](const LabeledMetricParameters& param)
32             -> std::shared_ptr<interfaces::Metric> {
33             namespace ts = utils::tstring;
34 
35             return std::make_shared<Metric>(
36                 getSensors(param.at_label<ts::SensorPath>()),
37                 param.at_label<ts::OperationType>(), param.at_label<ts::Id>(),
38                 param.at_label<ts::CollectionTimeScope>(),
39                 param.at_label<ts::CollectionDuration>(),
40                 std::make_unique<Clock>());
41         });
42 
43     return std::make_unique<Report>(bus->get_io_context(), objServer, id, name,
44                                     reportingType, reportActions, period,
45                                     appendLimit, reportUpdates, reportManager,
46                                     reportStorage, std::move(metrics), enabled);
47 }
48 
49 Sensors ReportFactory::getSensors(
50     const std::vector<LabeledSensorParameters>& sensorPaths) const
51 {
52     using namespace utils::tstring;
53 
54     return utils::transform(
55         sensorPaths,
56         [this](const LabeledSensorParameters& sensorPath)
57             -> std::shared_ptr<interfaces::Sensor> {
58             return sensorCache.makeSensor<Sensor>(
59                 sensorPath.at_label<Service>(), sensorPath.at_label<Path>(),
60                 sensorPath.at_label<Metadata>(), bus->get_io_context(), bus);
61         });
62 }
63 
64 std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
65     boost::asio::yield_context& yield,
66     const ReadingParameters& metricParams) const
67 {
68     auto tree = utils::getSubTreeSensors(yield, bus);
69 
70     return utils::transform(metricParams, [&tree](const auto& item) {
71         auto [sensorPaths, operationType, id, collectionTimeScope,
72               collectionDuration] = item;
73 
74         std::vector<LabeledSensorParameters> sensorParameters;
75 
76         for (const auto& [sensorPath, metadata] : sensorPaths)
77         {
78             auto it = std::find_if(
79                 tree.begin(), tree.end(),
80                 [&sensorPath](const auto& v) { return v.first == sensorPath; });
81 
82             if (it != tree.end() && it->second.size() == 1)
83             {
84                 const auto& [service, ifaces] = it->second.front();
85                 sensorParameters.emplace_back(service, sensorPath, metadata);
86             }
87         }
88 
89         if (sensorParameters.size() != sensorPaths.size())
90         {
91             throw sdbusplus::exception::SdBusError(
92                 static_cast<int>(std::errc::invalid_argument),
93                 "Could not find service for provided sensors");
94         }
95 
96         if (operationType.empty())
97         {
98             operationType = utils::enumToString(OperationType::avg);
99         }
100 
101         if (collectionTimeScope.empty())
102         {
103             collectionTimeScope =
104                 utils::enumToString(CollectionTimeScope::point);
105         }
106 
107         return LabeledMetricParameters(
108             std::move(sensorParameters), utils::toOperationType(operationType),
109             id, utils::toCollectionTimeScope(collectionTimeScope),
110             CollectionDuration(Milliseconds(collectionDuration)));
111     });
112 }
113