Add SEL_LOGGER_SEND_TO_LOGGING_SERVICE option

When enabled, the sel logger sends the SEL data to logging service
instead of journal.

The logging service will create a logging entry with related metadata,
so that it could be used for ipmid to convert to SEL entry.

Tested: Verify the logging entry is created as below example:

    # Add OEM SEL
    busctl call "xyz.openbmc_project.Logging.IPMI" "/xyz/openbmc_project/Logging/IPMI" xyz.openbmc_project.Logging.IPMI IpmiSelAddOem sayy "b370836ccf2f4850ac5bee185b77893a" 9 0x00 0xdd 0xb3 0xba 0xcd 0x00 0x01 0x00 0x00 0xcd
    # logging entry:
    "data": {
      "AdditionalData": [
        "EVENT_DIR=0",
        "GENERATE_ID=0",
        "IS_OEM=1",
        "RECORD_TYPE=205",
        "SENSOR_DATA=00DDB3BACD00010000",
        "SENSOR_PATH=",
        "_PID=198"
      ],
      "Associations": [],
      "Id": 1,
      "Message": "xyz.openbmc_project.Logging.SEL.Error.Created",
      "Purpose": "xyz.openbmc_project.Software.Version.VersionPurpose.BMC",
      "Resolved": false,
      "Severity": "xyz.openbmc_project.Logging.Entry.Level.Informational",
      "Timestamp": 86022,
      "UpdateTimestamp": 86022,
      "Version": "2.9.0-dev-1308-g01b7feb91-dirty"
    },

    # Add regular SEL record
    busctl call "xyz.openbmc_project.Logging.IPMI" "/xyz/openbmc_project/Logging/IPMI" xyz.openbmc_project.Logging.IPMI IpmiSelAdd ssaybq "MyTestMessage" "InvalidPath" 3 0x01 0x02 0x03 true 0x2000
    # logging entry:
    "data": {
      "AdditionalData": [
        "EVENT_DIR=1",
        "GENERATE_ID=8192",
        "IS_OEM=0",
        "RECORD_TYPE=2",
        "SENSOR_DATA=010203",
        "SENSOR_PATH=InvalidPath",
        "_PID=512"
      ],
      "Associations": [],
      "Id": 2,
      "Message": "xyz.openbmc_project.Logging.SEL.Error.Created",
      "Purpose": "xyz.openbmc_project.Software.Version.VersionPurpose.BMC",
      "Resolved": false,
      "Severity": "xyz.openbmc_project.Logging.Entry.Level.Informational",
      "Timestamp": 458713,
      "UpdateTimestamp": 458713,
      "Version": "2.9.0-dev-1312-g30641eb10"
    },

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I01aa0af2b9ba6211d1f447106f82cfa264ef877a
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cbbb23b..a0f428c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,15 +19,28 @@
     OFF
 )
 
+option (
+    SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+    "Make SEL Logger to send sel to logging service instead of journal"
+    OFF
+)
+
 target_compile_definitions (
     sel-logger PRIVATE
     $<$<BOOL:${SEL_LOGGER_MONITOR_THRESHOLD_EVENTS}>: -DSEL_LOGGER_MONITOR_THRESHOLD_EVENTS>
     $<$<BOOL:${REDFISH_LOG_MONITOR_PULSE_EVENTS}>: -DREDFISH_LOG_MONITOR_PULSE_EVENTS>
+    $<$<BOOL:${SEL_LOGGER_SEND_TO_LOGGING_SERVICE}>: -DSEL_LOGGER_SEND_TO_LOGGING_SERVICE>
 )
 
 target_include_directories (sel-logger PRIVATE ${CMAKE_SOURCE_DIR})
 
-target_link_libraries (sel-logger systemd sdbusplus pthread phosphor_logging -lstdc++fs)
+set(LINK_LIBS systemd sdbusplus pthread phosphor_logging -lstdc++fs)
+
+if (SEL_LOGGER_SEND_TO_LOGGING_SERVICE)
+    list(APPEND LINK_LIBS phosphor_dbus)
+endif()
+
+target_link_libraries (sel-logger ${LINK_LIBS})
 
 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
 
diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index 5f330e0..7fb19ef 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -30,6 +30,17 @@
 #include <iostream>
 #include <sstream>
 
+#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Logging/SEL/error.hpp>
+
+using namespace phosphor::logging;
+using SELCreated =
+    sdbusplus::xyz::openbmc_project::Logging::SEL::Error::Created;
+#endif
+
 struct DBusInternalError final : public sdbusplus::exception_t
 {
     const char* name() const noexcept override
@@ -47,6 +58,7 @@
     };
 };
 
+#ifndef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
 static bool getSELLogFiles(std::vector<std::filesystem::path>& selLogFiles)
 {
     // Loop through the directory looking for ipmi_sel log files
@@ -115,6 +127,7 @@
     }
     return recordId;
 }
+#endif
 
 static void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr)
 {
@@ -141,6 +154,14 @@
     std::string selDataStr;
     toHexStr(selData, selDataStr);
 
+#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+    using namespace xyz::openbmc_project::Logging::SEL;
+    report<SELCreated>(
+        Created::RECORD_TYPE(selSystemType), Created::GENERATOR_ID(genId),
+        Created::SENSOR_DATA(selDataStr.c_str()), Created::EVENT_DIR(assert),
+        Created::SENSOR_PATH(path.c_str()));
+    return 0;
+#else
     unsigned int recordId = getNewRecordId();
     sd_journal_send("MESSAGE=%s", message.c_str(), "PRIORITY=%i", selPriority,
                     "MESSAGE_ID=%s", selMessageId, "IPMI_SEL_RECORD_ID=%d",
@@ -150,6 +171,7 @@
                     "IPMI_SEL_EVENT_DIR=%x", assert, "IPMI_SEL_DATA=%s",
                     selDataStr.c_str(), std::forward<T>(metadata)..., NULL);
     return recordId;
+#endif
 }
 
 static uint16_t selAddOemRecord(const std::string& message,
@@ -164,12 +186,21 @@
     std::string selDataStr;
     toHexStr(selData, selDataStr);
 
+#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+    using namespace xyz::openbmc_project::Logging::SEL;
+    report<SELCreated>(Created::RECORD_TYPE(recordType),
+                       Created::GENERATOR_ID(0),
+                       Created::SENSOR_DATA(selDataStr.c_str()),
+                       Created::EVENT_DIR(0), Created::SENSOR_PATH(""));
+    return 0;
+#else
     unsigned int recordId = getNewRecordId();
     sd_journal_send("MESSAGE=%s", message.c_str(), "PRIORITY=%i", selPriority,
                     "MESSAGE_ID=%s", selMessageId, "IPMI_SEL_RECORD_ID=%d",
                     recordId, "IPMI_SEL_RECORD_TYPE=%x", recordType,
                     "IPMI_SEL_DATA=%s", selDataStr.c_str(), NULL);
     return recordId;
+#endif
 }
 
 int main(int argc, char* argv[])