xref: /openbmc/telemetry/src/trigger.cpp (revision dcc4e1936173a93251a02066432bc2bcbc386240)
1 #include "trigger.hpp"
2 
3 #include "types/report_types.hpp"
4 #include "types/trigger_types.hpp"
5 #include "utils/conversion_trigger.hpp"
6 #include "utils/transform.hpp"
7 
8 #include <phosphor-logging/log.hpp>
9 
10 Trigger::Trigger(
11     boost::asio::io_context& ioc,
12     const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
13     const std::string& nameIn, const bool isDiscreteIn,
14     const bool logToJournalIn, const bool logToRedfishIn,
15     const bool updateReportIn, const std::vector<std::string>& reportNamesIn,
16     const std::vector<LabeledSensorInfo>& LabeledSensorsInfoIn,
17     const LabeledTriggerThresholdParams& labeledThresholdParamsIn,
18     std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
19     interfaces::TriggerManager& triggerManager,
20     interfaces::JsonStorage& triggerStorageIn) :
21     name(nameIn),
22     isDiscrete(isDiscreteIn), logToJournal(logToJournalIn),
23     logToRedfish(logToRedfishIn), updateReport(updateReportIn),
24     path(triggerDir + name), reportNames(reportNamesIn),
25     labeledSensorsInfo(LabeledSensorsInfoIn),
26     labeledThresholdParams(labeledThresholdParamsIn),
27     thresholds(std::move(thresholdsIn)),
28     fileName(std::to_string(std::hash<std::string>{}(name))),
29     triggerStorage(triggerStorageIn)
30 {
31     deleteIface = objServer->add_unique_interface(
32         path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
33             dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
34                 if (persistent)
35                 {
36                     triggerStorage.remove(fileName);
37                 }
38                 boost::asio::post(ioc, [this, &triggerManager] {
39                     triggerManager.removeTrigger(this);
40                 });
41             });
42         });
43 
44     triggerIface = objServer->add_unique_interface(
45         path, triggerIfaceName,
46         [this, isDiscreteIn, logToJournalIn, logToRedfishIn,
47          updateReportIn](auto& dbusIface) {
48             persistent = storeConfiguration();
49             dbusIface.register_property_rw(
50                 "Persistent", persistent,
51                 sdbusplus::vtable::property_::emits_change,
52                 [this](bool newVal, const auto&) {
53                     if (newVal == persistent)
54                     {
55                         return true;
56                     }
57                     if (newVal)
58                     {
59                         persistent = storeConfiguration();
60                     }
61                     else
62                     {
63                         triggerStorage.remove(fileName);
64                         persistent = false;
65                     }
66                     return true;
67                 },
68                 [this](const auto&) { return persistent; });
69 
70             dbusIface.register_property_r(
71                 "Thresholds", TriggerThresholdParams{},
72                 sdbusplus::vtable::property_::emits_change,
73                 [this](const auto&) {
74                     return std::visit(
75                         utils::FromLabeledThresholdParamConversion(),
76                         labeledThresholdParams);
77                 });
78 
79             dbusIface.register_property_r(
80                 "Sensors", SensorsInfo{},
81                 sdbusplus::vtable::property_::emits_change,
82                 [this](const auto&) {
83                     return utils::fromLabeledSensorsInfo(labeledSensorsInfo);
84                 });
85 
86             dbusIface.register_property_r(
87 
88                 "ReportNames", reportNames,
89                 sdbusplus::vtable::property_::emits_change,
90                 [](const auto& x) { return x; });
91             dbusIface.register_property_r("Discrete", isDiscrete,
92                                           sdbusplus::vtable::property_::const_,
93                                           [](const auto& x) { return x; });
94             dbusIface.register_property_r("LogToJournal", logToJournal,
95                                           sdbusplus::vtable::property_::const_,
96                                           [](const auto& x) { return x; });
97             dbusIface.register_property_r("LogToRedfish", logToRedfish,
98                                           sdbusplus::vtable::property_::const_,
99                                           [](const auto& x) { return x; });
100             dbusIface.register_property_r("UpdateReport", updateReport,
101                                           sdbusplus::vtable::property_::const_,
102                                           [](const auto& x) { return x; });
103         });
104 
105     for (const auto& threshold : thresholds)
106     {
107         threshold->initialize();
108     }
109 }
110 
111 bool Trigger::storeConfiguration() const
112 {
113     try
114     {
115         nlohmann::json data;
116 
117         data["Version"] = triggerVersion;
118         data["Name"] = name;
119         data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
120         data["IsDiscrete"] = labeledThresholdParams.index() == 1;
121         data["LogToJournal"] = logToJournal;
122         data["LogToRedfish"] = logToRedfish;
123         data["UpdateReport"] = updateReport;
124         data["ThresholdParams"] =
125             utils::labeledThresholdParamsToJson(labeledThresholdParams);
126         data["ReportNames"] = reportNames;
127         data["Sensors"] = labeledSensorsInfo;
128 
129         triggerStorage.store(fileName, data);
130     }
131     catch (const std::exception& e)
132     {
133         phosphor::logging::log<phosphor::logging::level::ERR>(
134             "Failed to store a trigger in storage",
135             phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
136         return false;
137     }
138     return true;
139 }
140