psutil: Add PSU Event Log Reporting Methods

This commit introduces new methods in the Updater class to log errors
and create Platform Event Logs for PSU failures and I2C-related
issues. The following methods are added:

- createServiceableEventLog:
  Creates a serviceable Platform Event Log using
  xyz.openbmc_project.Logging.Create. Takes an error name, severity, and
  additional data as parameters. Retrieves the logging service and calls
  the D-Bus method to create the log.

- getI2CAdditionalData:
  Retrieves I2C-related callout data, including I2C bus ID, address, and
  error number. Formats the ID and address as hexadecimal strings and
  returns them as a map.

- callOutI2CEventLog:
  Reports a Event Log for I2C failures. Collects PSU inventory path,
  priority, and I2C-specific callout data. Merges any additional
  provided data and creates a Event Log.

- callOutPsuEventLog:
  Reports a Event Log for general PSU failures. Includes PSU inventory
  callout information and priority.

- callOutSWEventLog:
  Reports Event Log for software-related PSU file issues.Logs errors
  using predefined PSU firmware file issue messages. These changes
  improve fault logging and troubleshooting capabilities in PSU
  management by ensuring proper logging and event recording.

- callOutGoodEventLog:
  Reports a successful PSU firmware update Event Log along with the
  firmware level.

- Added accessor functions to provide control over Event logging,
  allowing:
  - Enabling/disabling Event logging at runtime.
  - Tracking if Event Log  has been logged in the current session.

  Accessor functions:
    - enableEventLogging()
    - disableEventLogging()
    - isEventLogEnabled()
    - enableEventLoggedThisSession()
    - isEventLoggedThisSession()

Test:
 Verified each function correctly generates Event Log  in openBmc. The
 test was conducted by writing a standalone test program that:
 1 - Calls createServiceableEventLog() with various error names,
 severity levels, and additionalData then check the generated Event Log.
 2 - Calls getI2CAdditionalData() and verifies the returned data
 contains the correct I2C bus ID, Address and error number.
 3 - Calls callOutI2CEventLog() with simulated I2C error and checks the
 generated Event Log.
 4 - Calls callOutPsuEventLog() and callOutSWEventLog() with different
 input data and verifies the correct error messages are logged.

Change-Id: Id52b3e1c0b2a3b09ae3ac5d93bc53e02d335d6c7
Signed-off-by: Faisal Awada <faisal@us.ibm.com>
diff --git a/tools/power-utils/updater.hpp b/tools/power-utils/updater.hpp
index c02541b..21bc4cd 100644
--- a/tools/power-utils/updater.hpp
+++ b/tools/power-utils/updater.hpp
@@ -30,6 +30,17 @@
 
 namespace fs = std::filesystem;
 
+constexpr auto FW_UPDATE_FAILED_MSG =
+    "xyz.openbmc_project.Power.PowerSupply.Error.FirmwareUpdateFailed";
+constexpr auto PSU_FW_FILE_ISSUE_MSG =
+    "xyz.openbmc_project.Power.PowerSupply.Error.FirmwareIssue";
+constexpr auto FW_UPDATE_SUCCESS_MSG =
+    "xyz.openbmc_project.Power.PowerSupply.Info.FirmwareUpdateSuccessful";
+
+constexpr auto ERROR_SEVERITY = "xyz.openbmc_project.Logging.Entry.Level.Error";
+constexpr auto INFORMATIONAL_SEVERITY =
+    "xyz.openbmc_project.Logging.Entry.Level.Informational";
+
 /**
  * Update PSU firmware
  *
@@ -127,6 +138,128 @@
         return i2c.get();
     }
 
+    /**
+     * @brief Creates a serviceable Predictive Event Log,
+     *
+     * This method generates an event log with the given error name, severity,
+     * and additional data. It interacts with the OpenBMC logging service to
+     * record faults.
+     *
+     * @param[in] errorName The name of the error to log.
+     * @param[in] severity The severity level of the error.
+     * @param[in] additionalData Additional key-value pairs containing details
+     *                           about the error.
+     */
+    void createServiceableEventLog(
+        const std::string& errorName, const std::string& severity,
+        std::map<std::string, std::string>& additionalData);
+
+    /**
+     * @brief Retrieves additional data related to I2C communication.
+     *
+     * This method collects and returns I2C bus information, including the
+     * bus ID, address, and error number, which are used for reporting
+     * Predictive Error Log.
+     *
+     * @return A map containing I2C-related key-value pairs.
+     */
+    std::map<std::string, std::string> getI2CAdditionalData();
+
+    /**
+     * @brief Call out an I2C-related Predictive Error Log.
+     *
+     * This method creates a serviceable event log related to I2C failures.
+     * It collects additional data about the I2C communication and logs the
+     * failure with appropriate severity.
+     *
+     * @param[in] extraAdditionalData Additional key-value pairs specific to
+     *                                the error context.
+     * @param[in] exceptionString A string describing the exception that
+     *                            triggered the error.
+     * @param[in] errorCode Exception error code.
+     */
+    void callOutI2CEventLog(
+        std::map<std::string, std::string> extraAdditionalData,
+        const std::string& exceptionString = "", const int errorCode = 0);
+
+    /**
+     * @brief Call out a PSU-related Predictive Error Log.
+     *
+     * This method logs a failure related to PSU firmware updates and additional
+     * diagnostics data to the event log.
+     *
+     * @param[in] extraAdditionalData Additional key-value pairs specific to
+     *                                the PSU-related error.
+     */
+    void callOutPsuEventLog(
+        std::map<std::string, std::string> extraAdditionalData);
+
+    /**
+     * @brief Call out a software-related Predictive Error Log.
+     *
+     * This method logs a failure related to PSU firmware file issues or other
+     * software-related errors. It merges any additional error-specific data
+     * before logging the event.
+     *
+     * @param[in] extraAdditionalData Additional key-value pairs specific to
+     *                                the software-related error.
+     */
+    void callOutSWEventLog(
+        std::map<std::string, std::string> extraAdditionalData);
+
+    /**
+     * @brief Accessor to set logEventLog to true
+     *
+     */
+    void enableEventLogging()
+    {
+        eventLogState = true;
+    }
+
+    /**
+     * @brief Accessor to set eventLogState to false
+     *
+     */
+    void disableEventLogging()
+    {
+        eventLogState = false;
+    }
+
+    /**
+     * @brief Accessor eventLogState status (enable true, disable false)
+     *
+     * @return true or false
+     */
+    bool isEventLogEnabled()
+    {
+        return eventLogState;
+    }
+
+    /**
+     * @brief Accessor to disable eventLoggedThisSession
+     *
+     */
+    void enableEventLoggedThisSession()
+    {
+        eventLoggedThisSession = true;
+    }
+
+    /**
+     * @brief Accessor to retieve eventLoggedThisSession status
+     *
+     * @return true or false
+     */
+    bool isEventLoggedThisSession()
+    {
+        return eventLoggedThisSession;
+    }
+
+    /**
+     * @brief Call out successful PSU firmware update.
+     *
+     */
+    void callOutGoodEventLog();
+
   private:
     /** @brief The sdbusplus DBus bus connection */
     sdbusplus::bus_t bus;
@@ -160,6 +293,14 @@
 
     /** @brief The i2c device interface */
     std::unique_ptr<i2c::I2CInterface> i2c;
+
+    /** @brief Event Log flag */
+    bool eventLogState = false;
+
+    /** @brief Event logged this session flag, this is to make sure no other
+     * event log can be logged
+     */
+    bool eventLoggedThisSession = false;
 };
 
 namespace internal