1 #include <sys/syslog.h> 2 3 #include <nlohmann/json.hpp> 4 #include <phosphor-logging/lg2/commit.hpp> 5 #include <sdbusplus/async.hpp> 6 #include <sdbusplus/exception.hpp> 7 #include <xyz/openbmc_project/Logging/Create/client.hpp> 8 #include <xyz/openbmc_project/Logging/Entry/client.hpp> 9 10 namespace lg2::details 11 { 12 13 using Create = sdbusplus::client::xyz::openbmc_project::logging::Create<>; 14 using Entry = sdbusplus::client::xyz::openbmc_project::logging::Entry<>; 15 16 /* Convert syslog severity to Entry::Level */ 17 static auto severity_from_syslog(int s) -> Entry::Level 18 { 19 switch (s) 20 { 21 case LOG_DEBUG: 22 return Entry::Level::Debug; 23 24 case LOG_INFO: 25 return Entry::Level::Informational; 26 27 case LOG_NOTICE: 28 return Entry::Level::Notice; 29 30 case LOG_WARNING: 31 return Entry::Level::Warning; 32 33 case LOG_ERR: 34 return Entry::Level::Error; 35 36 case LOG_CRIT: 37 return Entry::Level::Critical; 38 39 case LOG_ALERT: 40 return Entry::Level::Alert; 41 42 case LOG_EMERG: 43 return Entry::Level::Emergency; 44 } 45 return Entry::Level::Emergency; 46 } 47 48 using AdditionalData_t = std::map<std::string, std::string>; 49 50 /* Create AdditionalData from the sdbusplus event json. */ 51 static auto data_from_json(sdbusplus::exception::generated_event_base& t) 52 -> AdditionalData_t 53 { 54 AdditionalData_t result{}; 55 56 auto j = t.to_json()[t.name()]; 57 for (const auto& item : j.items()) 58 { 59 // Special cases for the "_SOURCE" fields, which contain debug 60 // information about the origin of the event. 61 if (item.key() == "_SOURCE") 62 { 63 for (const auto& source_item : item.value().items()) 64 { 65 if (source_item.key() == "PID") 66 { 67 result.emplace("_PID", source_item.value().dump()); 68 continue; 69 } 70 if (source_item.key() == "FILE") 71 { 72 result.emplace("_CODE_FILE", source_item.value()); 73 continue; 74 } 75 if (source_item.key() == "FUNCTION") 76 { 77 result.emplace("_CODE_FUNC", source_item.value()); 78 continue; 79 } 80 if (source_item.key() == "LINE") 81 { 82 result.emplace("_CODE_LINE", source_item.value().dump()); 83 continue; 84 } 85 } 86 continue; 87 } 88 89 result.emplace(item.key(), item.value().dump()); 90 } 91 92 return result; 93 } 94 95 auto commit(sdbusplus::exception::generated_event_base&& t) 96 -> sdbusplus::message::object_path 97 { 98 auto b = sdbusplus::bus::new_default(); 99 auto m = b.new_method_call(Create::default_service, Create::instance_path, 100 Create::interface, "Create"); 101 102 m.append(t.name(), severity_from_syslog(t.severity()), data_from_json(t)); 103 104 auto reply = b.call(m); 105 106 return reply.unpack<sdbusplus::message::object_path>(); 107 } 108 109 auto commit(sdbusplus::async::context& ctx, 110 sdbusplus::exception::generated_event_base&& t) 111 -> sdbusplus::async::task<sdbusplus::message::object_path> 112 { 113 co_return co_await Create(ctx) 114 .service(Create::default_service) 115 .path(Create::instance_path) 116 .create(t.name(), severity_from_syslog(t.severity()), 117 data_from_json(t)); 118 } 119 120 } // namespace lg2::details 121