Break out hostlogger
Similar to what we've done elsewhere, break out hostlogger into its own
file.
Tested: Code compiles.
Change-Id: Ib9a48577878f57eb7ed4e3cf6b84a58a3ec203f6
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 46ceae1..f9a68e7 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -2007,230 +2007,6 @@
return true;
}
-inline void fillHostLoggerEntryJson(std::string_view logEntryID,
- std::string_view msg,
- nlohmann::json::object_t& logEntryJson)
-{
- // Fill in the log entry with the gathered data.
- logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
- logEntryJson["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}",
- BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
- logEntryJson["Name"] = "Host Logger Entry";
- logEntryJson["Id"] = logEntryID;
- logEntryJson["Message"] = msg;
- logEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
- logEntryJson["Severity"] = log_entry::EventSeverity::OK;
- logEntryJson["OemRecordFormat"] = "Host Logger Entry";
-}
-
-inline void requestRoutesSystemHostLogger(App& app)
-{
- BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")
- .privileges(redfish::privileges::getLogService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] =
- std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogService.v1_2_0.LogService";
- asyncResp->res.jsonValue["Name"] = "Host Logger Service";
- asyncResp->res.jsonValue["Description"] = "Host Logger Service";
- asyncResp->res.jsonValue["Id"] = "HostLogger";
- asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- });
-}
-
-inline void requestRoutesSystemHostLoggerCollection(App& app)
-{
- BMCWEB_ROUTE(app,
- "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(
- boost::beast::http::verb::
- get)([&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName) {
- query_param::QueryCapabilities capabilities = {
- .canDelegateTop = true,
- .canDelegateSkip = true,
- };
- query_param::Query delegatedQuery;
- if (!redfish::setUpRedfishRouteWithDelegation(
- app, req, asyncResp, delegatedQuery, capabilities))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- asyncResp->res.jsonValue["@odata.id"] = std::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
- BMCWEB_REDFISH_SYSTEM_URI_NAME);
- asyncResp->res.jsonValue["@odata.type"] =
- "#LogEntryCollection.LogEntryCollection";
- asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
- asyncResp->res.jsonValue["Description"] =
- "Collection of HostLogger Entries";
- nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
- logEntryArray = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = 0;
-
- std::vector<std::filesystem::path> hostLoggerFiles;
- if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
- {
- BMCWEB_LOG_DEBUG("Failed to get host log file path");
- return;
- }
- // If we weren't provided top and skip limits, use the defaults.
- size_t skip = delegatedQuery.skip.value_or(0);
- size_t top =
- delegatedQuery.top.value_or(query_param::Query::maxTop);
- size_t logCount = 0;
- // This vector only store the entries we want to expose that
- // control by skip and top.
- std::vector<std::string> logEntries;
- if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries,
- logCount))
- {
- messages::internalError(asyncResp->res);
- return;
- }
- // If vector is empty, that means skip value larger than total
- // log count
- if (logEntries.empty())
- {
- asyncResp->res.jsonValue["Members@odata.count"] = logCount;
- return;
- }
- if (!logEntries.empty())
- {
- for (size_t i = 0; i < logEntries.size(); i++)
- {
- nlohmann::json::object_t hostLogEntry;
- fillHostLoggerEntryJson(std::to_string(skip + i),
- logEntries[i], hostLogEntry);
- logEntryArray.emplace_back(std::move(hostLogEntry));
- }
-
- asyncResp->res.jsonValue["Members@odata.count"] = logCount;
- if (skip + top < logCount)
- {
- asyncResp->res.jsonValue["Members@odata.nextLink"] =
- std::format(
- "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries?$skip=",
- BMCWEB_REDFISH_SYSTEM_URI_NAME) +
- std::to_string(skip + top);
- }
- }
- });
-}
-
-inline void requestRoutesSystemHostLoggerLogEntry(App& app)
-{
- BMCWEB_ROUTE(
- app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/")
- .privileges(redfish::privileges::getLogEntry)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& systemName, const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
- {
- // Option currently returns no systems. TBD
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
- {
- messages::resourceNotFound(asyncResp->res, "ComputerSystem",
- systemName);
- return;
- }
- std::string_view targetID = param;
-
- uint64_t idInt = 0;
-
- auto [ptr, ec] =
- std::from_chars(targetID.begin(), targetID.end(), idInt);
- if (ec != std::errc{} || ptr != targetID.end())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry",
- param);
- return;
- }
-
- std::vector<std::filesystem::path> hostLoggerFiles;
- if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
- {
- BMCWEB_LOG_DEBUG("Failed to get host log file path");
- return;
- }
-
- size_t logCount = 0;
- size_t top = 1;
- std::vector<std::string> logEntries;
- // We can get specific entry by skip and top. For example, if we
- // want to get nth entry, we can set skip = n-1 and top = 1 to
- // get that entry
- if (!getHostLoggerEntries(hostLoggerFiles, idInt, top,
- logEntries, logCount))
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- if (!logEntries.empty())
- {
- nlohmann::json::object_t hostLogEntry;
- fillHostLoggerEntryJson(targetID, logEntries[0],
- hostLogEntry);
- asyncResp->res.jsonValue.update(hostLogEntry);
- return;
- }
-
- // Requested ID was not found
- messages::resourceNotFound(asyncResp->res, "LogEntry", param);
- });
-}
-
inline void handleBMCLogServicesCollectionGet(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
diff --git a/redfish-core/lib/systems_logservices_hostlogger.hpp b/redfish-core/lib/systems_logservices_hostlogger.hpp
new file mode 100644
index 0000000..1dde09c
--- /dev/null
+++ b/redfish-core/lib/systems_logservices_hostlogger.hpp
@@ -0,0 +1,250 @@
+#pragma once
+
+#include "app.hpp"
+#include "generated/enums/log_entry.hpp"
+#include "query.hpp"
+#include "registries/openbmc_message_registry.hpp"
+#include "registries/privilege_registry.hpp"
+#include "utils/time_utils.hpp"
+
+#include <cstdint>
+#include <memory>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+
+inline void fillHostLoggerEntryJson(std::string_view logEntryID,
+ std::string_view msg,
+ nlohmann::json::object_t& logEntryJson)
+{
+ // Fill in the log entry with the gathered data.
+ logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+ logEntryJson["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
+ logEntryJson["Name"] = "Host Logger Entry";
+ logEntryJson["Id"] = logEntryID;
+ logEntryJson["Message"] = msg;
+ logEntryJson["EntryType"] = log_entry::LogEntryType::Oem;
+ logEntryJson["Severity"] = log_entry::EventSeverity::OK;
+ logEntryJson["OemRecordFormat"] = "Host Logger Entry";
+}
+
+inline void requestRoutesSystemHostLogger(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")
+ .privileges(redfish::privileges::getLogService)
+ .methods(boost::beast::http::verb::get)(
+ [&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] =
+ std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogService.v1_2_0.LogService";
+ asyncResp->res.jsonValue["Name"] = "Host Logger Service";
+ asyncResp->res.jsonValue["Description"] = "Host Logger Service";
+ asyncResp->res.jsonValue["Id"] = "HostLogger";
+ asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ });
+}
+
+inline void requestRoutesSystemHostLoggerCollection(App& app)
+{
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName) {
+ query_param::QueryCapabilities capabilities = {
+ .canDelegateTop = true,
+ .canDelegateSkip = true,
+ };
+ query_param::Query delegatedQuery;
+ if (!redfish::setUpRedfishRouteWithDelegation(
+ app, req, asyncResp, delegatedQuery, capabilities))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.id"] = std::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME);
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#LogEntryCollection.LogEntryCollection";
+ asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of HostLogger Entries";
+ nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
+ logEntryArray = nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] = 0;
+
+ std::vector<std::filesystem::path> hostLoggerFiles;
+ if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+ {
+ BMCWEB_LOG_DEBUG("Failed to get host log file path");
+ return;
+ }
+ // If we weren't provided top and skip limits, use the defaults.
+ size_t skip = delegatedQuery.skip.value_or(0);
+ size_t top =
+ delegatedQuery.top.value_or(query_param::Query::maxTop);
+ size_t logCount = 0;
+ // This vector only store the entries we want to expose that
+ // control by skip and top.
+ std::vector<std::string> logEntries;
+ if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries,
+ logCount))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // If vector is empty, that means skip value larger than total
+ // log count
+ if (logEntries.empty())
+ {
+ asyncResp->res.jsonValue["Members@odata.count"] = logCount;
+ return;
+ }
+ if (!logEntries.empty())
+ {
+ for (size_t i = 0; i < logEntries.size(); i++)
+ {
+ nlohmann::json::object_t hostLogEntry;
+ fillHostLoggerEntryJson(std::to_string(skip + i),
+ logEntries[i], hostLogEntry);
+ logEntryArray.emplace_back(std::move(hostLogEntry));
+ }
+
+ asyncResp->res.jsonValue["Members@odata.count"] = logCount;
+ if (skip + top < logCount)
+ {
+ asyncResp->res.jsonValue["Members@odata.nextLink"] =
+ std::format(
+ "/redfish/v1/Systems/{}/LogServices/HostLogger/Entries?$skip=",
+ BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+ std::to_string(skip + top);
+ }
+ }
+ });
+}
+
+inline void requestRoutesSystemHostLoggerLogEntry(App& app)
+{
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/")
+ .privileges(redfish::privileges::getLogEntry)
+ .methods(boost::beast::http::verb::get)(
+ [&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& systemName, const std::string& param) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+ {
+ // Option currently returns no systems. TBD
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+ {
+ messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+ systemName);
+ return;
+ }
+ std::string_view targetID = param;
+
+ uint64_t idInt = 0;
+
+ auto [ptr, ec] =
+ std::from_chars(targetID.begin(), targetID.end(), idInt);
+ if (ec != std::errc{} || ptr != targetID.end())
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry",
+ param);
+ return;
+ }
+
+ std::vector<std::filesystem::path> hostLoggerFiles;
+ if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+ {
+ BMCWEB_LOG_DEBUG("Failed to get host log file path");
+ return;
+ }
+
+ size_t logCount = 0;
+ size_t top = 1;
+ std::vector<std::string> logEntries;
+ // We can get specific entry by skip and top. For example, if we
+ // want to get nth entry, we can set skip = n-1 and top = 1 to
+ // get that entry
+ if (!getHostLoggerEntries(hostLoggerFiles, idInt, top,
+ logEntries, logCount))
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ if (!logEntries.empty())
+ {
+ nlohmann::json::object_t hostLogEntry;
+ fillHostLoggerEntryJson(targetID, logEntries[0],
+ hostLogEntry);
+ asyncResp->res.jsonValue.update(hostLogEntry);
+ return;
+ }
+
+ // Requested ID was not found
+ messages::resourceNotFound(asyncResp->res, "LogEntry", param);
+ });
+}
+
+inline void requestRoutesSystemsLogServiceHostlogger(App& app)
+{
+ requestRoutesSystemHostLogger(app);
+ requestRoutesSystemHostLoggerCollection(app);
+ requestRoutesSystemHostLoggerLogEntry(app);
+}
+
+} // namespace redfish
diff --git a/redfish-core/src/redfish.cpp b/redfish-core/src/redfish.cpp
index 95f50ca..61f2762 100644
--- a/redfish-core/src/redfish.cpp
+++ b/redfish-core/src/redfish.cpp
@@ -39,6 +39,7 @@
#include "service_root.hpp"
#include "storage.hpp"
#include "systems.hpp"
+#include "systems_logservices_hostlogger.hpp"
#include "systems_logservices_postcodes.hpp"
#include "task.hpp"
#include "telemetry_service.hpp"
@@ -183,9 +184,7 @@
if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
{
- requestRoutesSystemHostLogger(app);
- requestRoutesSystemHostLoggerCollection(app);
- requestRoutesSystemHostLoggerLogEntry(app);
+ requestRoutesSystemsLogServiceHostlogger(app);
}
requestRoutesMessageRegistryFileCollection(app);