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     sdbusplus::bus::bus& getBus()
123     {
124         return busLog;
125     }
126 
127   private:
128     /*
129      * @fn _commit()
130      * @brief commit() helper
131      * @param[in] transactionId - Unique identifier of the journal entries
132      *                            to be committed.
133      * @param[in] errMsg - The error exception message associated with the
134      *                     error log to be committed.
135      * @param[in] errLvl - level of the error
136      */
137     void _commit(uint64_t transactionId, std::string&& errMsg,
138                  Entry::Level errLvl);
139 
140     /** @brief Call metadata handler(s), if any. Handlers may create
141      *         associations.
142      *  @param[in] errorName - name of the error
143      *  @param[in] additionalData - list of metadata (in key=value format)
144      *  @param[out] objects - list of error's association objects
145      */
146     void processMetadata(const std::string& errorName,
147                          const std::vector<std::string>& additionalData,
148                          AssociationList& objects) const;
149 
150     /** @brief Synchronize unwritten journal messages to disk.
151      *  @details This is the same implementation as the systemd command
152      *  "journalctl --sync".
153      */
154     void journalSync();
155 
156     /** @brief Reads the BMC code level
157      *
158      *  @return std::string - the version string
159      */
160     static std::string readFWVersion();
161 
162     /** @brief Call any create() functions provided by any extensions.
163      *  This is called right after an event log is created to allow
164      *  extensions to create their own log based on this one.
165      *
166      *  @param[in] entry - the new event log entry
167      */
168     void doExtensionLogCreate(const Entry& entry);
169 
170     /** @brief Persistent sdbusplus DBus bus connection. */
171     sdbusplus::bus::bus& busLog;
172 
173     /** @brief Persistent map of Entry dbus objects and their ID */
174     std::map<uint32_t, std::unique_ptr<Entry>> entries;
175 
176     /** @brief List of error ids for high severity errors */
177     std::list<uint32_t> realErrors;
178 
179     /** @brief List of error ids for Info(and below) severity */
180     std::list<uint32_t> infoErrors;
181 
182     /** @brief Id of last error log entry */
183     uint32_t entryId;
184 
185     /** @brief The BMC firmware version */
186     const std::string fwVersion;
187 };
188 
189 } // namespace internal
190 
191 /** @class Manager
192  *  @brief Implementation for delete all error log entries.
193  *  @details A concrete implementation for the
194  *  xyz.openbmc_project.Collection.DeleteAll
195  */
196 class Manager : public DeleteAllIface
197 {
198   public:
199     Manager() = delete;
200     Manager(const Manager&) = delete;
201     Manager& operator=(const Manager&) = delete;
202     Manager(Manager&&) = delete;
203     Manager& operator=(Manager&&) = delete;
204     virtual ~Manager() = default;
205 
206     /** @brief Constructor to put object onto bus at a dbus path.
207      *         Defer signal registration (pass true for deferSignal to the
208      *         base class) until after the properties are set.
209      *  @param[in] bus - Bus to attach to.
210      *  @param[in] path - Path to attach at.
211      *  @param[in] manager - Reference to internal manager object.
212      */
213     Manager(sdbusplus::bus::bus& bus, const std::string& path,
214             internal::Manager& manager) :
215         DeleteAllIface(bus, path.c_str(), true),
216         manager(manager){};
217 
218     /** @brief Delete all d-bus objects.
219      */
220     void deleteAll()
221     {
222         manager.eraseAll();
223     }
224 
225   private:
226     /** @brief This is a reference to manager object */
227     internal::Manager& manager;
228 };
229 
230 } // namespace logging
231 } // namespace phosphor
232