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