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"