#include "config.h" #include "lg2_commit.hpp" #include #include #include #include #include #include #include #include namespace lg2 { namespace details { using Create = sdbusplus::client::xyz::openbmc_project::logging::Create<>; using Entry = sdbusplus::client::xyz::openbmc_project::logging::Entry<>; /* Convert syslog severity to Entry::Level */ static auto severity_from_syslog(int s) -> Entry::Level { switch (s) { case LOG_DEBUG: return Entry::Level::Debug; case LOG_INFO: return Entry::Level::Informational; case LOG_NOTICE: return Entry::Level::Notice; case LOG_WARNING: return Entry::Level::Warning; case LOG_ERR: return Entry::Level::Error; case LOG_CRIT: return Entry::Level::Critical; case LOG_ALERT: return Entry::Level::Alert; case LOG_EMERG: return Entry::Level::Emergency; } return Entry::Level::Emergency; } using AdditionalData_t = std::map; /* Create AdditionalData from the sdbusplus event json. */ static auto data_from_json(sdbusplus::exception::generated_event_base& t) -> AdditionalData_t { AdditionalData_t result{}; auto j = t.to_json()[t.name()]; for (const auto& item : j.items()) { // Special cases for the "_SOURCE" fields, which contain debug // information about the origin of the event. if (item.key() == "_SOURCE") { for (const auto& source_item : item.value().items()) { if (source_item.key() == "PID") { result.emplace("_PID", source_item.value().dump()); continue; } if (source_item.key() == "FILE") { result.emplace("_CODE_FILE", source_item.value()); continue; } if (source_item.key() == "FUNCTION") { result.emplace("_CODE_FUNC", source_item.value()); continue; } if (source_item.key() == "LINE") { result.emplace("_CODE_LINE", source_item.value().dump()); continue; } } continue; } if (item.value().type() == nlohmann::json::value_t::string) { result.emplace(item.key(), item.value()); } else { result.emplace(item.key(), item.value().dump()); } } return result; } auto extractEvent(sdbusplus::exception::generated_event_base&& t) -> std::tuple> { auto data = data_from_json(t); std::vector additional_data = {}; for (auto& [key, data] : data) { additional_data.emplace_back(key + "=" + data); } return {t.name(), severity_from_syslog(t.severity()), std::move(additional_data)}; } } // namespace details auto commit(sdbusplus::exception::generated_event_base&& t) -> sdbusplus::message::object_path { if constexpr (LG2_COMMIT_JOURNAL) { lg2::error("OPENBMC_MESSAGE_ID={DATA}", "DATA", t.to_json().dump()); } if constexpr (LG2_COMMIT_DBUS) { using details::Create; auto b = sdbusplus::bus::new_default(); auto m = b.new_method_call(Create::default_service, Create::instance_path, Create::interface, "Create"); m.append(t.name(), details::severity_from_syslog(t.severity()), details::data_from_json(t)); auto reply = b.call(m); return reply.unpack(); } return {}; } auto commit(sdbusplus::async::context& ctx, sdbusplus::exception::generated_event_base&& t) -> sdbusplus::async::task { using details::Create; if constexpr (LG2_COMMIT_JOURNAL) { lg2::error("OPENBMC_MESSAGE_ID={DATA}", "DATA", t.to_json().dump()); } if constexpr (LG2_COMMIT_DBUS) { co_return co_await Create(ctx) .service(Create::default_service) .path(Create::instance_path) .create(t.name(), details::severity_from_syslog(t.severity()), details::data_from_json(t)); } co_return {}; } } // namespace lg2