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