blob: d5ae41badb3f58be5fee922306d26b73d3881cd8 [file] [log] [blame]
#include "config.h"
#include "lg2_commit.hpp"
#include <sys/syslog.h>
#include <nlohmann/json.hpp>
#include <phosphor-logging/commit.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/exception.hpp>
#include <xyz/openbmc_project/Logging/Create/client.hpp>
#include <xyz/openbmc_project/Logging/Entry/client.hpp>
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<std::string, std::string>;
/* 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;
}
result.emplace(item.key(), item.value().dump());
}
return result;
}
auto extractEvent(sdbusplus::exception::generated_event_base&& t)
-> std::tuple<std::string, Entry::Level, std::vector<std::string>>
{
auto data = data_from_json(t);
std::vector<std::string> 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<sdbusplus::message::object_path>();
}
return {};
}
auto commit(sdbusplus::async::context& ctx,
sdbusplus::exception::generated_event_base&& t)
-> sdbusplus::async::task<sdbusplus::message::object_path>
{
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