xref: /openbmc/openpower-vpd-parser/vpd-manager/src/event_logger.cpp (revision fa5e4d325ef9cea3c841fe89d202c340f92bd8c6)
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