1 #pragma once 2 3 #include "elog_entry.hpp" 4 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp" 5 #include "xyz/openbmc_project/Logging/Create/server.hpp" 6 #include "xyz/openbmc_project/Logging/Entry/server.hpp" 7 #include "xyz/openbmc_project/Logging/Internal/Manager/server.hpp" 8 9 #include <list> 10 #include <phosphor-logging/log.hpp> 11 #include <sdbusplus/bus.hpp> 12 13 namespace phosphor 14 { 15 namespace logging 16 { 17 18 extern const std::map<std::string, std::vector<std::string>> g_errMetaMap; 19 extern const std::map<std::string, level> g_errLevelMap; 20 21 using CreateIface = sdbusplus::xyz::openbmc_project::Logging::server::Create; 22 using DeleteAllIface = 23 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll; 24 25 namespace details 26 { 27 template <typename... T> 28 using ServerObject = typename sdbusplus::server::object::object<T...>; 29 30 using ManagerIface = 31 sdbusplus::xyz::openbmc_project::Logging::Internal::server::Manager; 32 33 } // namespace details 34 35 namespace internal 36 { 37 38 /** @class Manager 39 * @brief OpenBMC logging manager implementation. 40 * @details A concrete implementation for the 41 * xyz.openbmc_project.Logging.Internal.Manager DBus API. 42 */ 43 class Manager : public details::ServerObject<details::ManagerIface> 44 { 45 public: 46 Manager() = delete; 47 Manager(const Manager&) = delete; 48 Manager& operator=(const Manager&) = delete; 49 Manager(Manager&&) = delete; 50 Manager& operator=(Manager&&) = delete; 51 virtual ~Manager() = default; 52 53 /** @brief Constructor to put object onto bus at a dbus path. 54 * @param[in] bus - Bus to attach to. 55 * @param[in] path - Path to attach at. 56 */ 57 Manager(sdbusplus::bus::bus& bus, const char* objPath) : 58 details::ServerObject<details::ManagerIface>(bus, objPath), busLog(bus), 59 entryId(0), fwVersion(readFWVersion()){}; 60 61 /* 62 * @fn commit() 63 * @brief sd_bus Commit method implementation callback. 64 * @details Create an error/event log based on transaction id and 65 * error message. 66 * @param[in] transactionId - Unique identifier of the journal entries 67 * to be committed. 68 * @param[in] errMsg - The error exception message associated with the 69 * error log to be committed. 70 */ 71 void commit(uint64_t transactionId, std::string errMsg) override; 72 73 /* 74 * @fn commit() 75 * @brief sd_bus CommitWithLvl method implementation callback. 76 * @details Create an error/event log based on transaction id and 77 * error message. 78 * @param[in] transactionId - Unique identifier of the journal entries 79 * to be committed. 80 * @param[in] errMsg - The error exception message associated with the 81 * error log to be committed. 82 * @param[in] errLvl - level of the error 83 */ 84 void commitWithLvl(uint64_t transactionId, std::string errMsg, 85 uint32_t errLvl) override; 86 87 /** @brief Erase specified entry d-bus object 88 * 89 * @param[in] entryId - unique identifier of the entry 90 */ 91 void erase(uint32_t entryId); 92 93 /** @brief Construct error d-bus objects from their persisted 94 * representations. 95 */ 96 void restore(); 97 98 /** @brief Erase all error log entries 99 * 100 */ 101 void eraseAll() 102 { 103 auto iter = entries.begin(); 104 while (iter != entries.end()) 105 { 106 auto e = iter->first; 107 ++iter; 108 erase(e); 109 } 110 } 111 112 /** @brief Returns the count of high severity errors 113 * 114 * @return int - count of real errors 115 */ 116 int getRealErrSize(); 117 118 /** @brief Returns the count of Info errors 119 * 120 * @return int - count of info errors 121 */ 122 int getInfoErrSize(); 123 124 sdbusplus::bus::bus& getBus() 125 { 126 return busLog; 127 } 128 129 /** @brief Creates an event log 130 * 131 * This is an alternative to the _commit() API. It doesn't use 132 * the journal to look up event log metadata like _commit does. 133 * 134 * @param[in] errMsg - The error exception message associated with the 135 * error log to be committed. 136 * @param[in] severity - level of the error 137 * @param[in] additionalData - The AdditionalData property for the error 138 */ 139 void create( 140 const std::string& message, 141 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity, 142 const std::map<std::string, std::string>& additionalData); 143 144 private: 145 /* 146 * @fn _commit() 147 * @brief commit() helper 148 * @param[in] transactionId - Unique identifier of the journal entries 149 * to be committed. 150 * @param[in] errMsg - The error exception message associated with the 151 * error log to be committed. 152 * @param[in] errLvl - level of the error 153 */ 154 void _commit(uint64_t transactionId, std::string&& errMsg, 155 Entry::Level errLvl); 156 157 /** @brief Call metadata handler(s), if any. Handlers may create 158 * associations. 159 * @param[in] errorName - name of the error 160 * @param[in] additionalData - list of metadata (in key=value format) 161 * @param[out] objects - list of error's association objects 162 */ 163 void processMetadata(const std::string& errorName, 164 const std::vector<std::string>& additionalData, 165 AssociationList& objects) const; 166 167 /** @brief Synchronize unwritten journal messages to disk. 168 * @details This is the same implementation as the systemd command 169 * "journalctl --sync". 170 */ 171 void journalSync(); 172 173 /** @brief Reads the BMC code level 174 * 175 * @return std::string - the version string 176 */ 177 static std::string readFWVersion(); 178 179 /** @brief Call any create() functions provided by any extensions. 180 * This is called right after an event log is created to allow 181 * extensions to create their own log based on this one. 182 * 183 * @param[in] entry - the new event log entry 184 */ 185 void doExtensionLogCreate(const Entry& entry); 186 187 /** @brief Common wrapper for creating an Entry object 188 * 189 * @param[in] errMsg - The error exception message associated with the 190 * error log to be committed. 191 * @param[in] errLvl - level of the error 192 * @param[in] additionalData - The AdditionalData property for the error 193 */ 194 void createEntry(std::string errMsg, Entry::Level errLvl, 195 std::vector<std::string> additionalData); 196 197 /** @brief Persistent sdbusplus DBus bus connection. */ 198 sdbusplus::bus::bus& busLog; 199 200 /** @brief Persistent map of Entry dbus objects and their ID */ 201 std::map<uint32_t, std::unique_ptr<Entry>> entries; 202 203 /** @brief List of error ids for high severity errors */ 204 std::list<uint32_t> realErrors; 205 206 /** @brief List of error ids for Info(and below) severity */ 207 std::list<uint32_t> infoErrors; 208 209 /** @brief Id of last error log entry */ 210 uint32_t entryId; 211 212 /** @brief The BMC firmware version */ 213 const std::string fwVersion; 214 }; 215 216 } // namespace internal 217 218 /** @class Manager 219 * @brief Implementation for deleting all error log entries and 220 * creating new logs. 221 * @details A concrete implementation for the 222 * xyz.openbmc_project.Collection.DeleteAll and 223 * xyz.openbmc_project.Logging.Create interfaces. 224 */ 225 class Manager : public details::ServerObject<DeleteAllIface, CreateIface> 226 { 227 public: 228 Manager() = delete; 229 Manager(const Manager&) = delete; 230 Manager& operator=(const Manager&) = delete; 231 Manager(Manager&&) = delete; 232 Manager& operator=(Manager&&) = delete; 233 virtual ~Manager() = default; 234 235 /** @brief Constructor to put object onto bus at a dbus path. 236 * Defer signal registration (pass true for deferSignal to the 237 * base class) until after the properties are set. 238 * @param[in] bus - Bus to attach to. 239 * @param[in] path - Path to attach at. 240 * @param[in] manager - Reference to internal manager object. 241 */ 242 Manager(sdbusplus::bus::bus& bus, const std::string& path, 243 internal::Manager& manager) : 244 details::ServerObject<DeleteAllIface, CreateIface>(bus, path.c_str(), 245 true), 246 manager(manager){}; 247 248 /** @brief Delete all d-bus objects. 249 */ 250 void deleteAll() 251 { 252 manager.eraseAll(); 253 } 254 255 /** @brief D-Bus method call implementation to create an event log. 256 * 257 * @param[in] errMsg - The error exception message associated with the 258 * error log to be committed. 259 * @param[in] severity - Level of the error 260 * @param[in] additionalData - The AdditionalData property for the error 261 */ 262 void create( 263 std::string message, 264 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity, 265 std::map<std::string, std::string> additionalData) override 266 { 267 manager.create(message, severity, additionalData); 268 } 269 270 void createWithFFDCFiles( 271 std::string message, 272 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity, 273 std::map<std::string, std::string> additionalData, 274 std::vector<std::tuple<CreateIface::FFDCFormat, uint8_t, uint8_t, 275 sdbusplus::message::unix_fd>> 276 ffdc) override 277 { 278 279 } 280 281 private: 282 /** @brief This is a reference to manager object */ 283 internal::Manager& manager; 284 }; 285 286 } // namespace logging 287 } // namespace phosphor 288