Refactor: extract src/event_log.cpp
event_service_manager.hpp contains namespace 'event_log' which is
confusing. Extract it to a separate header and cpp file to have the
filename match the namespace.
No functional changes have been made to the code.
Tested:
- Using Redfish Event Listener, test subscriptions and eventing.
- Redfish Service Validator passes
Change-Id: Ia0bf658b8b46f92aede059d46e8de48f160e073e
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
Signed-off-by: Ed Tanous <ed@tanous.net>
diff --git a/meson.build b/meson.build
index af2c69c..1bdbc71 100644
--- a/meson.build
+++ b/meson.build
@@ -342,6 +342,7 @@
srcfiles_bmcweb = files(
'http/mutual_tls.cpp',
'redfish-core/src/error_messages.cpp',
+ 'redfish-core/src/event_log.cpp',
'redfish-core/src/filter_expr_executor.cpp',
'redfish-core/src/filter_expr_printer.cpp',
'redfish-core/src/redfish.cpp',
diff --git a/redfish-core/include/event_log.hpp b/redfish-core/include/event_log.hpp
new file mode 100644
index 0000000..676dbfd
--- /dev/null
+++ b/redfish-core/include/event_log.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+#include <span>
+#include <string>
+#include <string_view>
+
+namespace redfish
+{
+
+namespace event_log
+{
+
+bool getUniqueEntryID(const std::string& logEntry, std::string& entryID);
+
+int getEventLogParams(const std::string& logEntry, std::string& timestamp,
+ std::string& messageID,
+ std::vector<std::string>& messageArgs);
+
+int formatEventLogEntry(
+ const std::string& logEntryID, const std::string& messageID,
+ std::span<std::string_view> messageArgs, std::string timestamp,
+ const std::string& customText, nlohmann::json::object_t& logEntryJson);
+
+} // namespace event_log
+
+} // namespace redfish
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index e376980..40854d5 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -16,6 +16,7 @@
#pragma once
#include "dbus_utility.hpp"
#include "error_messages.hpp"
+#include "event_log.hpp"
#include "event_matches_filter.hpp"
#include "event_service_store.hpp"
#include "metric_report.hpp"
@@ -71,7 +72,7 @@
namespace registries
{
-static const Message*
+inline const Message*
getMsgFromRegistry(const std::string& messageKey,
const std::span<const MessageEntry>& registry)
{
@@ -87,7 +88,7 @@
return nullptr;
}
-static const Message* formatMessage(std::string_view messageID)
+inline const Message* formatMessage(std::string_view messageID)
{
// Redfish MessageIds are in the form
// RegistryName.MajorVersion.MinorVersion.MessageKey, so parse it to find
@@ -108,134 +109,6 @@
}
} // namespace registries
-namespace event_log
-{
-inline bool getUniqueEntryID(const std::string& logEntry, std::string& entryID)
-{
- static time_t prevTs = 0;
- static int index = 0;
-
- // Get the entry timestamp
- std::time_t curTs = 0;
- std::tm timeStruct = {};
- std::istringstream entryStream(logEntry);
- if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
- {
- curTs = std::mktime(&timeStruct);
- if (curTs == -1)
- {
- return false;
- }
- }
- // If the timestamp isn't unique, increment the index
- index = (curTs == prevTs) ? index + 1 : 0;
-
- // Save the timestamp
- prevTs = curTs;
-
- entryID = std::to_string(curTs);
- if (index > 0)
- {
- entryID += "_" + std::to_string(index);
- }
- return true;
-}
-
-inline int getEventLogParams(const std::string& logEntry,
- std::string& timestamp, std::string& messageID,
- std::vector<std::string>& messageArgs)
-{
- // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>"
- // First get the Timestamp
- size_t space = logEntry.find_first_of(' ');
- if (space == std::string::npos)
- {
- BMCWEB_LOG_ERROR("EventLog Params: could not find first space: {}",
- logEntry);
- return -EINVAL;
- }
- timestamp = logEntry.substr(0, space);
- // Then get the log contents
- size_t entryStart = logEntry.find_first_not_of(' ', space);
- if (entryStart == std::string::npos)
- {
- BMCWEB_LOG_ERROR("EventLog Params: could not find log contents: {}",
- logEntry);
- return -EINVAL;
- }
- std::string_view entry(logEntry);
- entry.remove_prefix(entryStart);
- // Use split to separate the entry into its fields
- std::vector<std::string> logEntryFields;
- bmcweb::split(logEntryFields, entry, ',');
- // We need at least a MessageId to be valid
- if (logEntryFields.empty())
- {
- BMCWEB_LOG_ERROR("EventLog Params: could not find entry fields: {}",
- logEntry);
- return -EINVAL;
- }
- messageID = logEntryFields[0];
-
- // Get the MessageArgs from the log if there are any
- if (logEntryFields.size() > 1)
- {
- const std::string& messageArgsStart = logEntryFields[1];
- // If the first string is empty, assume there are no MessageArgs
- if (!messageArgsStart.empty())
- {
- messageArgs.assign(logEntryFields.begin() + 1,
- logEntryFields.end());
- }
- }
-
- return 0;
-}
-
-inline int formatEventLogEntry(
- const std::string& logEntryID, const std::string& messageID,
- const std::span<std::string_view> messageArgs, std::string timestamp,
- const std::string& customText, nlohmann::json::object_t& logEntryJson)
-{
- // Get the Message from the MessageRegistry
- const registries::Message* message = registries::formatMessage(messageID);
-
- if (message == nullptr)
- {
- return -1;
- }
-
- std::string msg =
- redfish::registries::fillMessageArgs(messageArgs, message->message);
- if (msg.empty())
- {
- return -1;
- }
-
- // Get the Created time from the timestamp. The log timestamp is in
- // RFC3339 format which matches the Redfish format except for the
- // fractional seconds between the '.' and the '+', so just remove them.
- std::size_t dot = timestamp.find_first_of('.');
- std::size_t plus = timestamp.find_first_of('+', dot);
- if (dot != std::string::npos && plus != std::string::npos)
- {
- timestamp.erase(dot, plus - dot);
- }
-
- // Fill in the log entry with the gathered data
- logEntryJson["EventId"] = logEntryID;
-
- logEntryJson["Severity"] = message->messageSeverity;
- logEntryJson["Message"] = std::move(msg);
- logEntryJson["MessageId"] = messageID;
- logEntryJson["MessageArgs"] = messageArgs;
- logEntryJson["EventTimestamp"] = std::move(timestamp);
- logEntryJson["Context"] = customText;
- return 0;
-}
-
-} // namespace event_log
-
class EventServiceManager
{
private:
diff --git a/redfish-core/src/event_log.cpp b/redfish-core/src/event_log.cpp
new file mode 100644
index 0000000..5420549
--- /dev/null
+++ b/redfish-core/src/event_log.cpp
@@ -0,0 +1,168 @@
+/*
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include "event_log.hpp"
+
+#include "event_service_manager.hpp"
+#include "logging.hpp"
+#include "registries.hpp"
+#include "str_utility.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <cerrno>
+#include <cstddef>
+#include <ctime>
+#include <iomanip>
+#include <span>
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace redfish
+{
+
+namespace event_log
+{
+
+bool getUniqueEntryID(const std::string& logEntry, std::string& entryID)
+{
+ static time_t prevTs = 0;
+ static int index = 0;
+
+ // Get the entry timestamp
+ std::time_t curTs = 0;
+ std::tm timeStruct = {};
+ std::istringstream entryStream(logEntry);
+ if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
+ {
+ curTs = std::mktime(&timeStruct);
+ if (curTs == -1)
+ {
+ return false;
+ }
+ }
+ // If the timestamp isn't unique, increment the index
+ index = (curTs == prevTs) ? index + 1 : 0;
+
+ // Save the timestamp
+ prevTs = curTs;
+
+ entryID = std::to_string(curTs);
+ if (index > 0)
+ {
+ entryID += "_" + std::to_string(index);
+ }
+ return true;
+}
+
+int getEventLogParams(const std::string& logEntry, std::string& timestamp,
+ std::string& messageID,
+ std::vector<std::string>& messageArgs)
+{
+ // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>"
+ // First get the Timestamp
+ size_t space = logEntry.find_first_of(' ');
+ if (space == std::string::npos)
+ {
+ BMCWEB_LOG_ERROR("EventLog Params: could not find first space: {}",
+ logEntry);
+ return -EINVAL;
+ }
+ timestamp = logEntry.substr(0, space);
+ // Then get the log contents
+ size_t entryStart = logEntry.find_first_not_of(' ', space);
+ if (entryStart == std::string::npos)
+ {
+ BMCWEB_LOG_ERROR("EventLog Params: could not find log contents: {}",
+ logEntry);
+ return -EINVAL;
+ }
+ std::string_view entry(logEntry);
+ entry.remove_prefix(entryStart);
+ // Use split to separate the entry into its fields
+ std::vector<std::string> logEntryFields;
+ bmcweb::split(logEntryFields, entry, ',');
+ // We need at least a MessageId to be valid
+ if (logEntryFields.empty())
+ {
+ BMCWEB_LOG_ERROR("EventLog Params: could not find entry fields: {}",
+ logEntry);
+ return -EINVAL;
+ }
+ messageID = logEntryFields[0];
+
+ // Get the MessageArgs from the log if there are any
+ if (logEntryFields.size() > 1)
+ {
+ const std::string& messageArgsStart = logEntryFields[1];
+ // If the first string is empty, assume there are no MessageArgs
+ if (!messageArgsStart.empty())
+ {
+ messageArgs.assign(logEntryFields.begin() + 1,
+ logEntryFields.end());
+ }
+ }
+
+ return 0;
+}
+
+int formatEventLogEntry(
+ const std::string& logEntryID, const std::string& messageID,
+ const std::span<std::string_view> messageArgs, std::string timestamp,
+ const std::string& customText, nlohmann::json::object_t& logEntryJson)
+{
+ // Get the Message from the MessageRegistry
+ const registries::Message* message = registries::formatMessage(messageID);
+
+ if (message == nullptr)
+ {
+ return -1;
+ }
+
+ std::string msg =
+ redfish::registries::fillMessageArgs(messageArgs, message->message);
+ if (msg.empty())
+ {
+ return -1;
+ }
+
+ // Get the Created time from the timestamp. The log timestamp is in
+ // RFC3339 format which matches the Redfish format except for the
+ // fractional seconds between the '.' and the '+', so just remove them.
+ std::size_t dot = timestamp.find_first_of('.');
+ std::size_t plus = timestamp.find_first_of('+', dot);
+ if (dot != std::string::npos && plus != std::string::npos)
+ {
+ timestamp.erase(dot, plus - dot);
+ }
+
+ // Fill in the log entry with the gathered data
+ logEntryJson["EventId"] = logEntryID;
+
+ logEntryJson["Severity"] = message->messageSeverity;
+ logEntryJson["Message"] = std::move(msg);
+ logEntryJson["MessageId"] = messageID;
+ logEntryJson["MessageArgs"] = messageArgs;
+ logEntryJson["EventTimestamp"] = std::move(timestamp);
+ logEntryJson["Context"] = customText;
+ return 0;
+}
+
+} // namespace event_log
+
+} // namespace redfish
diff --git a/redfish-core/src/subscription.cpp b/redfish-core/src/subscription.cpp
index f74435d..0b7a9fd 100644
--- a/redfish-core/src/subscription.cpp
+++ b/redfish-core/src/subscription.cpp
@@ -15,9 +15,9 @@
*/
#include "subscription.hpp"
+#include "event_log.hpp"
#include "event_logs_object_type.hpp"
#include "event_matches_filter.hpp"
-#include "event_service_manager.hpp"
#include "event_service_store.hpp"
#include "filter_expr_executor.hpp"
#include "generated/enums/log_entry.hpp"