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 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 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 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 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 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