xref: /openbmc/telemetry/src/trigger_actions.cpp (revision 66db900fa95b28f8e5f4a313196026cc4d04cfed)
1 #include "trigger_actions.hpp"
2 
3 #include "messages/update_report_ind.hpp"
4 #include "types/trigger_types.hpp"
5 #include "utils/clock.hpp"
6 #include "utils/messanger.hpp"
7 #include "utils/to_short_enum.hpp"
8 
9 #include <phosphor-logging/log.hpp>
10 
11 #include <ctime>
12 #include <iomanip>
13 #include <sstream>
14 
15 namespace action
16 {
17 
18 namespace numeric
19 {
20 
getDirection(double value,double threshold)21 static const char* getDirection(double value, double threshold)
22 {
23     if (value < threshold)
24     {
25         return "decreasing";
26     }
27     if (value > threshold)
28     {
29         return "increasing";
30     }
31     throw std::runtime_error("Invalid value");
32 }
33 
getRedfishMessageId(const double value) const34 const char* LogToRedfishEventLog::getRedfishMessageId(const double value) const
35 {
36     std::string direction(getDirection(value, threshold));
37 
38     if (direction == "decreasing")
39     {
40         switch (type)
41         {
42             case ::numeric::Type::upperCritical:
43                 return redfish_message_ids::TriggerNumericBelowUpperCritical;
44             case ::numeric::Type::lowerCritical:
45                 return redfish_message_ids::TriggerNumericBelowLowerCritical;
46             case ::numeric::Type::upperWarning:
47                 return redfish_message_ids::TriggerNumericReadingNormal;
48             case ::numeric::Type::lowerWarning:
49                 return redfish_message_ids::TriggerNumericBelowLowerWarning;
50         }
51     }
52 
53     if (direction == "increasing")
54     {
55         switch (type)
56         {
57             case ::numeric::Type::upperCritical:
58                 return redfish_message_ids::TriggerNumericAboveUpperCritical;
59             case ::numeric::Type::lowerCritical:
60                 return redfish_message_ids::TriggerNumericAboveLowerCritical;
61             case ::numeric::Type::upperWarning:
62                 return redfish_message_ids::TriggerNumericAboveUpperWarning;
63             case ::numeric::Type::lowerWarning:
64                 return redfish_message_ids::TriggerNumericReadingNormal;
65         }
66     }
67 
68     throw std::runtime_error("Invalid type");
69 }
70 
commit(const std::string & triggerId,const ThresholdName thresholdNameInIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)71 void LogToRedfishEventLog::commit(
72     const std::string& triggerId, const ThresholdName thresholdNameInIn,
73     const std::string& sensorName, const Milliseconds timestamp,
74     const TriggerValue triggerValue)
75 {
76     double value = std::get<double>(triggerValue);
77     auto messageId = getRedfishMessageId(value);
78 
79     if (std::string_view(messageId) ==
80         redfish_message_ids::TriggerNumericReadingNormal)
81     {
82         phosphor::logging::log<phosphor::logging::level::INFO>(
83             "Logging numeric trigger action to Redfish Event Log.",
84             phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
85             phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%s",
86                                      sensorName.c_str(), value,
87                                      triggerId.c_str()));
88     }
89     else
90     {
91         phosphor::logging::log<phosphor::logging::level::INFO>(
92             "Logging numeric trigger action to Redfish Event Log.",
93             phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
94             phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%f,%s",
95                                      sensorName.c_str(), value, threshold,
96                                      triggerId.c_str()));
97     }
98 }
99 
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,::numeric::Type type,double thresholdValue,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)100 void fillActions(
101     std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
102     const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
103     double thresholdValue, boost::asio::io_context& ioc,
104     const std::shared_ptr<std::vector<std::string>>& reportIds)
105 {
106     actionsIf.reserve(ActionsEnum.size());
107     for (auto actionType : ActionsEnum)
108     {
109         switch (actionType)
110         {
111             case TriggerAction::LogToRedfishEventLog:
112             {
113                 actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
114                     type, thresholdValue));
115                 break;
116             }
117             case TriggerAction::UpdateReport:
118             {
119                 actionsIf.emplace_back(
120                     std::make_unique<UpdateReport>(ioc, reportIds));
121                 break;
122             }
123         }
124     }
125 }
126 
127 } // namespace numeric
128 
129 namespace discrete
130 {
131 
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)132 void LogToRedfishEventLog::commit(
133     const std::string& triggerId, const ThresholdName thresholdNameIn,
134     const std::string& sensorName, const Milliseconds timestamp,
135     const TriggerValue triggerValue)
136 {
137     auto value = std::get<std::string>(triggerValue);
138 
139     phosphor::logging::log<phosphor::logging::level::INFO>(
140         "Logging discrete trigger action to Redfish Event Log.",
141         phosphor::logging::entry(
142             "REDFISH_MESSAGE_ID=%s",
143             redfish_message_ids::TriggerDiscreteConditionMet),
144         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
145                                  sensorName.c_str(), value.c_str(),
146                                  triggerId.c_str()));
147 }
148 
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,::discrete::Severity severity,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)149 void fillActions(
150     std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
151     const std::vector<TriggerAction>& ActionsEnum,
152     ::discrete::Severity severity, boost::asio::io_context& ioc,
153     const std::shared_ptr<std::vector<std::string>>& reportIds)
154 {
155     actionsIf.reserve(ActionsEnum.size());
156     for (auto actionType : ActionsEnum)
157     {
158         switch (actionType)
159         {
160             case TriggerAction::LogToRedfishEventLog:
161             {
162                 actionsIf.emplace_back(
163                     std::make_unique<LogToRedfishEventLog>());
164                 break;
165             }
166             case TriggerAction::UpdateReport:
167             {
168                 actionsIf.emplace_back(
169                     std::make_unique<UpdateReport>(ioc, reportIds));
170                 break;
171             }
172         }
173     }
174 }
175 
176 namespace onChange
177 {
178 
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)179 void LogToRedfishEventLog::commit(
180     const std::string& triggerId, const ThresholdName thresholdNameIn,
181     const std::string& sensorName, const Milliseconds timestamp,
182     const TriggerValue triggerValue)
183 {
184     auto value = triggerValueToString(triggerValue);
185 
186     phosphor::logging::log<phosphor::logging::level::INFO>(
187         "Logging onChange discrete trigger action to Redfish Event Log.",
188         phosphor::logging::entry(
189             "REDFISH_MESSAGE_ID=%s",
190             redfish_message_ids::TriggerDiscreteConditionMet),
191         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
192                                  sensorName.c_str(), value.c_str(),
193                                  triggerId.c_str()));
194 }
195 
fillActions(std::vector<std::unique_ptr<interfaces::TriggerAction>> & actionsIf,const std::vector<TriggerAction> & ActionsEnum,boost::asio::io_context & ioc,const std::shared_ptr<std::vector<std::string>> & reportIds)196 void fillActions(
197     std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
198     const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
199     const std::shared_ptr<std::vector<std::string>>& reportIds)
200 {
201     actionsIf.reserve(ActionsEnum.size());
202     for (auto actionType : ActionsEnum)
203     {
204         switch (actionType)
205         {
206             case TriggerAction::LogToRedfishEventLog:
207             {
208                 actionsIf.emplace_back(
209                     std::make_unique<LogToRedfishEventLog>());
210                 break;
211             }
212             case TriggerAction::UpdateReport:
213             {
214                 actionsIf.emplace_back(
215                     std::make_unique<UpdateReport>(ioc, reportIds));
216                 break;
217             }
218         }
219     }
220 }
221 } // namespace onChange
222 } // namespace discrete
223 
commit(const std::string & triggerId,const ThresholdName thresholdNameIn,const std::string & sensorName,const Milliseconds timestamp,const TriggerValue triggerValue)224 void UpdateReport::commit(
225     const std::string& triggerId, const ThresholdName thresholdNameIn,
226     const std::string& sensorName, const Milliseconds timestamp,
227     const TriggerValue triggerValue)
228 {
229     if (reportIds->empty())
230     {
231         return;
232     }
233 
234     utils::Messanger messanger(ioc);
235     messanger.send(messages::UpdateReportInd{*reportIds});
236 }
237 } // namespace action
238