Break out journal utils
A number of the journald utilities are distinct from Redfish, and could
be reused. Functions moved are copy/paste with no modifications.
Tested:
Journald LogService GET still functions correctly
Redfish service validator fails no new checks.
Change-Id: Icf1c28152e14f3e0c1c5203aac50c40d56bb272e
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/redfish-core/include/utils/journal_utils.hpp b/redfish-core/include/utils/journal_utils.hpp
new file mode 100644
index 0000000..af8f3a7
--- /dev/null
+++ b/redfish-core/include/utils/journal_utils.hpp
@@ -0,0 +1,148 @@
+#pragma once
+
+#include "logging.hpp"
+#include "utils/time_utils.hpp"
+
+#include <systemd/sd-journal.h>
+
+#include <nlohmann/json.hpp>
+
+#include <string>
+#include <string_view>
+
+namespace redfish
+{
+
+inline int getJournalMetadata(sd_journal* journal, const char* field,
+ std::string_view& contents)
+{
+ const char* data = nullptr;
+ size_t length = 0;
+ int ret = 0;
+ // Get the metadata from the requested field of the journal entry
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ const void** dataVoid = reinterpret_cast<const void**>(&data);
+
+ ret = sd_journal_get_data(journal, field, dataVoid, &length);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ contents = std::string_view(data, length);
+ // Only use the content after the "=" character.
+ contents.remove_prefix(std::min(contents.find('=') + 1, contents.size()));
+ return ret;
+}
+
+inline int getJournalMetadataInt(sd_journal* journal, const char* field,
+ long int& contents)
+{
+ std::string_view metadata;
+ // Get the metadata from the requested field of the journal entry
+ int ret = getJournalMetadata(journal, field, metadata);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ std::from_chars_result res =
+ std::from_chars(&*metadata.begin(), &*metadata.end(), contents);
+ if (res.ec != std::error_code{} || res.ptr != &*metadata.end())
+ {
+ return -1;
+ }
+ return 0;
+}
+
+inline bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp)
+{
+ int ret = 0;
+ uint64_t timestamp = 0;
+ ret = sd_journal_get_realtime_usec(journal, ×tamp);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", ret);
+ return false;
+ }
+ entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp);
+ return true;
+}
+
+inline bool fillBMCJournalLogEntryJson(
+ sd_journal* journal, nlohmann::json::object_t& bmcJournalLogEntryJson)
+{
+ char* cursor = nullptr;
+ int ret = sd_journal_get_cursor(journal, &cursor);
+ if (ret < 0)
+ {
+ return false;
+ }
+ std::unique_ptr<char*> cursorptr = std::make_unique<char*>(cursor);
+ std::string bmcJournalLogEntryID(cursor);
+
+ // Get the Log Entry contents
+ std::string message;
+ std::string_view syslogID;
+ ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_DEBUG("Failed to read SYSLOG_IDENTIFIER field: {}", ret);
+ }
+ if (!syslogID.empty())
+ {
+ message += std::string(syslogID) + ": ";
+ }
+
+ std::string_view msg;
+ ret = getJournalMetadata(journal, "MESSAGE", msg);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to read MESSAGE field: {}", ret);
+ return false;
+ }
+ message += std::string(msg);
+
+ // Get the severity from the PRIORITY field
+ long int severity = 8; // Default to an invalid priority
+ ret = getJournalMetadataInt(journal, "PRIORITY", severity);
+ if (ret < 0)
+ {
+ BMCWEB_LOG_DEBUG("Failed to read PRIORITY field: {}", ret);
+ }
+
+ // Get the Created time from the timestamp
+ std::string entryTimeStr;
+ if (!getEntryTimestamp(journal, entryTimeStr))
+ {
+ return false;
+ }
+
+ // Fill in the log entry with the gathered data
+ bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+
+ std::string entryIdBase64 =
+ crow::utility::base64encode(bmcJournalLogEntryID);
+
+ bmcJournalLogEntryJson["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Managers/{}/LogServices/Journal/Entries/{}",
+ BMCWEB_REDFISH_MANAGER_URI_NAME, entryIdBase64);
+ bmcJournalLogEntryJson["Name"] = "BMC Journal Entry";
+ bmcJournalLogEntryJson["Id"] = entryIdBase64;
+ bmcJournalLogEntryJson["Message"] = std::move(message);
+ bmcJournalLogEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
+ log_entry::EventSeverity severityEnum = log_entry::EventSeverity::OK;
+ if (severity <= 2)
+ {
+ severityEnum = log_entry::EventSeverity::Critical;
+ }
+ else if (severity <= 4)
+ {
+ severityEnum = log_entry::EventSeverity::Warning;
+ }
+
+ bmcJournalLogEntryJson["Severity"] = severityEnum;
+ bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry";
+ bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr);
+ return true;
+}
+
+} // namespace redfish
diff --git a/redfish-core/lib/manager_logservices_journal.hpp b/redfish-core/lib/manager_logservices_journal.hpp
index 0a90390..e5bc35e 100644
--- a/redfish-core/lib/manager_logservices_journal.hpp
+++ b/redfish-core/lib/manager_logservices_journal.hpp
@@ -6,6 +6,7 @@
#include "query.hpp"
#include "registries/base_message_registry.hpp"
#include "registries/privilege_registry.hpp"
+#include "utils/journal_utils.hpp"
#include "utils/time_utils.hpp"
#include <systemd/sd-journal.h>
@@ -20,138 +21,6 @@
namespace redfish
{
-inline int getJournalMetadata(sd_journal* journal, const char* field,
- std::string_view& contents)
-{
- const char* data = nullptr;
- size_t length = 0;
- int ret = 0;
- // Get the metadata from the requested field of the journal entry
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const void** dataVoid = reinterpret_cast<const void**>(&data);
-
- ret = sd_journal_get_data(journal, field, dataVoid, &length);
- if (ret < 0)
- {
- return ret;
- }
- contents = std::string_view(data, length);
- // Only use the content after the "=" character.
- contents.remove_prefix(std::min(contents.find('=') + 1, contents.size()));
- return ret;
-}
-
-inline int getJournalMetadataInt(sd_journal* journal, const char* field,
- long int& contents)
-{
- std::string_view metadata;
- // Get the metadata from the requested field of the journal entry
- int ret = getJournalMetadata(journal, field, metadata);
- if (ret < 0)
- {
- return ret;
- }
- std::from_chars_result res =
- std::from_chars(&*metadata.begin(), &*metadata.end(), contents);
- if (res.ec != std::error_code{} || res.ptr != &*metadata.end())
- {
- return -1;
- }
- return 0;
-}
-
-inline bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp)
-{
- int ret = 0;
- uint64_t timestamp = 0;
- ret = sd_journal_get_realtime_usec(journal, ×tamp);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("Failed to read entry timestamp: {}", ret);
- return false;
- }
- entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp);
- return true;
-}
-
-inline bool fillBMCJournalLogEntryJson(
- sd_journal* journal, nlohmann::json::object_t& bmcJournalLogEntryJson)
-{
- char* cursor = nullptr;
- int ret = sd_journal_get_cursor(journal, &cursor);
- if (ret < 0)
- {
- return false;
- }
- std::unique_ptr<char*> cursorptr = std::make_unique<char*>(cursor);
- std::string bmcJournalLogEntryID(cursor);
-
- // Get the Log Entry contents
- std::string message;
- std::string_view syslogID;
- ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID);
- if (ret < 0)
- {
- BMCWEB_LOG_DEBUG("Failed to read SYSLOG_IDENTIFIER field: {}", ret);
- }
- if (!syslogID.empty())
- {
- message += std::string(syslogID) + ": ";
- }
-
- std::string_view msg;
- ret = getJournalMetadata(journal, "MESSAGE", msg);
- if (ret < 0)
- {
- BMCWEB_LOG_ERROR("Failed to read MESSAGE field: {}", ret);
- return false;
- }
- message += std::string(msg);
-
- // Get the severity from the PRIORITY field
- long int severity = 8; // Default to an invalid priority
- ret = getJournalMetadataInt(journal, "PRIORITY", severity);
- if (ret < 0)
- {
- BMCWEB_LOG_DEBUG("Failed to read PRIORITY field: {}", ret);
- }
-
- // Get the Created time from the timestamp
- std::string entryTimeStr;
- if (!getEntryTimestamp(journal, entryTimeStr))
- {
- return false;
- }
-
- // Fill in the log entry with the gathered data
- bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
-
- std::string entryIdBase64 =
- crow::utility::base64encode(bmcJournalLogEntryID);
-
- bmcJournalLogEntryJson["@odata.id"] = boost::urls::format(
- "/redfish/v1/Managers/{}/LogServices/Journal/Entries/{}",
- BMCWEB_REDFISH_MANAGER_URI_NAME, entryIdBase64);
- bmcJournalLogEntryJson["Name"] = "BMC Journal Entry";
- bmcJournalLogEntryJson["Id"] = entryIdBase64;
- bmcJournalLogEntryJson["Message"] = std::move(message);
- bmcJournalLogEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
- log_entry::EventSeverity severityEnum = log_entry::EventSeverity::OK;
- if (severity <= 2)
- {
- severityEnum = log_entry::EventSeverity::Critical;
- }
- else if (severity <= 4)
- {
- severityEnum = log_entry::EventSeverity::Warning;
- }
-
- bmcJournalLogEntryJson["Severity"] = severityEnum;
- bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry";
- bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr);
- return true;
-}
-
inline void handleManagersLogServiceJournalGet(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,