blob: ef4a50b5c08d5ea355a27eb39d6b0e95c38186c6 [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
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020067const char* LogToRedfishEventLog::getRedfishMessageId() const
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010068{
69 switch (type)
70 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010071 case ::numeric::Type::upperCritical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020072 return redfish_message_ids::TriggerNumericCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010073 case ::numeric::Type::lowerCritical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020074 return redfish_message_ids::TriggerNumericCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010075 case ::numeric::Type::upperWarning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020076 return redfish_message_ids::TriggerNumericWarning;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010077 case ::numeric::Type::lowerWarning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020078 return redfish_message_ids::TriggerNumericWarning;
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010079 }
80 throw std::runtime_error("Invalid type");
81}
82
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020083void LogToRedfishEventLog::commit(const std::string& triggerId,
84 const ThresholdName thresholdNameInIn,
85 const std::string& sensorName,
86 const Milliseconds timestamp,
87 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010088{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020089 double value = std::get<double>(triggerValue);
90 std::string thresholdName = ::numeric::typeToString(type);
91 auto direction = getDirection(value, threshold);
92 auto timestampStr = timestampToString(timestamp);
93
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010094 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020095 "Logging numeric trigger action to Redfish Event Log.",
96 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
97 getRedfishMessageId()),
98 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%f,%s,%s",
99 thresholdName.c_str(), triggerId.c_str(),
100 sensorName.c_str(), value, direction,
101 timestampStr.c_str()));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100102}
103
Szymon Dompke20013012021-07-23 09:54:20 +0200104void fillActions(
105 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
106 const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100107 double thresholdValue, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100108 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200109{
110 actionsIf.reserve(ActionsEnum.size());
111 for (auto actionType : ActionsEnum)
112 {
113 switch (actionType)
114 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200115 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200116 {
117 actionsIf.emplace_back(
118 std::make_unique<LogToJournal>(type, thresholdValue));
119 break;
120 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200121 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200122 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200123 actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
124 type, thresholdValue));
Szymon Dompke20013012021-07-23 09:54:20 +0200125 break;
126 }
127 case TriggerAction::UpdateReport:
128 {
129 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100130 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200131 break;
132 }
133 }
134 }
135}
136
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100137} // namespace numeric
138
139namespace discrete
140{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200141
142void LogToJournal::commit(const std::string& triggerId,
143 const ThresholdName thresholdNameIn,
144 const std::string& sensorName,
145 const Milliseconds timestamp,
146 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100147{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200148 auto value = std::get<std::string>(triggerValue);
149
Krzysztof Grobelnycff70c12022-10-27 07:16:08 +0000150 std::string msg =
151 "Discrete condition '" + thresholdNameIn->get() + "' of trigger '" +
152 triggerId + "' is met on sensor " + sensorName +
153 ", recorded value: " + value + ", severity: " +
154 std::string(utils::toShortEnum(utils::enumToString(severity))) +
155 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100156
157 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
158}
159
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200160const char* LogToRedfishEventLog::getRedfishMessageId() const
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100161{
162 switch (severity)
163 {
164 case ::discrete::Severity::ok:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200165 return redfish_message_ids::TriggerDiscreteOK;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100166 case ::discrete::Severity::warning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200167 return redfish_message_ids::TriggerDiscreteWarning;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100168 case ::discrete::Severity::critical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200169 return redfish_message_ids::TriggerDiscreteCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100170 }
171 throw std::runtime_error("Invalid severity");
172}
173
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200174void LogToRedfishEventLog::commit(const std::string& triggerId,
175 const ThresholdName thresholdNameIn,
176 const std::string& sensorName,
177 const Milliseconds timestamp,
178 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100179{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200180 auto value = std::get<std::string>(triggerValue);
181 auto timestampStr = timestampToString(timestamp);
182
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100183 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200184 "Logging discrete trigger action to Redfish Event Log.",
185 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
186 getRedfishMessageId()),
187 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
188 thresholdNameIn->get().c_str(),
189 triggerId.c_str(), sensorName.c_str(),
190 value.c_str(), timestampStr.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100191}
192
Szymon Dompke20013012021-07-23 09:54:20 +0200193void fillActions(
194 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
195 const std::vector<TriggerAction>& ActionsEnum,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100196 ::discrete::Severity severity, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100197 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200198{
199 actionsIf.reserve(ActionsEnum.size());
200 for (auto actionType : ActionsEnum)
201 {
202 switch (actionType)
203 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200204 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200205 {
206 actionsIf.emplace_back(
207 std::make_unique<LogToJournal>(severity));
208 break;
209 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200210 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200211 {
212 actionsIf.emplace_back(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200213 std::make_unique<LogToRedfishEventLog>(severity));
Szymon Dompke20013012021-07-23 09:54:20 +0200214 break;
215 }
216 case TriggerAction::UpdateReport:
217 {
218 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100219 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200220 break;
221 }
222 }
223 }
224}
225
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100226namespace onChange
227{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200228void LogToJournal::commit(const std::string& triggerId,
229 const ThresholdName thresholdNameIn,
230 const std::string& sensorName,
231 const Milliseconds timestamp,
232 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100233{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200234 auto value = triggerValueToString(triggerValue);
235 std::string msg = "Discrete condition 'OnChange' of trigger '" + triggerId +
236 "' is met on sensor: " + sensorName +
237 ", recorded value: " + value +
238 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100239
240 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
241}
242
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200243void LogToRedfishEventLog::commit(const std::string& triggerId,
244 const ThresholdName thresholdNameIn,
245 const std::string& sensorName,
246 const Milliseconds timestamp,
247 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100248{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200249 auto value = triggerValueToString(triggerValue);
250 auto timestampStr = timestampToString(timestamp);
251
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100252 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200253 "Logging onChange discrete trigger action to Redfish Event Log.",
254 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
255 redfish_message_ids::TriggerDiscreteOK),
256 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
257 "OnChange", triggerId.c_str(),
258 sensorName.c_str(), value.c_str(),
259 timestampStr.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100260}
Szymon Dompke20013012021-07-23 09:54:20 +0200261
262void fillActions(
263 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100264 const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100265 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200266{
267 actionsIf.reserve(ActionsEnum.size());
268 for (auto actionType : ActionsEnum)
269 {
270 switch (actionType)
271 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200272 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200273 {
274 actionsIf.emplace_back(std::make_unique<LogToJournal>());
275 break;
276 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200277 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200278 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200279 actionsIf.emplace_back(
280 std::make_unique<LogToRedfishEventLog>());
Szymon Dompke20013012021-07-23 09:54:20 +0200281 break;
282 }
283 case TriggerAction::UpdateReport:
284 {
285 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100286 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200287 break;
288 }
289 }
290 }
291}
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100292} // namespace onChange
293} // namespace discrete
294
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200295void UpdateReport::commit(const std::string& triggerId,
296 const ThresholdName thresholdNameIn,
297 const std::string& sensorName,
298 const Milliseconds timestamp,
299 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100300{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100301 if (reportIds->empty())
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100302 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100303 return;
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100304 }
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100305
306 utils::Messanger messanger(ioc);
307 messanger.send(messages::UpdateReportInd{*reportIds});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100308}
309} // namespace action