1 #include "event_logger.hpp"
2
3 #include "logger.hpp"
4
5 #include <systemd/sd-bus.h>
6
7 namespace vpd
8 {
9 const std::unordered_map<types::SeverityType, std::string>
10 EventLogger::m_severityMap = {
11 {types::SeverityType::Notice,
12 "xyz.openbmc_project.Logging.Entry.Level.Notice"},
13 {types::SeverityType::Informational,
14 "xyz.openbmc_project.Logging.Entry.Level.Informational"},
15 {types::SeverityType::Debug,
16 "xyz.openbmc_project.Logging.Entry.Level.Debug"},
17 {types::SeverityType::Warning,
18 "xyz.openbmc_project.Logging.Entry.Level.Warning"},
19 {types::SeverityType::Critical,
20 "xyz.openbmc_project.Logging.Entry.Level.Critical"},
21 {types::SeverityType::Emergency,
22 "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
23 {types::SeverityType::Alert,
24 "xyz.openbmc_project.Logging.Entry.Level.Alert"},
25 {types::SeverityType::Error,
26 "xyz.openbmc_project.Logging.Entry.Level.Error"}};
27
28 const std::unordered_map<types::ErrorType, std::string>
29 EventLogger::m_errorMsgMap = {
30 {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
31 {types::ErrorType::InvalidVpdMessage, "com.ibm.VPD.Error.InvalidVPD"},
32 {types::ErrorType::VpdMismatch, "com.ibm.VPD.Error.Mismatch"},
33 {types::ErrorType::InvalidEeprom,
34 "com.ibm.VPD.Error.InvalidEepromPath"},
35 {types::ErrorType::EccCheckFailed, "com.ibm.VPD.Error.EccCheckFailed"},
36 {types::ErrorType::JsonFailure, "com.ibm.VPD.Error.InvalidJson"},
37 {types::ErrorType::DbusFailure, "com.ibm.VPD.Error.DbusFailure"},
38 {types::ErrorType::InvalidSystem,
39 "com.ibm.VPD.Error.UnknownSystemType"},
40 {types::ErrorType::EssentialFru,
41 "com.ibm.VPD.Error.RequiredFRUMissing"},
42 {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"}};
43
44 const std::unordered_map<types::CalloutPriority, std::string>
45 EventLogger::m_priorityMap = {
46 {types::CalloutPriority::High, "H"},
47 {types::CalloutPriority::Medium, "M"},
48 {types::CalloutPriority::MediumGroupA, "A"},
49 {types::CalloutPriority::MediumGroupB, "B"},
50 {types::CalloutPriority::MediumGroupC, "C"},
51 {types::CalloutPriority::Low, "L"}};
52
createAsyncPelWithInventoryCallout(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::vector<types::InventoryCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)53 void EventLogger::createAsyncPelWithInventoryCallout(
54 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
55 const std::vector<types::InventoryCalloutData>& i_callouts,
56 const std::string& i_fileName, const std::string& i_funcName,
57 const uint8_t i_internalRc, const std::string& i_description,
58 const std::optional<std::string> i_userData1,
59 const std::optional<std::string> i_userData2,
60 const std::optional<std::string> i_symFru,
61 const std::optional<std::string> i_procedure)
62 {
63 (void)i_symFru;
64 (void)i_procedure;
65
66 try
67 {
68 if (i_callouts.empty())
69 {
70 logging::logMessage("Callout information is missing to create PEL");
71 // TODO: Revisit this instead of simpley returning.
72 return;
73 }
74
75 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
76 {
77 throw std::runtime_error(
78 "Error type not found in the error message map to create PEL");
79 // TODO: Need to handle, instead of throwing exception. Create
80 // default message in message_registry.json.
81 }
82
83 const std::string& l_message = m_errorMsgMap.at(i_errorType);
84
85 const std::string& l_severity =
86 (m_severityMap.find(i_severity) != m_severityMap.end()
87 ? m_severityMap.at(i_severity)
88 : m_severityMap.at(types::SeverityType::Informational));
89
90 std::string l_description =
91 (!i_description.empty() ? i_description : "VPD generic error");
92
93 std::string l_userData1 = (i_userData1) ? (*i_userData1) : "";
94
95 std::string l_userData2 = (i_userData2) ? (*i_userData2) : "";
96
97 const types::InventoryCalloutData& l_invCallout = i_callouts[0];
98 // TODO: Need to handle multiple inventory path callout's, when multiple
99 // callout's is supported by "Logging" service.
100
101 const types::CalloutPriority& l_priorityEnum = get<1>(l_invCallout);
102
103 const std::string& l_priority =
104 (m_priorityMap.find(l_priorityEnum) != m_priorityMap.end()
105 ? m_priorityMap.at(l_priorityEnum)
106 : m_priorityMap.at(types::CalloutPriority::Low));
107
108 sd_bus* l_sdBus = nullptr;
109 sd_bus_default(&l_sdBus);
110
111 const uint8_t l_additionalDataCount = 8;
112 auto l_rc = sd_bus_call_method_async(
113 l_sdBus, NULL, constants::eventLoggingServiceName,
114 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
115 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
116 l_severity.c_str(), l_additionalDataCount, "FileName",
117 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
118 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
119 l_description.c_str(), "UserData1", l_userData1.c_str(),
120 "UserData2", l_userData2.c_str(), "CALLOUT_INVENTORY_PATH",
121 get<0>(l_invCallout).c_str(), "CALLOUT_PRIORITY",
122 l_priority.c_str());
123
124 if (l_rc < 0)
125 {
126 logging::logMessage(
127 "Error calling sd_bus_call_method_async, Message = " +
128 std::string(strerror(-l_rc)));
129 }
130 }
131 catch (const std::exception& l_ex)
132 {
133 logging::logMessage(
134 "Create PEL failed with error: " + std::string(l_ex.what()));
135 }
136 }
137
createAsyncPelWithI2cDeviceCallout(const types::ErrorType i_errorType,const types::SeverityType i_severity,const std::vector<types::DeviceCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::optional<std::pair<std::string,std::string>> i_userData1,const std::optional<std::pair<std::string,std::string>> i_userData2)138 void EventLogger::createAsyncPelWithI2cDeviceCallout(
139 const types::ErrorType i_errorType, const types::SeverityType i_severity,
140 const std::vector<types::DeviceCalloutData>& i_callouts,
141 const std::string& i_fileName, const std::string& i_funcName,
142 const uint8_t i_internalRc,
143 const std::optional<std::pair<std::string, std::string>> i_userData1,
144 const std::optional<std::pair<std::string, std::string>> i_userData2)
145 {
146 // TODO, implementation needs to be added.
147 (void)i_errorType;
148 (void)i_severity;
149 (void)i_callouts;
150 (void)i_fileName;
151 (void)i_funcName;
152 (void)i_internalRc;
153 (void)i_userData1;
154 (void)i_userData2;
155 }
156
createAsyncPelWithI2cBusCallout(const types::ErrorType i_errorType,const types::SeverityType i_severity,const std::vector<types::I2cBusCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::optional<std::pair<std::string,std::string>> i_userData1,const std::optional<std::pair<std::string,std::string>> i_userData2)157 void EventLogger::createAsyncPelWithI2cBusCallout(
158 const types::ErrorType i_errorType, const types::SeverityType i_severity,
159 const std::vector<types::I2cBusCalloutData>& i_callouts,
160 const std::string& i_fileName, const std::string& i_funcName,
161 const uint8_t i_internalRc,
162 const std::optional<std::pair<std::string, std::string>> i_userData1,
163 const std::optional<std::pair<std::string, std::string>> i_userData2)
164 {
165 // TODO, implementation needs to be added.
166 (void)i_errorType;
167 (void)i_severity;
168 (void)i_callouts;
169 (void)i_fileName;
170 (void)i_funcName;
171 (void)i_internalRc;
172 (void)i_userData1;
173 (void)i_userData2;
174 }
175
createAsyncPel(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)176 void EventLogger::createAsyncPel(
177 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
178 const std::string& i_fileName, const std::string& i_funcName,
179 const uint8_t i_internalRc, const std::string& i_description,
180 const std::optional<std::string> i_userData1,
181 const std::optional<std::string> i_userData2,
182 const std::optional<std::string> i_symFru,
183 const std::optional<std::string> i_procedure)
184 {
185 (void)i_symFru;
186 (void)i_procedure;
187 try
188 {
189 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
190 {
191 throw std::runtime_error("Unsupported error type received");
192 // TODO: Need to handle, instead of throwing an exception.
193 }
194
195 const std::string& l_message = m_errorMsgMap.at(i_errorType);
196
197 const std::string& l_severity =
198 (m_severityMap.find(i_severity) != m_severityMap.end()
199 ? m_severityMap.at(i_severity)
200 : m_severityMap.at(types::SeverityType::Informational));
201
202 const std::string l_description =
203 ((!i_description.empty() ? i_description : "VPD generic error"));
204
205 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
206
207 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
208
209 sd_bus* l_sdBus = nullptr;
210 sd_bus_default(&l_sdBus);
211
212 // VALUE_6 represents the additional data pair count passing to create
213 // PEL. If there any change in additional data, we need to pass the
214 // correct number.
215 auto l_rc = sd_bus_call_method_async(
216 l_sdBus, NULL, constants::eventLoggingServiceName,
217 constants::eventLoggingObjectPath, constants::eventLoggingInterface,
218 "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
219 l_severity.c_str(), constants::VALUE_6, "FileName",
220 i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
221 "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
222 l_description.c_str(), "UserData1", l_userData1.c_str(),
223 "UserData2", l_userData2.c_str());
224
225 if (l_rc < 0)
226 {
227 logging::logMessage(
228 "Error calling sd_bus_call_method_async, Message = " +
229 std::string(strerror(-l_rc)));
230 }
231 }
232 catch (const sdbusplus::exception::SdBusError& l_ex)
233 {
234 logging::logMessage("Async PEL creation failed with an error: " +
235 std::string(l_ex.what()));
236 }
237 }
238
createSyncPel(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)239 void EventLogger::createSyncPel(
240 const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
241 const std::string& i_fileName, const std::string& i_funcName,
242 const uint8_t i_internalRc, const std::string& i_description,
243 const std::optional<std::string> i_userData1,
244 const std::optional<std::string> i_userData2,
245 const std::optional<std::string> i_symFru,
246 const std::optional<std::string> i_procedure)
247 {
248 (void)i_symFru;
249 (void)i_procedure;
250 try
251 {
252 if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
253 {
254 throw std::runtime_error("Unsupported error type received");
255 // TODO: Need to handle, instead of throwing an exception.
256 }
257
258 const std::string& l_message = m_errorMsgMap.at(i_errorType);
259
260 const std::string& l_severity =
261 (m_severityMap.find(i_severity) != m_severityMap.end()
262 ? m_severityMap.at(i_severity)
263 : m_severityMap.at(types::SeverityType::Informational));
264
265 const std::string l_description =
266 ((!i_description.empty() ? i_description : "VPD generic error"));
267
268 const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
269
270 const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
271
272 std::map<std::string, std::string> l_additionalData{
273 {"FileName", i_fileName},
274 {"FunctionName", i_funcName},
275 {"DESCRIPTION", l_description},
276 {"InteranlRc", std::to_string(i_internalRc)},
277 {"UserData1", l_userData1.c_str()},
278 {"UserData2", l_userData2.c_str()}};
279
280 auto l_bus = sdbusplus::bus::new_default();
281 auto l_method =
282 l_bus.new_method_call(constants::eventLoggingServiceName,
283 constants::eventLoggingObjectPath,
284 constants::eventLoggingInterface, "Create");
285 l_method.append(l_message, l_severity, l_additionalData);
286 l_bus.call(l_method);
287 }
288 catch (const sdbusplus::exception::SdBusError& l_ex)
289 {
290 logging::logMessage("Sync PEL creation failed with an error: " +
291 std::string(l_ex.what()));
292 }
293 }
294 } // namespace vpd
295