lg2: commit: add support for journal-only method
The design document for the new event system references an
option to log events to the journal rather than to dbus[1] using
the 'OPENBMC_MESSAGE_ID' identifier. Add support and test cases
for this as a meson option.
[1]: https://github.com/openbmc/docs/blob/master/designs/event-logging.md#phosphor-logging
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I6cb94453c6cc95a9ccbbbc11859b70ef12d375fd
diff --git a/config/config.h.meson b/config/config.h.meson
index 698b09d..f852bab 100644
--- a/config/config.h.meson
+++ b/config/config.h.meson
@@ -36,4 +36,7 @@
static constexpr auto FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION = "5";
static constexpr size_t CLASS_VERSION = 5;
+static constexpr bool LG2_COMMIT_DBUS = @lg2_commit_dbus@;
+static constexpr bool LG2_COMMIT_JOURNAL = @lg2_commit_journal@;
+
// vim: ft=cpp
diff --git a/config/meson.build b/config/meson.build
index 661ded3..946ec39 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -4,6 +4,16 @@
conf_data.set('error_info_cap', get_option('error_info_cap'))
conf_data.set('rsyslog_server_conf', get_option('rsyslog_server_conf'))
+lg2_commit_strategy = get_option('lg2_commit_strategy')
+conf_data.set(
+ 'lg2_commit_dbus',
+ lg2_commit_strategy == 'dbus' or lg2_commit_strategy == 'both' ? 'true' : 'false',
+)
+conf_data.set(
+ 'lg2_commit_journal',
+ lg2_commit_strategy == 'journal' or lg2_commit_strategy == 'both' ? 'true' : 'false',
+)
+
cxx = meson.get_compiler('cpp')
if cxx.has_header('poll.h')
add_project_arguments('-DPLDM_HAS_POLL=1', language: 'cpp')
@@ -15,5 +25,5 @@
input: 'config.h.meson',
output: 'config.h',
configuration: conf_data,
- )
+ ),
)
diff --git a/lib/lg2_commit.cpp b/lib/lg2_commit.cpp
index 6f11a4c..4f37cb6 100644
--- a/lib/lg2_commit.cpp
+++ b/lib/lg2_commit.cpp
@@ -1,8 +1,11 @@
+#include "config.h"
+
#include "lg2_commit.hpp"
#include <sys/syslog.h>
#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/lg2/commit.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/exception.hpp>
@@ -97,26 +100,47 @@
auto commit(sdbusplus::exception::generated_event_base&& t)
-> sdbusplus::message::object_path
{
- auto b = sdbusplus::bus::new_default();
- auto m = b.new_method_call(Create::default_service, Create::instance_path,
- Create::interface, "Create");
+ if constexpr (LG2_COMMIT_JOURNAL)
+ {
+ lg2::error("OPENBMC_MESSAGE_ID={DATA}", "DATA", t.to_json().dump());
+ }
- m.append(t.name(), severity_from_syslog(t.severity()), data_from_json(t));
+ if constexpr (LG2_COMMIT_DBUS)
+ {
+ auto b = sdbusplus::bus::new_default();
+ auto m =
+ b.new_method_call(Create::default_service, Create::instance_path,
+ Create::interface, "Create");
- auto reply = b.call(m);
+ m.append(t.name(), severity_from_syslog(t.severity()),
+ data_from_json(t));
- return reply.unpack<sdbusplus::message::object_path>();
+ 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>
{
- co_return co_await Create(ctx)
- .service(Create::default_service)
- .path(Create::instance_path)
- .create(t.name(), severity_from_syslog(t.severity()),
- data_from_json(t));
+ 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(), severity_from_syslog(t.severity()),
+ data_from_json(t));
+ }
+ co_return {};
}
auto extractEvent(sdbusplus::exception::generated_event_base&& t)
diff --git a/meson.options b/meson.options
index 0dd7c3e..2bab22c 100644
--- a/meson.options
+++ b/meson.options
@@ -41,3 +41,10 @@
value: '/etc/rsyslog.d/server.conf',
description: 'Path to rsyslog server conf file',
)
+
+option(
+ 'lg2_commit_strategy',
+ type: 'combo',
+ choices: ['dbus', 'journal', 'both'],
+ value: 'both'
+)
diff --git a/test/log_manager_dbus_tests.cpp b/test/log_manager_dbus_tests.cpp
index e2bc8be..12136c1 100644
--- a/test/log_manager_dbus_tests.cpp
+++ b/test/log_manager_dbus_tests.cpp
@@ -85,6 +85,43 @@
};
std::unique_ptr<fixture_data> data;
+
+ static constexpr auto journal_unavailable = "UNAVAILABLE";
+ std::string last_journal_entry()
+ {
+ if constexpr (LG2_COMMIT_JOURNAL)
+ {
+ // When running under Docker, the journal is not available and
+ // sd-journal calls just silently pass. Return a string to make
+ // it obvious.
+ if (!std::filesystem::exists("/run/systemd/journal/socket"))
+ {
+ return journal_unavailable;
+ }
+
+ sd_journal* j = nullptr;
+
+ sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+ sd_journal_add_match(j, "SYSLOG_IDENTIFIER=test_manager_dbus_tests",
+ SIZE_MAX);
+
+ SD_JOURNAL_FOREACH_BACKWARDS(j)
+ {
+ const char* data = nullptr;
+ size_t length = 0;
+
+ sd_journal_get_data(j, "MESSAGE", (const void**)&data, &length);
+
+ std::string entry(data, length);
+ if (entry.contains("OPENBMC_MESSAGE_ID="))
+ {
+ return entry;
+ }
+ }
+ }
+
+ return "";
+ }
};
// Ensure we can successfully create and throw an sdbusplus event.
@@ -100,11 +137,27 @@
TEST_F(TestLogManagerDbus, CallCommitSync)
{
auto path = lg2::commit(LoggingCleared("NUMBER_OF_LOGS", 3));
- ASSERT_FALSE(path.str.empty());
- EXPECT_THAT(path.str,
- ::testing::StartsWith(
- std::filesystem::path(LoggingEntry::namespace_path::value) /
- LoggingEntry::namespace_path::entry));
+
+ if constexpr (LG2_COMMIT_DBUS)
+ {
+ ASSERT_FALSE(path.str.empty());
+ EXPECT_THAT(
+ path.str,
+ ::testing::StartsWith(
+ std::filesystem::path(LoggingEntry::namespace_path::value) /
+ LoggingEntry::namespace_path::entry));
+ }
+
+ if constexpr (LG2_COMMIT_JOURNAL)
+ {
+ auto entry = last_journal_entry();
+ if (entry != journal_unavailable)
+ {
+ EXPECT_THAT(entry, ::testing::HasSubstr(
+ "\"xyz.openbmc_project.Logging.Cleared\":"));
+ EXPECT_THAT(entry, ::testing::HasSubstr("\"NUMBER_OF_LOGS\":3"));
+ }
+ }
}
// Call the asynchronous version of the commit function and verify that the
@@ -121,30 +174,33 @@
path = co_await lg2::commit(data->client_ctx,
LoggingCleared("NUMBER_OF_LOGS", 6));
- // Grab the additional data.
- auto additionalData = co_await LoggingEntry(data->client_ctx)
- .service(Entry::default_service)
- .path(path.str)
- .additional_data();
-
- // Extract the NUMBER_OF_LOGS, PID, and CODE_FILE.
- for (const auto& value : additionalData)
+ if constexpr (LG2_COMMIT_DBUS)
{
- auto getValue = [&value]() {
- return value.substr(value.find_first_of('=') + 1);
- };
+ // Grab the additional data.
+ auto additionalData = co_await LoggingEntry(data->client_ctx)
+ .service(Entry::default_service)
+ .path(path.str)
+ .additional_data();
- if (value.starts_with("NUMBER_OF_LOGS="))
+ // Extract the NUMBER_OF_LOGS, PID, and CODE_FILE.
+ for (const auto& value : additionalData)
{
- log_count = getValue();
- }
- if (value.starts_with("_PID="))
- {
- pid = std::stoull(getValue());
- }
- if (value.starts_with("_CODE_FILE="))
- {
- source_file = getValue();
+ auto getValue = [&value]() {
+ return value.substr(value.find_first_of('=') + 1);
+ };
+
+ if (value.starts_with("NUMBER_OF_LOGS="))
+ {
+ log_count = getValue();
+ }
+ if (value.starts_with("_PID="))
+ {
+ pid = std::stoull(getValue());
+ }
+ if (value.starts_with("_CODE_FILE="))
+ {
+ source_file = getValue();
+ }
}
}
@@ -153,17 +209,32 @@
run(create_log());
- ASSERT_FALSE(path.str.empty());
- ASSERT_FALSE(log_count.empty());
+ if constexpr (LG2_COMMIT_DBUS)
+ {
+ ASSERT_FALSE(path.str.empty());
+ ASSERT_FALSE(log_count.empty());
- EXPECT_THAT(path.str,
- ::testing::StartsWith(
- std::filesystem::path(LoggingEntry::namespace_path::value) /
- LoggingEntry::namespace_path::entry));
+ EXPECT_THAT(
+ path.str,
+ ::testing::StartsWith(
+ std::filesystem::path(LoggingEntry::namespace_path::value) /
+ LoggingEntry::namespace_path::entry));
- EXPECT_EQ(log_count, "6");
- EXPECT_EQ(pid, getpid());
- EXPECT_EQ(source_file, std::source_location::current().file_name());
+ EXPECT_EQ(log_count, "6");
+ EXPECT_EQ(pid, getpid());
+ EXPECT_EQ(source_file, std::source_location::current().file_name());
+ }
+
+ if constexpr (LG2_COMMIT_JOURNAL)
+ {
+ auto entry = last_journal_entry();
+ if (entry != journal_unavailable)
+ {
+ EXPECT_THAT(entry, ::testing::HasSubstr(
+ "\"xyz.openbmc_project.Logging.Cleared\":"));
+ EXPECT_THAT(entry, ::testing::HasSubstr("\"NUMBER_OF_LOGS\":6"));
+ }
+ }
}
} // namespace phosphor::logging::test