clang-tidy: Enable bugprone-unchecked-optional-access

Enable bugprone-unchecked-optional-access to detect the case that it
accesses std::optional without checking empty.

See https://gerrit.openbmc.org/c/openbmc/docs/+/78034 for details.

This commit also fixes quite a few issues reported by clang-tidy:

* Add necessary includes in the hpp files;
* Move the template function `selAddSystemRecord()` into hpp;
* Fix the uncheck access of `expireAction`.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I4ad3cc07510a03965a2b4ae9c08fe452433ccdab
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000..4b6eca0
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,7 @@
+Checks: '
+    -*,
+    bugprone-unchecked-optional-access,
+    readability-identifier-naming
+'
+WarningsAsErrors: '*'
+HeaderFilterRegex: '(?!^subprojects).*'
diff --git a/include/host_error_event_monitor.hpp b/include/host_error_event_monitor.hpp
index 9823623..73bcba8 100644
--- a/include/host_error_event_monitor.hpp
+++ b/include/host_error_event_monitor.hpp
@@ -16,6 +16,7 @@
 
 #pragma once
 #include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
 #include <sdbusplus/asio/object_server.hpp>
 #include <sel_logger.hpp>
 #include <sensorutils.hpp>
diff --git a/include/pulse_event_monitor.hpp b/include/pulse_event_monitor.hpp
index 301515e..35ce7c9 100644
--- a/include/pulse_event_monitor.hpp
+++ b/include/pulse_event_monitor.hpp
@@ -15,7 +15,9 @@
 */
 
 #pragma once
+#include <boost/container/flat_map.hpp>
 #include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <sel_logger.hpp>
 #include <sensorutils.hpp>
 
diff --git a/include/sel_logger.hpp b/include/sel_logger.hpp
index 2b01fa2..0be63fc 100644
--- a/include/sel_logger.hpp
+++ b/include/sel_logger.hpp
@@ -15,7 +15,10 @@
 */
 
 #pragma once
+#include <sdbusplus/asio/connection.hpp>
+
 #include <filesystem>
+#include <string>
 
 static constexpr const char* ipmiSelObject = "xyz.openbmc_project.Logging.IPMI";
 static constexpr const char* ipmiSelPath = "/xyz/openbmc_project/Logging/IPMI";
@@ -40,9 +43,56 @@
 static const std::string nextRecordFilename = "next_records";
 #endif
 
+void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr);
+
 template <typename... T>
-static uint16_t selAddSystemRecord(
-    std::shared_ptr<sdbusplus::asio::connection> conn,
-    const std::string& message, const std::string& path,
+uint16_t selAddSystemRecord(
+    [[maybe_unused]] std::shared_ptr<sdbusplus::asio::connection> conn,
+    [[maybe_unused]] const std::string& message, const std::string& path,
     const std::vector<uint8_t>& selData, const bool& assert,
-    const uint16_t& genId, T&&... metadata);
+    const uint16_t& genId, [[maybe_unused]] T&&... metadata)
+{
+    // Only 3 bytes of SEL event data are allowed in a system record
+    if (selData.size() > selEvtDataMaxSize)
+    {
+        throw std::invalid_argument("Event data too large");
+    }
+    std::string selDataStr;
+    toHexStr(selData, selDataStr);
+
+#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+    sdbusplus::message_t AddToLog = conn->new_method_call(
+        "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
+        "xyz.openbmc_project.Logging.Create", "Create");
+
+    std::string journalMsg(
+        message + " from " + path + ": " +
+        " RecordType=" + std::to_string(selSystemType) +
+        ", GeneratorID=" + std::to_string(genId) +
+        ", EventDir=" + std::to_string(assert) + ", EventData=" + selDataStr);
+
+    AddToLog.append(
+        journalMsg, "xyz.openbmc_project.Logging.Entry.Level.Informational",
+        std::map<std::string, std::string>(
+            {{"SENSOR_PATH", path},
+             {"GENERATOR_ID", std::to_string(genId)},
+             {"RECORD_TYPE", std::to_string(selSystemType)},
+             {"EVENT_DIR", std::to_string(assert)},
+             {"SENSOR_DATA", selDataStr}}));
+    conn->call(AddToLog);
+    return 0;
+#else
+    unsigned int recordId = getNewRecordId();
+    if (recordId < selInvalidRecID)
+    {
+        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", selSystemType,
+            "IPMI_SEL_GENERATOR_ID=%x", genId, "IPMI_SEL_SENSOR_PATH=%s",
+            path.c_str(), "IPMI_SEL_EVENT_DIR=%x", assert, "IPMI_SEL_DATA=%s",
+            selDataStr.c_str(), std::forward<T>(metadata)..., NULL);
+    }
+    return recordId;
+#endif
+}
diff --git a/include/threshold_alarm_event_monitor.hpp b/include/threshold_alarm_event_monitor.hpp
index 6b0544a..9fe7e0a 100644
--- a/include/threshold_alarm_event_monitor.hpp
+++ b/include/threshold_alarm_event_monitor.hpp
@@ -15,7 +15,10 @@
 */
 
 #pragma once
