xref: /openbmc/telemetry/src/report_factory.cpp (revision d22381949a8705da399107fcff71f8fbfe910f46)
1 #include "report_factory.hpp"
2 
3 #include "metric.hpp"
4 #include "report.hpp"
5 #include "sensor.hpp"
6 #include "utils/transform.hpp"
7 
8 ReportFactory::ReportFactory(
9     std::shared_ptr<sdbusplus::asio::connection> bus,
10     const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
11     bus(std::move(bus)),
12     objServer(objServer)
13 {}
14 
15 std::unique_ptr<interfaces::Report> ReportFactory::make(
16     boost::asio::yield_context& yield, const std::string& name,
17     const std::string& reportingType, bool emitsReadingsSignal,
18     bool logToMetricReportsCollection, std::chrono::milliseconds period,
19     const ReadingParameters& metricParams,
20     interfaces::ReportManager& reportManager,
21     interfaces::JsonStorage& reportStorage) const
22 {
23     return make(name, reportingType, emitsReadingsSignal,
24                 logToMetricReportsCollection, period, metricParams,
25                 reportManager, reportStorage,
26                 convertMetricParams(yield, metricParams));
27 }
28 
29 std::unique_ptr<interfaces::Report> ReportFactory::make(
30     const std::string& name, const std::string& reportingType,
31     bool emitsReadingsSignal, bool logToMetricReportsCollection,
32     std::chrono::milliseconds period, const ReadingParameters& metricParams,
33     interfaces::ReportManager& reportManager,
34     interfaces::JsonStorage& reportStorage,
35     std::vector<LabeledMetricParameters> labeledMetricParams) const
36 {
37     std::vector<std::shared_ptr<interfaces::Metric>> metrics = utils::transform(
38         labeledMetricParams,
39         [this](const LabeledMetricParameters& param)
40             -> std::shared_ptr<interfaces::Metric> {
41             return std::make_shared<Metric>(
42                 getSensors(param.at_index<0>()), param.at_index<1>(),
43                 param.at_index<2>(), param.at_index<3>());
44         });
45 
46     return std::make_unique<Report>(
47         bus->get_io_context(), objServer, name, reportingType,
48         emitsReadingsSignal, logToMetricReportsCollection, period, metricParams,
49         reportManager, reportStorage, std::move(metrics));
50 }
51 
52 std::vector<std::shared_ptr<interfaces::Sensor>> ReportFactory::getSensors(
53     const std::vector<LabeledSensorParameters>& sensorPaths) const
54 {
55     return utils::transform(sensorPaths,
56                             [this](const LabeledSensorParameters& param)
57                                 -> std::shared_ptr<interfaces::Sensor> {
58                                 using namespace utils::tstring;
59 
60                                 return sensorCache.makeSensor<Sensor>(
61                                     param.at_label<Service>(),
62                                     param.at_label<Path>(),
63                                     bus->get_io_context(), bus);
64                             });
65 }
66 
67 std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
68     boost::asio::yield_context& yield,
69     const ReadingParameters& metricParams) const
70 {
71     std::array<const char*, 1> interfaces = {
72         "xyz.openbmc_project.Sensor.Value"};
73     boost::system::error_code ec;
74 
75     auto tree = bus->yield_method_call<std::vector<SensorTree>>(
76         yield, ec, "xyz.openbmc_project.ObjectMapper",
77         "/xyz/openbmc_project/object_mapper",
78         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
79         "/xyz/openbmc_project/sensors", 2, interfaces);
80     if (ec)
81     {
82         throw std::runtime_error("Failed to query ObjectMapper!");
83     }
84 
85     return utils::transform(metricParams, [&tree](const auto& item) {
86         std::vector<LabeledSensorParameters> sensors;
87 
88         for (const auto& sensorPath : std::get<0>(item))
89         {
90             auto it = std::find_if(
91                 tree.begin(), tree.end(),
92                 [&sensorPath](const auto& v) { return v.first == sensorPath; });
93 
94             if (it != tree.end())
95             {
96                 for (const auto& [service, ifaces] : it->second)
97                 {
98                     sensors.emplace_back(service, sensorPath);
99                 }
100             }
101         }
102 
103         return LabeledMetricParameters(std::move(sensors), std::get<1>(item),
104                                        std::get<2>(item), std::get<3>(item));
105     });
106 }
107