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 e = iter->first;
105             ++iter;
106             erase(e);
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 Call any create() functions provided by any extensions.
158      *  This is called right after an event log is created to allow
159      *  extensions to create their own log based on this one.
160      *
161      *  @param[in] entry - the new event log entry
162      */
163     void doExtensionLogCreate(const Entry& entry);
164 
165     /** @brief Persistent sdbusplus DBus bus connection. */
166     sdbusplus::bus::bus& busLog;
167 
168     /** @brief Persistent map of Entry dbus objects and their ID */
169     std::map<uint32_t, std::unique_ptr<Entry>> entries;
170 
171     /** @brief List of error ids for high severity errors */
172     std::list<uint32_t> realErrors;
173 
174     /** @brief List of error ids for Info(and below) severity */
175     std::list<uint32_t> infoErrors;
176 
177     /** @brief Id of last error log entry */
178     uint32_t entryId;
179 
180     /** @brief The BMC firmware version */
181     const std::string fwVersion;
182 };
183 
184 } // namespace internal
185 
186 /** @class Manager
187  *  @brief Implementation for delete all error log entries.
188  *  @details A concrete implementation for the
189  *  xyz.openbmc_project.Collection.DeleteAll
190  */
191 class Manager : public DeleteAllIface
192 {
193   public:
194     Manager() = delete;
195     Manager(const Manager&) = delete;
196     Manager& operator=(const Manager&) = delete;
197     Manager(Manager&&) = delete;
198     Manager& operator=(Manager&&) = delete;
199     virtual ~Manager() = default;
200 
201     /** @brief Constructor to put object onto bus at a dbus path.
202      *         Defer signal registration (pass true for deferSignal to the
203      *         base class) until after the properties are set.
204      *  @param[in] bus - Bus to attach to.
205      *  @param[in] path - Path to attach at.
206      *  @param[in] manager - Reference to internal manager object.
207      */
208     Manager(sdbusplus::bus::bus& bus, const std::string& path,
209             internal::Manager& manager) :
210         DeleteAllIface(bus, path.c_str(), true),
211         manager(manager){};
212 
213     /** @brief Delete all d-bus objects.
214      */
215     void deleteAll()
216     {
217         manager.eraseAll();
218     }
219 
220   private:
221     /** @brief This is a reference to manager object */
222     internal::Manager& manager;
223 };
224 
225 } // namespace logging
226 } // namespace phosphor
227