1515#include " query.hpp"
1616#include " registries/privilege_registry.hpp"
1717#include " utils/query_param.hpp"
18+ #include " utils/systems_utils.hpp"
1819
1920#include < boost/beast/http/verb.hpp>
2021#include < boost/url/format.hpp>
@@ -38,10 +39,38 @@ namespace redfish
3839{
3940constexpr const char * hostLoggerFolderPath = " /var/log/console" ;
4041
42+ // default output dir for phosphor-hostlogger in buffer mode
43+ constexpr const char * multiHostLoggerFolderPath = " /var/lib/obmc/hostlogs" ;
44+
4145inline bool getHostLoggerFiles (
4246 const std::string& hostLoggerFilePath,
43- std::vector<std::filesystem::path>& hostLoggerFiles)
47+ std::vector<std::filesystem::path>& hostLoggerFiles,
48+ const uint64_t computerSystemIndex)
4449{
50+ if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
51+ {
52+ std::string logFilesPath = multiHostLoggerFolderPath;
53+ logFilesPath.append (" /host" + std::to_string (computerSystemIndex));
54+
55+ BMCWEB_LOG_DEBUG (" LogFilesPath: {}" , logFilesPath);
56+
57+ std::error_code ec;
58+ std::filesystem::directory_iterator logPath (logFilesPath, ec);
59+
60+ if (ec)
61+ {
62+ BMCWEB_LOG_WARNING (" {}" , ec.message ());
63+ return false ;
64+ }
65+ for (const std::filesystem::directory_entry& it : logPath)
66+ {
67+ BMCWEB_LOG_DEBUG (" Logfile: {}" , it.path ().filename ().string ());
68+ hostLoggerFiles.emplace_back (it.path ());
69+ }
70+ // TODO 07/13/25-19:58 olek: need to sort vector by timestamps
71+ return true ;
72+ }
73+
4574 std::error_code ec;
4675 std::filesystem::directory_iterator logPath (hostLoggerFilePath, ec);
4776 if (ec)
@@ -96,15 +125,15 @@ inline bool getHostLoggerEntries(
96125 return true ;
97126}
98127
99- inline void fillHostLoggerEntryJson (std::string_view logEntryID,
100- std::string_view msg ,
101- nlohmann::json::object_t & logEntryJson)
128+ inline void fillHostLoggerEntryJson (
129+ const std::string& systemName, std::string_view logEntryID ,
130+ std::string_view msg, nlohmann::json::object_t & logEntryJson)
102131{
103132 // Fill in the log entry with the gathered data.
104133 logEntryJson[" @odata.type" ] = " #LogEntry.v1_9_0.LogEntry" ;
105134 logEntryJson[" @odata.id" ] = boost::urls::format (
106- " /redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}" ,
107- BMCWEB_REDFISH_SYSTEM_URI_NAME, logEntryID);
135+ " /redfish/v1/Systems/{}/LogServices/HostLogger/Entries/{}" , systemName,
136+ logEntryID);
108137 logEntryJson[" Name" ] = " Host Logger Entry" ;
109138 logEntryJson[" Id" ] = logEntryID;
110139 logEntryJson[" Message" ] = msg;
@@ -122,62 +151,33 @@ inline void handleSystemsLogServicesHostloggerGet(
122151 {
123152 return ;
124153 }
125- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
126- {
127- // Option currently returns no systems. TBD
128- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
129- systemName);
130- return ;
131- }
132- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
154+
155+ if (!BMCWEB_REDFISH_SYSTEM_URI_NAME.empty ())
133156 {
134- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
135- systemName);
136- return ;
157+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
158+ {
159+ messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
160+ systemName);
161+ return ;
162+ }
137163 }
138- asyncResp->res .jsonValue [" @odata.id" ] =
139- std::format (" /redfish/v1/Systems/{}/LogServices/HostLogger" ,
140- BMCWEB_REDFISH_SYSTEM_URI_NAME);
164+ asyncResp->res .jsonValue [" @odata.id" ] = std::format (
165+ " /redfish/v1/Systems/{}/LogServices/HostLogger" , systemName);
141166 asyncResp->res .jsonValue [" @odata.type" ] = " #LogService.v1_2_0.LogService" ;
142167 asyncResp->res .jsonValue [" Name" ] = " Host Logger Service" ;
143168 asyncResp->res .jsonValue [" Description" ] = " Host Logger Service" ;
144169 asyncResp->res .jsonValue [" Id" ] = " HostLogger" ;
145- asyncResp->res .jsonValue [" Entries" ][" @odata.id" ] =
146- std::format (" /redfish/v1/Systems/{}/LogServices/HostLogger/Entries" ,
147- BMCWEB_REDFISH_SYSTEM_URI_NAME);
170+ asyncResp->res .jsonValue [" Entries" ][" @odata.id" ] = std::format (
171+ " /redfish/v1/Systems/{}/LogServices/HostLogger/Entries" , systemName);
148172}
149173
150- inline void handleSystemsLogServicesHostloggerEntriesGet (
151- App& app, const crow::Request& req,
174+ inline void processSystemsLogServicesHostloggerEntriesGet (
152175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
153- const std::string& systemName)
176+ const std::string& systemName, query_param::Query& delegatedQuery,
177+ const uint64_t computerSystemIndex)
154178{
155- query_param::QueryCapabilities capabilities = {
156- .canDelegateTop = true ,
157- .canDelegateSkip = true ,
158- };
159- query_param::Query delegatedQuery;
160- if (!redfish::setUpRedfishRouteWithDelegation (app, req, asyncResp,
161- delegatedQuery, capabilities))
162- {
163- return ;
164- }
165- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
166- {
167- // Option currently returns no systems. TBD
168- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
169- systemName);
170- return ;
171- }
172- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
173- {
174- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
175- systemName);
176- return ;
177- }
178- asyncResp->res .jsonValue [" @odata.id" ] =
179- std::format (" /redfish/v1/Systems/{}/LogServices/HostLogger/Entries" ,
180- BMCWEB_REDFISH_SYSTEM_URI_NAME);
179+ asyncResp->res .jsonValue [" @odata.id" ] = std::format (
180+ " /redfish/v1/Systems/{}/LogServices/HostLogger/Entries" , systemName);
181181 asyncResp->res .jsonValue [" @odata.type" ] =
182182 " #LogEntryCollection.LogEntryCollection" ;
183183 asyncResp->res .jsonValue [" Name" ] = " HostLogger Entries" ;
@@ -188,7 +188,9 @@ inline void handleSystemsLogServicesHostloggerEntriesGet(
188188 asyncResp->res .jsonValue [" Members@odata.count" ] = 0 ;
189189
190190 std::vector<std::filesystem::path> hostLoggerFiles;
191- if (!getHostLoggerFiles (hostLoggerFolderPath, hostLoggerFiles))
191+
192+ if (!getHostLoggerFiles (hostLoggerFolderPath, hostLoggerFiles,
193+ computerSystemIndex))
192194 {
193195 BMCWEB_LOG_DEBUG (" Failed to get host log file path" );
194196 return ;
@@ -217,8 +219,8 @@ inline void handleSystemsLogServicesHostloggerEntriesGet(
217219 for (size_t i = 0 ; i < logEntries.size (); i++)
218220 {
219221 nlohmann::json::object_t hostLogEntry;
220- fillHostLoggerEntryJson (std::to_string (skip + i), logEntries[i] ,
221- hostLogEntry);
222+ fillHostLoggerEntryJson (systemName, std::to_string (skip + i),
223+ logEntries[i], hostLogEntry);
222224 logEntryArray.emplace_back (std::move (hostLogEntry));
223225 }
224226
@@ -228,36 +230,48 @@ inline void handleSystemsLogServicesHostloggerEntriesGet(
228230 asyncResp->res .jsonValue [" Members@odata.nextLink" ] =
229231 std::format (
230232 " /redfish/v1/Systems/{}/LogServices/HostLogger/Entries?$skip=" ,
231- BMCWEB_REDFISH_SYSTEM_URI_NAME ) +
233+ systemName ) +
232234 std::to_string (skip + top);
233235 }
234236 }
235237}
236-
237- inline void handleSystemsLogServicesHostloggerEntriesEntryGet (
238+ inline void handleSystemsLogServicesHostloggerEntriesGet (
238239 App& app, const crow::Request& req,
239240 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
240- const std::string& systemName, const std::string& param )
241+ const std::string& systemName)
241242{
242- if (!redfish::setUpRedfishRoute (app, req, asyncResp))
243- {
244- return ;
245- }
246- if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
243+ query_param::QueryCapabilities capabilities = {
244+ .canDelegateTop = true ,
245+ .canDelegateSkip = true ,
246+ };
247+ query_param::Query delegatedQuery;
248+ if (!redfish::setUpRedfishRouteWithDelegation (app, req, asyncResp,
249+ delegatedQuery, capabilities))
247250 {
248- // Option currently returns no systems. TBD
249- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
250- systemName);
251251 return ;
252252 }
253- if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
253+ if (! BMCWEB_REDFISH_SYSTEM_URI_NAME. empty () )
254254 {
255- messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
256- systemName);
257- return ;
255+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
256+ {
257+ messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
258+ systemName);
259+ return ;
260+ }
258261 }
259- std::string_view targetID = param;
260262
263+ getComputerSystemIndex (
264+ asyncResp, systemName,
265+ std::bind_front (processSystemsLogServicesHostloggerEntriesGet,
266+ asyncResp, systemName, delegatedQuery));
267+ }
268+
269+ inline void processSystemsLogServicesHostloggerEntriesEntryGet (
270+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
271+ const std::string& systemName, const std::string& param,
272+ const uint64_t computerSystemIndex)
273+ {
274+ std::string_view targetID = param;
261275 uint64_t idInt = 0 ;
262276
263277 auto [ptr, ec] = std::from_chars (targetID.begin (), targetID.end (), idInt);
@@ -268,7 +282,8 @@ inline void handleSystemsLogServicesHostloggerEntriesEntryGet(
268282 }
269283
270284 std::vector<std::filesystem::path> hostLoggerFiles;
271- if (!getHostLoggerFiles (hostLoggerFolderPath, hostLoggerFiles))
285+ if (!getHostLoggerFiles (hostLoggerFolderPath, hostLoggerFiles,
286+ computerSystemIndex))
272287 {
273288 BMCWEB_LOG_DEBUG (" Failed to get host log file path" );
274289 return ;
@@ -290,7 +305,8 @@ inline void handleSystemsLogServicesHostloggerEntriesEntryGet(
290305 if (!logEntries.empty ())
291306 {
292307 nlohmann::json::object_t hostLogEntry;
293- fillHostLoggerEntryJson (targetID, logEntries[0 ], hostLogEntry);
308+ fillHostLoggerEntryJson (systemName, targetID, logEntries[0 ],
309+ hostLogEntry);
294310 asyncResp->res .jsonValue .update (hostLogEntry);
295311 return ;
296312 }
@@ -299,6 +315,31 @@ inline void handleSystemsLogServicesHostloggerEntriesEntryGet(
299315 messages::resourceNotFound (asyncResp->res , " LogEntry" , param);
300316}
301317
318+ inline void handleSystemsLogServicesHostloggerEntriesEntryGet (
319+ App& app, const crow::Request& req,
320+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
321+ const std::string& systemName, const std::string& param)
322+ {
323+ if (!redfish::setUpRedfishRoute (app, req, asyncResp))
324+ {
325+ return ;
326+ }
327+ if (!BMCWEB_REDFISH_SYSTEM_URI_NAME.empty ())
328+ {
329+ if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
330+ {
331+ messages::resourceNotFound (asyncResp->res , " ComputerSystem" ,
332+ systemName);
333+ return ;
334+ }
335+ }
336+
337+ getComputerSystemIndex (
338+ asyncResp, systemName,
339+ std::bind_front (processSystemsLogServicesHostloggerEntriesEntryGet,
340+ asyncResp, systemName, param));
341+ }
342+
302343inline void requestRoutesSystemsLogServiceHostlogger (App& app)
303344{
304345 BMCWEB_ROUTE (app, " /redfish/v1/Systems/<str>/LogServices/HostLogger/" )
0 commit comments