LogService: Increase Fault Log timestamp precision
https://gerrit.openbmc.org/c/openbmc/bmcweb/+/55837 introduced support
for microsecond-precision timestamps in bmcweb.
Here we modify the Fault Log LogService
(/redfish/v1/Managers/bmc/LogServices/FaultLog) to use
microsecond-precision "Created" timestamps for its log entries. The
motivation for increased precision is to increase the chance of having
unique timestamps in case faults happen in quick succession. Unique
timestamps are helpful for data center tools to keep log entries in
chronological order and to track which entries have been seen before.
The "Created" timestamp is based on the "Elapsed" property of the
D-Bus interface xyz.openbmc_project.Time.EpochTime [1]. Dump entries
must implement xyz.openbmc_project.Time.EpochTime [2].
Note: our intention is to increase timestamp precision to microseconds
for all dump types. However at the moment the BMC dump and System dump
managers (in phosphor-debug-collector module) are not populating
EpochTime with microsecond precision as they should. So for now this
patchset only increases precision for the FaultLog dump type.
Changes to the Redfish tree:
Clients will now see microsecond-precision instead of second-precision
"Created" timestamps for fault log entries.
Tested:
Verified that Fault Log entries include microsecond-precision "Created"
timestamps both when entries are retrieved individually and as a
collection.
Example commands:
```
curl -k -H "X-Auth-Token: $token" -X GET http://${bmc}/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries
curl -k -H "X-Auth-Token: $token" -X GET http://${bmc}/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/1
```
Example timestamp output:
"Created": "2022-07-12T15:56:33.017346+00:00",
Also verified that BMC dump and System dump "Created" timestamps remain
unchanged (they still use second-precision).
Example commands:
```
curl -k -H "X-Auth-Token: $token" -X GET http://${bmc}/redfish/v1/Managers/bmc/LogServices/Dump/Entries
curl -k -H "X-Auth-Token: $token" -X GET http://${bmc}/redfish/v1/Systems/system/LogServices/Dump/Entries
```
Redfish Service Validator succeeded on the following URI trees:
/redfish/v1/Managers/bmc/LogServices/FaultLog
/redfish/v1/Managers/bmc/LogServices/Dump
[1] https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Time/EpochTime.interface.yaml
[2] https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Dump/Entry.interface.yaml
Signed-off-by: Claire Weinan <cweinan@google.com>
Change-Id: I400a24def8dbeff1046b93f0bb64e04ae5038e9a
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 0d6be71..533c15e 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -331,7 +331,7 @@
inline void parseDumpEntryFromDbusObject(
const dbus::utility::ManagedObjectType::value_type& object,
- std::string& dumpStatus, uint64_t& size, uint64_t& timestamp,
+ std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
for (const auto& interfaceMap : object.second)
@@ -384,7 +384,7 @@
messages::internalError(asyncResp->res);
break;
}
- timestamp = (*usecsTimeStamp / 1000 / 1000);
+ timestampUs = *usecsTimeStamp;
break;
}
}
@@ -471,7 +471,7 @@
{
continue;
}
- uint64_t timestamp = 0;
+ uint64_t timestampUs = 0;
uint64_t size = 0;
std::string dumpStatus;
nlohmann::json::object_t thisEntry;
@@ -482,7 +482,7 @@
continue;
}
- parseDumpEntryFromDbusObject(object, dumpStatus, size, timestamp,
+ parseDumpEntryFromDbusObject(object, dumpStatus, size, timestampUs,
asyncResp);
if (dumpStatus !=
@@ -497,19 +497,26 @@
thisEntry["@odata.id"] = entriesPath + entryID;
thisEntry["Id"] = entryID;
thisEntry["EntryType"] = "Event";
- thisEntry["Created"] =
- redfish::time_utils::getDateTimeUint(timestamp);
thisEntry["Name"] = dumpType + " Dump Entry";
if (dumpType == "BMC")
{
+ thisEntry["Created"] = redfish::time_utils::getDateTimeUint(
+ timestampUs / 1000 / 1000);
thisEntry["DiagnosticDataType"] = "Manager";
thisEntry["AdditionalDataURI"] =
entriesPath + entryID + "/attachment";
thisEntry["AdditionalDataSizeBytes"] = size;
}
+ else if (dumpType == "FaultLog")
+ {
+ thisEntry["Created"] =
+ redfish::time_utils::getDateTimeUintUs(timestampUs);
+ }
else if (dumpType == "System")
{
+ thisEntry["Created"] = redfish::time_utils::getDateTimeUint(
+ timestampUs / 1000 / 1000);
thisEntry["DiagnosticDataType"] = "OEM";
thisEntry["OEMDiagnosticDataType"] = "System";
thisEntry["AdditionalDataURI"] =
@@ -559,12 +566,12 @@
}
foundDumpEntry = true;
- uint64_t timestamp = 0;
+ uint64_t timestampUs = 0;
uint64_t size = 0;
std::string dumpStatus;
parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
- timestamp, asyncResp);
+ timestampUs, asyncResp);
if (dumpStatus !=
"xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
@@ -581,19 +588,28 @@
asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
asyncResp->res.jsonValue["Id"] = entryID;
asyncResp->res.jsonValue["EntryType"] = "Event";
- asyncResp->res.jsonValue["Created"] =
- redfish::time_utils::getDateTimeUint(timestamp);
asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
if (dumpType == "BMC")
{
+ asyncResp->res.jsonValue["Created"] =
+ redfish::time_utils::getDateTimeUint(timestampUs / 1000 /
+ 1000);
asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
asyncResp->res.jsonValue["AdditionalDataURI"] =
entriesPath + entryID + "/attachment";
asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
}
+ else if (dumpType == "FaultLog")
+ {
+ asyncResp->res.jsonValue["Created"] =
+ redfish::time_utils::getDateTimeUintUs(timestampUs);
+ }
else if (dumpType == "System")
{
+ asyncResp->res.jsonValue["Created"] =
+ redfish::time_utils::getDateTimeUint(timestampUs / 1000 /
+ 1000);
asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
asyncResp->res.jsonValue["OEMDiagnosticDataType"] = "System";
asyncResp->res.jsonValue["AdditionalDataURI"] =