Skip to content

Commit 58ae26f

Browse files
committed
WIP: systems_logservices_hostlogger.hpp - support for multi-host
Add support for multi-host for all GET and POST method requests under /redfish/v1/Systems/{computerSystemId}/LogServices/HostLogger/ redfish resource. Testing: TBD Change-Id: I026be8106f2accbb77d8d40749f502f3162ad04b Signed-off-by: Oliver Brewka <oliver.brewka@9elements.com>
1 parent 1441d55 commit 58ae26f

File tree

1 file changed

+115
-74
lines changed

1 file changed

+115
-74
lines changed

redfish-core/lib/systems_logservices_hostlogger.hpp

Lines changed: 115 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
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
{
3940
constexpr 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+
4145
inline 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+
302343
inline void requestRoutesSystemsLogServiceHostlogger(App& app)
303344
{
304345
BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")

0 commit comments

Comments
 (0)