+#include "threshold_event_monitor.hpp"
+
 #include <boost/container/flat_map.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <sel_logger.hpp>
 #include <sensorutils.hpp>
 
diff --git a/include/threshold_event_monitor.hpp b/include/threshold_event_monitor.hpp
index 685bb4e..8e9b458 100644
--- a/include/threshold_event_monitor.hpp
+++ b/include/threshold_event_monitor.hpp
@@ -15,6 +15,9 @@
 */
 
 #pragma once
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <sel_logger.hpp>
 #include <sensorutils.hpp>
 
diff --git a/include/watchdog_event_monitor.hpp b/include/watchdog_event_monitor.hpp
index 990e25e..57ba24e 100644
--- a/include/watchdog_event_monitor.hpp
+++ b/include/watchdog_event_monitor.hpp
@@ -15,6 +15,8 @@
 */
 
 #pragma once
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <sel_logger.hpp>
 #include <sensorutils.hpp>
 
@@ -84,6 +86,7 @@
 
     if (!expireAction)
     {
+        expireAction = "";
         auto getExpireAction = watchdogStatus.find("ExpireAction");
         if (getExpireAction != watchdogStatus.end())
         {
diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index 493b443..5e7e02a 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -349,7 +349,7 @@
 #endif
 #endif
 
-static void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr)
+void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr)
 {
     std::stringstream stream;
     stream << std::hex << std::uppercase << std::setfill('0');
@@ -360,58 +360,6 @@
     hexStr = stream.str();
 }
 
-template <typename... T>
-static uint16_t selAddSystemRecord(
-    [[maybe_unused]] std::shared_ptr<sdbusplus::asio::connection> conn,
-    [[maybe_unused]] const std::string& message, const std::string& path,
-    const std::vector<uint8_t>& selData, const bool& assert,
-    const uint16_t& genId, [[maybe_unused]] T&&... metadata)
-{
-    // Only 3 bytes of SEL event data are allowed in a system record
-    if (selData.size() > selEvtDataMaxSize)
-    {
-        throw std::invalid_argument("Event data too large");
-    }
-    std::string selDataStr;
-    toHexStr(selData, selDataStr);
-
-#ifdef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
-    sdbusplus::message_t AddToLog = conn->new_method_call(
-        "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
-        "xyz.openbmc_project.Logging.Create", "Create");
-
-    std::string journalMsg(
-        message + " from " + path + ": " +
-        " RecordType=" + std::to_string(selSystemType) +
-        ", GeneratorID=" + std::to_string(genId) +
-        ", EventDir=" + std::to_string(assert) + ", EventData=" + selDataStr);
-
-    AddToLog.append(
-        journalMsg, "xyz.openbmc_project.Logging.Entry.Level.Informational",
-        std::map<std::string, std::string>(
-            {{"SENSOR_PATH", path},
-             {"GENERATOR_ID", std::to_string(genId)},
-             {"RECORD_TYPE", std::to_string(selSystemType)},
-             {"EVENT_DIR", std::to_string(assert)},
-             {"SENSOR_DATA", selDataStr}}));
-    conn->call(AddToLog);
-    return 0;
-#else
-    unsigned int recordId = getNewRecordId();
-    if (recordId < selInvalidRecID)
-    {
-        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", selSystemType,
-            "IPMI_SEL_GENERATOR_ID=%x", genId, "IPMI_SEL_SENSOR_PATH=%s",
-            path.c_str(), "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(
     [[maybe_unused]] std::shared_ptr<sdbusplus::asio::connection> conn,
     [[maybe_unused]] const std::string& message,