blob: 9466b77b927ad0bd1c1528f509e3854c6589ef4b [file] [log] [blame]
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +01001#include "trigger_actions.hpp"
2
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01003#include "messages/update_report_ind.hpp"
Szymon Dompkef670b022022-03-16 19:21:11 +01004#include "types/trigger_types.hpp"
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +02005#include "utils/clock.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01006#include "utils/messanger.hpp"
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +00007#include "utils/to_short_enum.hpp"
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +01008
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +01009#include <phosphor-logging/log.hpp>
10
11#include <ctime>
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020012#include <iomanip>
13#include <sstream>
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010014
15namespace action
16{
17
Szymon Dompkef763c9e2021-03-12 09:19:22 +010018namespace
19{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010020std::string timestampToString(Milliseconds timestamp)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010021{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020022 std::time_t t = static_cast<time_t>(
23 std::chrono::duration_cast<std::chrono::seconds>(timestamp).count());
24 std::stringstream ss;
25 ss << std::put_time(std::gmtime(&t), "%FT%T.") << std::setw(3)
26 << std::setfill('0') << timestamp.count() % 1000 << 'Z';
27 return ss.str();
Szymon Dompkef763c9e2021-03-12 09:19:22 +010028}
29} // namespace
30
31namespace numeric
32{
33
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010034static const char* getDirection(double value, double threshold)
35{
36 if (value < threshold)
37 {
38 return "decreasing";
39 }
40 if (value > threshold)
41 {
42 return "increasing";
43 }
44 throw std::runtime_error("Invalid value");
45}
46
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020047void LogToJournal::commit(const std::string& triggerId,
48 const ThresholdName thresholdNameInIn,
49 const std::string& sensorName,
50 const Milliseconds timestamp,
51 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010052{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020053 double value = std::get<double>(triggerValue);
54 std::string thresholdName = ::numeric::typeToString(type);
55 auto direction = getDirection(value, threshold);
56
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +000057 std::string msg =
58 "Numeric threshold '" + std::string(utils::toShortEnum(thresholdName)) +
59 "' of trigger '" + triggerId + "' is crossed on sensor " + sensorName +
60 ", recorded value: " + std::to_string(value) +
61 ", crossing direction: " + std::string(utils::toShortEnum(direction)) +
62 ", timestamp: " + timestampToString(timestamp);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010063
64 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
65}
66
Michal Orzel8018a3b2024-06-26 14:14:16 +020067const char* LogToRedfishEventLog::getRedfishMessageId(const double value) const
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010068{
Michal Orzel8018a3b2024-06-26 14:14:16 +020069 std::string direction(getDirection(value, threshold));
70
71 if (direction == "decreasing")
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010072 {
Michal Orzel8018a3b2024-06-26 14:14:16 +020073 switch (type)
74 {
75 case ::numeric::Type::upperCritical:
76 return redfish_message_ids::TriggerNumericBelowUpperCritical;
77 case ::numeric::Type::lowerCritical:
78 return redfish_message_ids::TriggerNumericBelowLowerCritical;
79 case ::numeric::Type::upperWarning:
80 return redfish_message_ids::TriggerNumericReadingNormal;
81 case ::numeric::Type::lowerWarning:
82 return redfish_message_ids::TriggerNumericBelowLowerWarning;
83 }
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010084 }
Michal Orzel8018a3b2024-06-26 14:14:16 +020085
86 if (direction == "increasing")
87 {
88 switch (type)
89 {
90 case ::numeric::Type::upperCritical:
91 return redfish_message_ids::TriggerNumericAboveUpperCritical;
92 case ::numeric::Type::lowerCritical:
93 return redfish_message_ids::TriggerNumericAboveLowerCritical;
94 case ::numeric::Type::upperWarning:
95 return redfish_message_ids::TriggerNumericAboveUpperWarning;
96 case ::numeric::Type::lowerWarning:
97 return redfish_message_ids::TriggerNumericReadingNormal;
98 }
99 }
100
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100101 throw std::runtime_error("Invalid type");
102}
103
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200104void LogToRedfishEventLog::commit(const std::string& triggerId,
105 const ThresholdName thresholdNameInIn,
106 const std::string& sensorName,
107 const Milliseconds timestamp,
108 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100109{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200110 double value = std::get<double>(triggerValue);
Michal Orzel8018a3b2024-06-26 14:14:16 +0200111 auto messageId = getRedfishMessageId(value);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200112
Michal Orzel8018a3b2024-06-26 14:14:16 +0200113 if (messageId == redfish_message_ids::TriggerNumericReadingNormal)
114 {
115 phosphor::logging::log<phosphor::logging::level::INFO>(
116 "Logging numeric trigger action to Redfish Event Log.",
117 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
118 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%s",
119 sensorName.c_str(), value,
120 triggerId.c_str()));
121 }
122 else
123 {
124 phosphor::logging::log<phosphor::logging::level::INFO>(
125 "Logging numeric trigger action to Redfish Event Log.",
126 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageId),
127 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%f,%s",
128 sensorName.c_str(), value, threshold,
129 triggerId.c_str()));
130 }
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100131}
132
Szymon Dompke20013012021-07-23 09:54:20 +0200133void fillActions(
134 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
135 const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100136 double thresholdValue, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100137 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200138{
139 actionsIf.reserve(ActionsEnum.size());
140 for (auto actionType : ActionsEnum)
141 {
142 switch (actionType)
143 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200144 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200145 {
146 actionsIf.emplace_back(
147 std::make_unique<LogToJournal>(type, thresholdValue));
148 break;
149 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200150 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200151 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200152 actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
153 type, thresholdValue));
Szymon Dompke20013012021-07-23 09:54:20 +0200154 break;
155 }
156 case TriggerAction::UpdateReport:
157 {
158 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100159 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200160 break;
161 }
162 }
163 }
164}
165
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100166} // namespace numeric
167
168namespace discrete
169{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200170
171void LogToJournal::commit(const std::string& triggerId,
172 const ThresholdName thresholdNameIn,
173 const std::string& sensorName,
174 const Milliseconds timestamp,
175 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100176{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200177 auto value = std::get<std::string>(triggerValue);
178
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000179 std::string msg =
180 "Discrete condition '" + thresholdNameIn->get() + "' of trigger '" +
181 triggerId + "' is met on sensor " + sensorName +
182 ", recorded value: " + value + ", severity: " +
183 std::string(utils::toShortEnum(utils::enumToString(severity))) +
184 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100185
186 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
187}
188
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200189void LogToRedfishEventLog::commit(const std::string& triggerId,
190 const ThresholdName thresholdNameIn,
191 const std::string& sensorName,
192 const Milliseconds timestamp,
193 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100194{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200195 auto value = std::get<std::string>(triggerValue);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200196
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100197 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200198 "Logging discrete trigger action to Redfish Event Log.",
Michal Orzel8018a3b2024-06-26 14:14:16 +0200199 phosphor::logging::entry(
200 "REDFISH_MESSAGE_ID=%s",
201 redfish_message_ids::TriggerDiscreteConditionMet),
202 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
203 sensorName.c_str(), value.c_str(),
204 triggerId.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100205}
206
Szymon Dompke20013012021-07-23 09:54:20 +0200207void fillActions(
208 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
209 const std::vector<TriggerAction>& ActionsEnum,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100210 ::discrete::Severity severity, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100211 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200212{
213 actionsIf.reserve(ActionsEnum.size());
214 for (auto actionType : ActionsEnum)
215 {
216 switch (actionType)
217 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200218 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200219 {
220 actionsIf.emplace_back(
221 std::make_unique<LogToJournal>(severity));
222 break;
223 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200224 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200225 {
226 actionsIf.emplace_back(
Michal Orzel8018a3b2024-06-26 14:14:16 +0200227 std::make_unique<LogToRedfishEventLog>());
Szymon Dompke20013012021-07-23 09:54:20 +0200228 break;
229 }
230 case TriggerAction::UpdateReport:
231 {
232 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100233 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200234 break;
235 }
236 }
237 }
238}
239
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100240namespace onChange
241{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200242void LogToJournal::commit(const std::string& triggerId,
243 const ThresholdName thresholdNameIn,
244 const std::string& sensorName,
245 const Milliseconds timestamp,
246 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100247{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200248 auto value = triggerValueToString(triggerValue);
249 std::string msg = "Discrete condition 'OnChange' of trigger '" + triggerId +
250 "' is met on sensor: " + sensorName +
251 ", recorded value: " + value +
252 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100253
254 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
255}
256
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200257void LogToRedfishEventLog::commit(const std::string& triggerId,
258 const ThresholdName thresholdNameIn,
259 const std::string& sensorName,
260 const Milliseconds timestamp,
261 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100262{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200263 auto value = triggerValueToString(triggerValue);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200264
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100265 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200266 "Logging onChange discrete trigger action to Redfish Event Log.",
Michal Orzel8018a3b2024-06-26 14:14:16 +0200267 phosphor::logging::entry(
268 "REDFISH_MESSAGE_ID=%s",
269 redfish_message_ids::TriggerDiscreteConditionMet),
270 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s",
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200271 sensorName.c_str(), value.c_str(),
Michal Orzel8018a3b2024-06-26 14:14:16 +0200272 triggerId.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100273}
Szymon Dompke20013012021-07-23 09:54:20 +0200274
275void fillActions(
276 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100277 const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100278 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200279{
280 actionsIf.reserve(ActionsEnum.size());
281 for (auto actionType : ActionsEnum)
282 {
283 switch (actionType)
284 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200285 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200286 {
287 actionsIf.emplace_back(std::make_unique<LogToJournal>());
288 break;
289 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200290 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200291 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200292 actionsIf.emplace_back(
293 std::make_unique<LogToRedfishEventLog>());
Szymon Dompke20013012021-07-23 09:54:20 +0200294 break;
295 }
296 case TriggerAction::UpdateReport:
297 {
298 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100299 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200300 break;
301 }
302 }
303 }
304}
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100305} // namespace onChange
306} // namespace discrete
307
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200308void UpdateReport::commit(const std::string& triggerId,
309 const ThresholdName thresholdNameIn,
310 const std::string& sensorName,
311 const Milliseconds timestamp,
312 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100313{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100314 if (reportIds->empty())
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100315 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100316 return;
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100317 }
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100318
319 utils::Messanger messanger(ioc);
320 messanger.send(messages::UpdateReportInd{*reportIds});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100321}
322} // namespace action