#pragma once #include "elog_entry.hpp" #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp" #include "xyz/openbmc_project/Logging/Create/server.hpp" #include "xyz/openbmc_project/Logging/Entry/server.hpp" #include "xyz/openbmc_project/Logging/Internal/Manager/server.hpp" #include #include #include namespace phosphor { namespace logging { extern const std::map> g_errMetaMap; extern const std::map g_errLevelMap; using CreateIface = sdbusplus::xyz::openbmc_project::Logging::server::Create; using DeleteAllIface = sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll; namespace details { template using ServerObject = typename sdbusplus::server::object::object; using ManagerIface = sdbusplus::xyz::openbmc_project::Logging::Internal::server::Manager; } // namespace details namespace internal { /** @class Manager * @brief OpenBMC logging manager implementation. * @details A concrete implementation for the * xyz.openbmc_project.Logging.Internal.Manager DBus API. */ class Manager : public details::ServerObject { public: Manager() = delete; Manager(const Manager&) = delete; Manager& operator=(const Manager&) = delete; Manager(Manager&&) = delete; Manager& operator=(Manager&&) = delete; virtual ~Manager() = default; /** @brief Constructor to put object onto bus at a dbus path. * @param[in] bus - Bus to attach to. * @param[in] path - Path to attach at. */ Manager(sdbusplus::bus::bus& bus, const char* objPath) : details::ServerObject(bus, objPath), busLog(bus), entryId(0), fwVersion(readFWVersion()){}; /* * @fn commit() * @brief sd_bus Commit method implementation callback. * @details Create an error/event log based on transaction id and * error message. * @param[in] transactionId - Unique identifier of the journal entries * to be committed. * @param[in] errMsg - The error exception message associated with the * error log to be committed. */ void commit(uint64_t transactionId, std::string errMsg) override; /* * @fn commit() * @brief sd_bus CommitWithLvl method implementation callback. * @details Create an error/event log based on transaction id and * error message. * @param[in] transactionId - Unique identifier of the journal entries * to be committed. * @param[in] errMsg - The error exception message associated with the * error log to be committed. * @param[in] errLvl - level of the error */ void commitWithLvl(uint64_t transactionId, std::string errMsg, uint32_t errLvl) override; /** @brief Erase specified entry d-bus object * * @param[in] entryId - unique identifier of the entry */ void erase(uint32_t entryId); /** @brief Construct error d-bus objects from their persisted * representations. */ void restore(); /** @brief Erase all error log entries * */ void eraseAll() { auto iter = entries.begin(); while (iter != entries.end()) { auto e = iter->first; ++iter; erase(e); } } /** @brief Returns the count of high severity errors * * @return int - count of real errors */ int getRealErrSize(); /** @brief Returns the count of Info errors * * @return int - count of info errors */ int getInfoErrSize(); sdbusplus::bus::bus& getBus() { return busLog; } /** @brief Creates an event log * * This is an alternative to the _commit() API. It doesn't use * the journal to look up event log metadata like _commit does. * * @param[in] errMsg - The error exception message associated with the * error log to be committed. * @param[in] severity - level of the error * @param[in] additionalData - The AdditionalData property for the error */ void create( const std::string& message, sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity, const std::map& additionalData); private: /* * @fn _commit() * @brief commit() helper * @param[in] transactionId - Unique identifier of the journal entries * to be committed. * @param[in] errMsg - The error exception message associated with the * error log to be committed. * @param[in] errLvl - level of the error */ void _commit(uint64_t transactionId, std::string&& errMsg, Entry::Level errLvl); /** @brief Call metadata handler(s), if any. Handlers may create * associations. * @param[in] errorName - name of the error * @param[in] additionalData - list of metadata (in key=value format) * @param[out] objects - list of error's association objects */ void processMetadata(const std::string& errorName, const std::vector& additionalData, AssociationList& objects) const; /** @brief Synchronize unwritten journal messages to disk. * @details This is the same implementation as the systemd command * "journalctl --sync". */ void journalSync(); /** @brief Reads the BMC code level * * @return std::string - the version string */ static std::string readFWVersion(); /** @brief Call any create() functions provided by any extensions. * This is called right after an event log is created to allow * extensions to create their own log based on this one. * * @param[in] entry - the new event log entry */ void doExtensionLogCreate(const Entry& entry); /** @brief Common wrapper for creating an Entry object * * @param[in] errMsg - The error exception message associated with the * error log to be committed. * @param[in] errLvl - level of the error * @param[in] additionalData - The AdditionalData property for the error */ void createEntry(std::string errMsg, Entry::Level errLvl, std::vector additionalData); /** @brief Persistent sdbusplus DBus bus connection. */ sdbusplus::bus::bus& busLog; /** @brief Persistent map of Entry dbus objects and their ID */ std::map> entries; /** @brief List of error ids for high severity errors */ std::list realErrors; /** @brief List of error ids for Info(and below) severity */ std::list infoErrors; /** @brief Id of last error log entry */ uint32_t entryId; /** @brief The BMC firmware version */ const std::string fwVersion; }; } // namespace internal /** @class Manager * @brief Implementation for deleting all error log entries and * creating new logs. * @details A concrete implementation for the * xyz.openbmc_project.Collection.DeleteAll and * xyz.openbmc_project.Logging.Create interfaces. */ class Manager : public details::ServerObject { public: Manager() = delete; Manager(const Manager&) = delete; Manager& operator=(const Manager&) = delete; Manager(Manager&&) = delete; Manager& operator=(Manager&&) = delete; virtual ~Manager() = default; /** @brief Constructor to put object onto bus at a dbus path. * Defer signal registration (pass true for deferSignal to the * base class) until after the properties are set. * @param[in] bus - Bus to attach to. * @param[in] path - Path to attach at. * @param[in] manager - Reference to internal manager object. */ Manager(sdbusplus::bus::bus& bus, const std::string& path, internal::Manager& manager) : details::ServerObject(bus, path.c_str(), true), manager(manager){}; /** @brief Delete all d-bus objects. */ void deleteAll() { manager.eraseAll(); } /** @brief D-Bus method call implementation to create an event log. * * @param[in] errMsg - The error exception message associated with the * error log to be committed. * @param[in] severity - Level of the error * @param[in] additionalData - The AdditionalData property for the error */ void create( std::string message, sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity, std::map additionalData) override { manager.create(message, severity, additionalData); } private: /** @brief This is a reference to manager object */ internal::Manager& manager; }; } // namespace logging } // namespace phosphor