blob: c59c8ba48597dd46fc2d2cb1e08f15c1a73d38c2 [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#include "event_logger.hpp"
2
Anupama B Rb53d97c2025-02-24 03:37:34 -06003#include "exceptions.hpp"
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05004#include "logger.hpp"
5
6#include <systemd/sd-bus.h>
7
8namespace vpd
9{
10const std::unordered_map<types::SeverityType, std::string>
11 EventLogger::m_severityMap = {
12 {types::SeverityType::Notice,
13 "xyz.openbmc_project.Logging.Entry.Level.Notice"},
14 {types::SeverityType::Informational,
15 "xyz.openbmc_project.Logging.Entry.Level.Informational"},
16 {types::SeverityType::Debug,
17 "xyz.openbmc_project.Logging.Entry.Level.Debug"},
18 {types::SeverityType::Warning,
19 "xyz.openbmc_project.Logging.Entry.Level.Warning"},
20 {types::SeverityType::Critical,
21 "xyz.openbmc_project.Logging.Entry.Level.Critical"},
22 {types::SeverityType::Emergency,
23 "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
24 {types::SeverityType::Alert,
25 "xyz.openbmc_project.Logging.Entry.Level.Alert"},
26 {types::SeverityType::Error,
27 "xyz.openbmc_project.Logging.Entry.Level.Error"}};
28
29const std::unordered_map<types::ErrorType, std::string>
30 EventLogger::m_errorMsgMap = {
31 {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
32 {types::ErrorType::InvalidVpdMessage, "com.ibm.VPD.Error.InvalidVPD"},
33 {types::ErrorType::VpdMismatch, "com.ibm.VPD.Error.Mismatch"},
34 {types::ErrorType::InvalidEeprom,
35 "com.ibm.VPD.Error.InvalidEepromPath"},
36 {types::ErrorType::EccCheckFailed, "com.ibm.VPD.Error.EccCheckFailed"},
37 {types::ErrorType::JsonFailure, "com.ibm.VPD.Error.InvalidJson"},
38 {types::ErrorType::DbusFailure, "com.ibm.VPD.Error.DbusFailure"},
39 {types::ErrorType::InvalidSystem,
40 "com.ibm.VPD.Error.UnknownSystemType"},
41 {types::ErrorType::EssentialFru,
42 "com.ibm.VPD.Error.RequiredFRUMissing"},
Sunny Srivastavaa88a2982025-01-23 12:03:21 +053043 {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"},
44 {types::ErrorType::InternalFailure,
45 "xyz.openbmc_project.Common.Error.InternalFailure"},
Rekha Aparnaffdff312025-03-25 01:10:56 -050046 {types::ErrorType::FruMissing, "com.ibm.VPD.Error.RequiredFRUMissing"},
47 {types::ErrorType::SystemTypeMismatch,
48 "com.ibm.VPD.Error.SystemTypeMismatch"},
49 {types::ErrorType::UnknownSystemSettings,
Sunny Srivastava4fa796c2025-04-01 10:27:02 +053050 "com.ibm.VPD.Error.UnknownSystemSettings"},
51 {types::ErrorType::FirmwareError, "com.ibm.VPD.Error.FirmwareError"}};
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050052
53const std::unordered_map<types::CalloutPriority, std::string>
54 EventLogger::m_priorityMap = {
55 {types::CalloutPriority::High, "H"},
56 {types::CalloutPriority::Medium, "M"},
57 {types::CalloutPriority::MediumGroupA, "A"},
58 {types::CalloutPriority::MediumGroupB, "B"},
59 {types::CalloutPriority::MediumGroupC, "C"},
60 {types::CalloutPriority::Low, "L"}};
61
62void EventLogger::createAsyncPelWithInventoryCallout(
63 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
64 const std::vector<types::InventoryCalloutData>& i_callouts,
65 const std::string& i_fileName, const std::string& i_funcName,
66 const uint8_t i_internalRc, const std::string& i_description,
67 const std::optional<std::string> i_userData1,
68 const std::optional<std::string> i_userData2,
69 const std::optional<std::string> i_symFru,
70 const std::optional<std::string> i_procedure)
71{
72 (void)i_symFru;
73 (void)i_procedure;
74
75 try
76 {
77 if (i_callouts.empty())
78 {
79 logging::logMessage("Callout information is missing to create PEL");
80 // TODO: Revisit this instead of simpley returning.
81 return;
82 }
83
84 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
85 {
86 throw std::runtime_error(
87 "Error type not found in the error message map to create PEL");
88 // TODO: Need to handle, instead of throwing exception. Create
89 // default message in message_registry.json.
90 }
91
92 const std::string& l_message = m_errorMsgMap.at(i_errorType);
93
94 const std::string& l_severity =
95 (m_severityMap.find(i_severity) != m_severityMap.end()
96 ? m_severityMap.at(i_severity)
97 : m_severityMap.at(types::SeverityType::Informational));
98
99 std::string l_description =
100 (!i_description.empty() ? i_description : "VPD generic error");
101
102 std::string l_userData1 = (i_userData1) ? (*i_userData1) : "";
103
104 std::string l_userData2 = (i_userData2) ? (*i_userData2) : "";
105
106 const types::InventoryCalloutData& l_invCallout = i_callouts[0];
107 // TODO: Need to handle multiple inventory path callout's, when multiple
108 // callout's is supported by "Logging" service.
109
110 const types::CalloutPriority& l_priorityEnum = get<1>(l_invCallout);
111
112 const std::string& l_priority =
113 (m_priorityMap.find(l_priorityEnum) != m_priorityMap.end()
114 ? m_priorityMap.at(l_priorityEnum)
115 : m_priorityMap.at(types::CalloutPriority::Low));
116
117 sd_bus* l_sdBus = nullptr;
118 sd_bus_default(&l_sdBus);
119
120 const uint8_t l_additionalDataCount = 8;
121 auto l_rc = sd_bus_call_method_async(
122 l_sdBus, NULL, constants::eventLoggingServiceName,
123 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
124 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
125 l_severity.c_str(), l_additionalDataCount, "FileName",
126 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
127 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
128 l_description.c_str(), "UserData1", l_userData1.c_str(),
129 "UserData2", l_userData2.c_str(), "CALLOUT_INVENTORY_PATH",
130 get<0>(l_invCallout).c_str(), "CALLOUT_PRIORITY",
131 l_priority.c_str());
132
133 if (l_rc < 0)
134 {
135 logging::logMessage(
136 "Error calling sd_bus_call_method_async, Message = " +
137 std::string(strerror(-l_rc)));
138 }
139 }
140 catch (const std::exception& l_ex)
141 {
142 logging::logMessage(
143 "Create PEL failed with error: " + std::string(l_ex.what()));
144 }
145}
146
147void EventLogger::createAsyncPelWithI2cDeviceCallout(
148 const types::ErrorType i_errorType, const types::SeverityType i_severity,
149 const std::vector<types::DeviceCalloutData>& i_callouts,
150 const std::string& i_fileName, const std::string& i_funcName,
151 const uint8_t i_internalRc,
152 const std::optional<std::pair<std::string, std::string>> i_userData1,
153 const std::optional<std::pair<std::string, std::string>> i_userData2)
154{
155 // TODO, implementation needs to be added.
156 (void)i_errorType;
157 (void)i_severity;
158 (void)i_callouts;
159 (void)i_fileName;
160 (void)i_funcName;
161 (void)i_internalRc;
162 (void)i_userData1;
163 (void)i_userData2;
164}
165
166void EventLogger::createAsyncPelWithI2cBusCallout(
167 const types::ErrorType i_errorType, const types::SeverityType i_severity,
168 const std::vector<types::I2cBusCalloutData>& i_callouts,
169 const std::string& i_fileName, const std::string& i_funcName,
170 const uint8_t i_internalRc,
171 const std::optional<std::pair<std::string, std::string>> i_userData1,
172 const std::optional<std::pair<std::string, std::string>> i_userData2)
173{
174 // TODO, implementation needs to be added.
175 (void)i_errorType;
176 (void)i_severity;
177 (void)i_callouts;
178 (void)i_fileName;
179 (void)i_funcName;
180 (void)i_internalRc;
181 (void)i_userData1;
182 (void)i_userData2;
183}
184
185void EventLogger::createAsyncPel(
186 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
187 const std::string& i_fileName, const std::string& i_funcName,
188 const uint8_t i_internalRc, const std::string& i_description,
189 const std::optional<std::string> i_userData1,
190 const std::optional<std::string> i_userData2,
191 const std::optional<std::string> i_symFru,
192 const std::optional<std::string> i_procedure)
193{
194 (void)i_symFru;
195 (void)i_procedure;
196 try
197 {
198 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
199 {
200 throw std::runtime_error("Unsupported error type received");
201 // TODO: Need to handle, instead of throwing an exception.
202 }
203
204 const std::string& l_message = m_errorMsgMap.at(i_errorType);
205
206 const std::string& l_severity =
207 (m_severityMap.find(i_severity) != m_severityMap.end()
208 ? m_severityMap.at(i_severity)
209 : m_severityMap.at(types::SeverityType::Informational));
210
211 const std::string l_description =
212 ((!i_description.empty() ? i_description : "VPD generic error"));
213
214 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
215
216 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
217
218 sd_bus* l_sdBus = nullptr;
219 sd_bus_default(&l_sdBus);
220
221 // VALUE_6 represents the additional data pair count passing to create
222 // PEL. If there any change in additional data, we need to pass the
223 // correct number.
224 auto l_rc = sd_bus_call_method_async(
225 l_sdBus, NULL, constants::eventLoggingServiceName,
226 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
227 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
228 l_severity.c_str(), constants::VALUE_6, "FileName",
229 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
230 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
231 l_description.c_str(), "UserData1", l_userData1.c_str(),
232 "UserData2", l_userData2.c_str());
233
234 if (l_rc < 0)
235 {
236 logging::logMessage(
237 "Error calling sd_bus_call_method_async, Message = " +
238 std::string(strerror(-l_rc)));
239 }
240 }
241 catch (const sdbusplus::exception::SdBusError& l_ex)
242 {
243 logging::logMessage("Async PEL creation failed with an error: " +
244 std::string(l_ex.what()));
245 }
246}
247
248void EventLogger::createSyncPel(
249 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
250 const std::string& i_fileName, const std::string& i_funcName,
251 const uint8_t i_internalRc, const std::string& i_description,
252 const std::optional<std::string> i_userData1,
253 const std::optional<std::string> i_userData2,
254 const std::optional<std::string> i_symFru,
255 const std::optional<std::string> i_procedure)
256{
257 (void)i_symFru;
258 (void)i_procedure;
259 try
260 {
261 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
262 {
263 throw std::runtime_error("Unsupported error type received");
264 // TODO: Need to handle, instead of throwing an exception.
265 }
266
267 const std::string& l_message = m_errorMsgMap.at(i_errorType);
268
269 const std::string& l_severity =
270 (m_severityMap.find(i_severity) != m_severityMap.end()
271 ? m_severityMap.at(i_severity)
272 : m_severityMap.at(types::SeverityType::Informational));
273
274 const std::string l_description =
275 ((!i_description.empty() ? i_description : "VPD generic error"));
276
277 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
278
279 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
280
281 std::map<std::string, std::string> l_additionalData{
282 {"FileName", i_fileName},
283 {"FunctionName", i_funcName},
284 {"DESCRIPTION", l_description},
285 {"InteranlRc", std::to_string(i_internalRc)},
286 {"UserData1", l_userData1.c_str()},
287 {"UserData2", l_userData2.c_str()}};
288
289 auto l_bus = sdbusplus::bus::new_default();
290 auto l_method =
291 l_bus.new_method_call(constants::eventLoggingServiceName,
292 constants::eventLoggingObjectPath,
293 constants::eventLoggingInterface, "Create");
294 l_method.append(l_message, l_severity, l_additionalData);
295 l_bus.call(l_method);
296 }
297 catch (const sdbusplus::exception::SdBusError& l_ex)
298 {
299 logging::logMessage("Sync PEL creation failed with an error: " +
300 std::string(l_ex.what()));
301 }
302}
Anupama B Rb53d97c2025-02-24 03:37:34 -0600303
304types::ExceptionDataMap EventLogger::getExceptionData(
305 const std::exception& i_exception)
306{
307 types::ExceptionDataMap l_errorInfo{
Sunny Srivastava4fa796c2025-04-01 10:27:02 +0530308 {"ErrorType", types::ErrorType::FirmwareError},
Anupama B Rb53d97c2025-02-24 03:37:34 -0600309 {"ErrorMsg", i_exception.what()}};
310
311 try
312 {
313 if (typeid(i_exception) == typeid(DataException))
314 {
315 const DataException& l_ex =
316 dynamic_cast<const DataException&>(i_exception);
317 l_errorInfo["ErrorType"] = l_ex.getErrorType();
318 l_errorInfo["ErrorMsg"] =
319 std::string("Data Exception. Reason: ") + i_exception.what();
320 }
321 else if (typeid(i_exception) == typeid(EccException))
322 {
323 const EccException& l_ex =
324 dynamic_cast<const EccException&>(i_exception);
325 l_errorInfo["ErrorType"] = l_ex.getErrorType();
326 l_errorInfo["ErrorMsg"] =
327 std::string("Ecc Exception. Reason: ") + i_exception.what();
328 }
329 else if (typeid(i_exception) == typeid(JsonException))
330 {
331 const JsonException& l_ex =
332 dynamic_cast<const JsonException&>(i_exception);
333 l_errorInfo["ErrorType"] = l_ex.getErrorType();
334 l_errorInfo["ErrorMsg"] =
335 std::string("Json Exception. Reason: ") + i_exception.what();
336 }
337 else if (typeid(i_exception) == typeid(GpioException))
338 {
339 const GpioException& l_ex =
340 dynamic_cast<const GpioException&>(i_exception);
341 l_errorInfo["ErrorType"] = l_ex.getErrorType();
342 l_errorInfo["ErrorMsg"] =
343 std::string("Gpio Exception. Reason: ") + i_exception.what();
344 }
345 else if (typeid(i_exception) == typeid(DbusException))
346 {
347 const DbusException& l_ex =
348 dynamic_cast<const DbusException&>(i_exception);
349 l_errorInfo["ErrorType"] = l_ex.getErrorType();
350 l_errorInfo["ErrorMsg"] =
351 std::string("Dbus Exception. Reason: ") + i_exception.what();
352 }
353 else if (typeid(i_exception) == typeid(FirmwareException))
354 {
355 const FirmwareException& l_ex =
356 dynamic_cast<const FirmwareException&>(i_exception);
357 l_errorInfo["ErrorType"] = l_ex.getErrorType();
358 l_errorInfo["ErrorMsg"] =
359 std::string("Firmware Exception. Reason: ") +
360 i_exception.what();
361 }
362 else if (typeid(i_exception) == typeid(EepromException))
363 {
364 const EepromException& l_ex =
365 dynamic_cast<const EepromException&>(i_exception);
366 l_errorInfo["ErrorType"] = l_ex.getErrorType();
367 l_errorInfo["ErrorMsg"] =
368 std::string("Eeprom Exception. Reason: ") + i_exception.what();
369 }
370 }
371 catch (const std::exception& l_ex)
372 {
373 logging::logMessage(
374 "Failed to get error info, reason: " + std::string(l_ex.what()));
375 }
376 return l_errorInfo;
377}
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530378
379types::ErrorType EventLogger::getErrorType(const std::exception& i_exception)
380{
381 const auto& l_exceptionDataMap = getExceptionData(i_exception);
382
383 auto l_itrToErrType = l_exceptionDataMap.find("ErrorType");
384 if (l_itrToErrType == l_exceptionDataMap.end())
385 {
Sunny Srivastava4fa796c2025-04-01 10:27:02 +0530386 return types::ErrorType::FirmwareError;
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530387 }
388
389 auto l_ptrToErrType =
390 std::get_if<types::ErrorType>(&l_itrToErrType->second);
391 if (!l_ptrToErrType)
392 {
Sunny Srivastava4fa796c2025-04-01 10:27:02 +0530393 return types::ErrorType::FirmwareError;
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530394 }
395
396 return *l_ptrToErrType;
397}
398
399std::string EventLogger::getErrorMsg(const std::exception& i_exception)
400{
401 const auto& l_exceptionDataMap = getExceptionData(i_exception);
402
403 auto l_itrToErrMsg = l_exceptionDataMap.find("ErrorMsg");
404 if (l_itrToErrMsg == l_exceptionDataMap.end())
405 {
406 return i_exception.what();
407 }
408
409 auto l_ptrToErrMsg = std::get_if<std::string>(&l_itrToErrMsg->second);
410 if (!l_ptrToErrMsg)
411 {
412 return i_exception.what();
413 }
414
415 return *l_ptrToErrMsg;
416}
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500417} // namespace vpd