blob: 75aab50700dee3bba61a8bd4d5a02d63530d8541 [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"
7
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +01008#include <phosphor-logging/log.hpp>
9
10#include <ctime>
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020011#include <iomanip>
12#include <sstream>
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010013
14namespace action
15{
16
Szymon Dompkef763c9e2021-03-12 09:19:22 +010017namespace
18{
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010019std::string timestampToString(Milliseconds timestamp)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010020{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020021 std::time_t t = static_cast<time_t>(
22 std::chrono::duration_cast<std::chrono::seconds>(timestamp).count());
23 std::stringstream ss;
24 ss << std::put_time(std::gmtime(&t), "%FT%T.") << std::setw(3)
25 << std::setfill('0') << timestamp.count() % 1000 << 'Z';
26 return ss.str();
Szymon Dompkef763c9e2021-03-12 09:19:22 +010027}
28} // namespace
29
30namespace numeric
31{
32
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010033static const char* getDirection(double value, double threshold)
34{
35 if (value < threshold)
36 {
37 return "decreasing";
38 }
39 if (value > threshold)
40 {
41 return "increasing";
42 }
43 throw std::runtime_error("Invalid value");
44}
45
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020046void LogToJournal::commit(const std::string& triggerId,
47 const ThresholdName thresholdNameInIn,
48 const std::string& sensorName,
49 const Milliseconds timestamp,
50 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010051{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020052 double value = std::get<double>(triggerValue);
53 std::string thresholdName = ::numeric::typeToString(type);
54 auto direction = getDirection(value, threshold);
55
56 std::string msg = "Numeric threshold '" + thresholdName + "' of trigger '" +
57 triggerId + "' is crossed on sensor " + sensorName +
58 ", recorded value: " + std::to_string(value) +
59 ", crossing direction: " + direction +
60 ", timestamp: " + timestampToString(timestamp);
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010061
62 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
63}
64
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020065const char* LogToRedfishEventLog::getRedfishMessageId() const
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010066{
67 switch (type)
68 {
Szymon Dompkef763c9e2021-03-12 09:19:22 +010069 case ::numeric::Type::upperCritical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020070 return redfish_message_ids::TriggerNumericCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010071 case ::numeric::Type::lowerCritical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020072 return redfish_message_ids::TriggerNumericCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010073 case ::numeric::Type::upperWarning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020074 return redfish_message_ids::TriggerNumericWarning;
Szymon Dompkef763c9e2021-03-12 09:19:22 +010075 case ::numeric::Type::lowerWarning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020076 return redfish_message_ids::TriggerNumericWarning;
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010077 }
78 throw std::runtime_error("Invalid type");
79}
80
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020081void LogToRedfishEventLog::commit(const std::string& triggerId,
82 const ThresholdName thresholdNameInIn,
83 const std::string& sensorName,
84 const Milliseconds timestamp,
85 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010086{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020087 double value = std::get<double>(triggerValue);
88 std::string thresholdName = ::numeric::typeToString(type);
89 auto direction = getDirection(value, threshold);
90 auto timestampStr = timestampToString(timestamp);
91
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +010092 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020093 "Logging numeric trigger action to Redfish Event Log.",
94 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
95 getRedfishMessageId()),
96 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%f,%s,%s",
97 thresholdName.c_str(), triggerId.c_str(),
98 sensorName.c_str(), value, direction,
99 timestampStr.c_str()));
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100100}
101
Szymon Dompke20013012021-07-23 09:54:20 +0200102void fillActions(
103 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
104 const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100105 double thresholdValue, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100106 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200107{
108 actionsIf.reserve(ActionsEnum.size());
109 for (auto actionType : ActionsEnum)
110 {
111 switch (actionType)
112 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200113 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200114 {
115 actionsIf.emplace_back(
116 std::make_unique<LogToJournal>(type, thresholdValue));
117 break;
118 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200119 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200120 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200121 actionsIf.emplace_back(std::make_unique<LogToRedfishEventLog>(
122 type, thresholdValue));
Szymon Dompke20013012021-07-23 09:54:20 +0200123 break;
124 }
125 case TriggerAction::UpdateReport:
126 {
127 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100128 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200129 break;
130 }
131 }
132 }
133}
134
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100135} // namespace numeric
136
137namespace discrete
138{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200139
140void LogToJournal::commit(const std::string& triggerId,
141 const ThresholdName thresholdNameIn,
142 const std::string& sensorName,
143 const Milliseconds timestamp,
144 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100145{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200146 auto value = std::get<std::string>(triggerValue);
147
148 std::string msg = "Discrete condition '" + thresholdNameIn->get() +
149 "' of trigger '" + triggerId + "' is met on sensor " +
150 sensorName + ", recorded value: " + value +
151 ", severity: " + ::discrete::severityToString(severity) +
152 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100153
154 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
155}
156
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200157const char* LogToRedfishEventLog::getRedfishMessageId() const
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100158{
159 switch (severity)
160 {
161 case ::discrete::Severity::ok:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200162 return redfish_message_ids::TriggerDiscreteOK;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100163 case ::discrete::Severity::warning:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200164 return redfish_message_ids::TriggerDiscreteWarning;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100165 case ::discrete::Severity::critical:
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200166 return redfish_message_ids::TriggerDiscreteCritical;
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100167 }
168 throw std::runtime_error("Invalid severity");
169}
170
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200171void LogToRedfishEventLog::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 auto timestampStr = timestampToString(timestamp);
179
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100180 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200181 "Logging discrete trigger action to Redfish Event Log.",
182 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
183 getRedfishMessageId()),
184 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
185 thresholdNameIn->get().c_str(),
186 triggerId.c_str(), sensorName.c_str(),
187 value.c_str(), timestampStr.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100188}
189
Szymon Dompke20013012021-07-23 09:54:20 +0200190void fillActions(
191 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
192 const std::vector<TriggerAction>& ActionsEnum,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100193 ::discrete::Severity severity, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100194 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200195{
196 actionsIf.reserve(ActionsEnum.size());
197 for (auto actionType : ActionsEnum)
198 {
199 switch (actionType)
200 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200201 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200202 {
203 actionsIf.emplace_back(
204 std::make_unique<LogToJournal>(severity));
205 break;
206 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200207 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200208 {
209 actionsIf.emplace_back(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200210 std::make_unique<LogToRedfishEventLog>(severity));
Szymon Dompke20013012021-07-23 09:54:20 +0200211 break;
212 }
213 case TriggerAction::UpdateReport:
214 {
215 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100216 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200217 break;
218 }
219 }
220 }
221}
222
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100223namespace onChange
224{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200225void LogToJournal::commit(const std::string& triggerId,
226 const ThresholdName thresholdNameIn,
227 const std::string& sensorName,
228 const Milliseconds timestamp,
229 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100230{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200231 auto value = triggerValueToString(triggerValue);
232 std::string msg = "Discrete condition 'OnChange' of trigger '" + triggerId +
233 "' is met on sensor: " + sensorName +
234 ", recorded value: " + value +
235 ", timestamp: " + timestampToString(timestamp);
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100236
237 phosphor::logging::log<phosphor::logging::level::INFO>(msg.c_str());
238}
239
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200240void LogToRedfishEventLog::commit(const std::string& triggerId,
241 const ThresholdName thresholdNameIn,
242 const std::string& sensorName,
243 const Milliseconds timestamp,
244 const TriggerValue triggerValue)
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100245{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200246 auto value = triggerValueToString(triggerValue);
247 auto timestampStr = timestampToString(timestamp);
248
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100249 phosphor::logging::log<phosphor::logging::level::INFO>(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200250 "Logging onChange discrete trigger action to Redfish Event Log.",
251 phosphor::logging::entry("REDFISH_MESSAGE_ID=%s",
252 redfish_message_ids::TriggerDiscreteOK),
253 phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%s,%s,%s,%s",
254 "OnChange", triggerId.c_str(),
255 sensorName.c_str(), value.c_str(),
256 timestampStr.c_str()));
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100257}
Szymon Dompke20013012021-07-23 09:54:20 +0200258
259void fillActions(
260 std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100261 const std::vector<TriggerAction>& ActionsEnum, boost::asio::io_context& ioc,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100262 const std::shared_ptr<std::vector<std::string>>& reportIds)
Szymon Dompke20013012021-07-23 09:54:20 +0200263{
264 actionsIf.reserve(ActionsEnum.size());
265 for (auto actionType : ActionsEnum)
266 {
267 switch (actionType)
268 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200269 case TriggerAction::LogToJournal:
Szymon Dompke20013012021-07-23 09:54:20 +0200270 {
271 actionsIf.emplace_back(std::make_unique<LogToJournal>());
272 break;
273 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200274 case TriggerAction::LogToRedfishEventLog:
Szymon Dompke20013012021-07-23 09:54:20 +0200275 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200276 actionsIf.emplace_back(
277 std::make_unique<LogToRedfishEventLog>());
Szymon Dompke20013012021-07-23 09:54:20 +0200278 break;
279 }
280 case TriggerAction::UpdateReport:
281 {
282 actionsIf.emplace_back(
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100283 std::make_unique<UpdateReport>(ioc, reportIds));
Szymon Dompke20013012021-07-23 09:54:20 +0200284 break;
285 }
286 }
287 }
288}
Szymon Dompkef763c9e2021-03-12 09:19:22 +0100289} // namespace onChange
290} // namespace discrete
291
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200292void UpdateReport::commit(const std::string& triggerId,
293 const ThresholdName thresholdNameIn,
294 const std::string& sensorName,
295 const Milliseconds timestamp,
296 const TriggerValue triggerValue)
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100297{
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100298 if (reportIds->empty())
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100299 {
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100300 return;
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100301 }
Krzysztof Grobelnye6d48872022-02-08 13:41:30 +0100302
303 utils::Messanger messanger(ioc);
304 messanger.send(messages::UpdateReportInd{*reportIds});
Wludzik, Jozefd960e1f2021-01-08 09:25:59 +0100305}
306} // namespace action