blob: 1f36c2f4c49a6caae443326755e47429e46d1bb5 [file] [log] [blame]
Matt Spinlerf13b42e2020-10-26 15:29:49 -05001#pragma once
2
3#include "utility.hpp"
4
5#include <nlohmann/json.hpp>
6#include <xyz/openbmc_project/Logging/Entry/server.hpp>
7
8#include <filesystem>
9#include <string>
10#include <tuple>
11
12namespace phosphor::fan::monitor
13{
14
15/**
16 * @class FFDCFile
17 *
18 * This class holds a file that is used for event log FFDC
19 * which needs a file descriptor as input. The file is
20 * deleted upon destruction.
21 */
22class FFDCFile
23{
24 public:
25 FFDCFile() = delete;
26 FFDCFile(const FFDCFile&) = delete;
27 FFDCFile& operator=(const FFDCFile&) = delete;
28 FFDCFile(FFDCFile&&) = delete;
29 FFDCFile& operator=(FFDCFile&&) = delete;
30
31 /**
32 * @brief Constructor
33 *
34 * Opens the file and saves the descriptor
35 *
36 * @param[in] name - The filename
37 */
38 explicit FFDCFile(const std::filesystem::path& name);
39
40 /**
41 * @brief Destructor - Deletes the file
42 */
43 ~FFDCFile()
44 {
45 std::filesystem::remove(_name);
46 }
47
48 /**
49 * @brief Returns the file descriptor
50 *
51 * @return int - The descriptor
52 */
53 int fd()
54 {
55 return _fd();
56 }
57
58 private:
59 /**
60 * @brief The file descriptor holder
61 */
62 util::FileDescriptor _fd;
63
64 /**
65 * @brief The filename
66 */
67 const std::filesystem::path _name;
68};
69
70/**
71 * @class FanError
72 *
73 * This class represents a fan error. It has a commit() interface
74 * that will create the event log with certain FFDC.
75 */
76class FanError
77{
78 public:
79 FanError() = delete;
80 ~FanError() = default;
81 FanError(const FanError&) = delete;
82 FanError& operator=(const FanError&) = delete;
83 FanError(FanError&&) = delete;
84 FanError& operator=(FanError&&) = delete;
85
86 /**
87 * @brief Constructor
88 *
89 * @param[in] error - The error name, like
90 * xyz.openbmc_project.Fan.Error.Fault
91 * @param[in] fan - The failing fan's inventory path
92 * @param[in] sensor - The failing sensor's inventory path. Can be empty
93 * if the error is for the FRU and not the sensor.
94 * @param[in] severity - The severity of the error
95 */
96 FanError(const std::string& error, const std::string& fan,
97 const std::string& sensor,
98 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level
99 severity) :
100 _errorName(error),
101 _fanName(fan), _sensorName(sensor),
102 _severity(
103 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
104 severity))
105 {}
106
107 /**
Matt Spinlerbb449c12021-06-14 11:45:28 -0600108 * @brief Constructor
109 *
110 * This version doesn't take a fan or sensor name.
111 *
112 * @param[in] error - The error name, like
113 * xyz.openbmc_project.Fan.Error.Fault
114 * @param[in] severity - The severity of the error
115 */
116 FanError(const std::string& error,
117 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level
118 severity) :
119 _errorName(error),
120 _severity(
121 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
122 severity))
123 {}
124
125 /**
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500126 * @brief Commits the error by calling the D-Bus method to create
127 * the event log.
128 *
129 * The FFDC is passed in here so that if an error is committed
130 * more than once it can have up to date FFDC.
131 *
132 * @param[in] jsonFFDC - Free form JSON data that should be sent in as
133 * FFDC.
Matt Spinlerf435eb12021-05-11 14:44:25 -0500134 * @param[in] isPowerOffError - If this is committed at the time of the
135 * power off.
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500136 */
Matt Spinlerf435eb12021-05-11 14:44:25 -0500137 void commit(const nlohmann::json& jsonFFDC, bool isPowerOffError = false);
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500138
139 private:
140 /**
Mike Capps8beef172022-06-01 11:16:13 -0400141 * @brief returns a JSON structure containing the previous N journal
142 * entries.
143 *
144 * @param[in] numLines - Number of lines of journal to retrieve
145 */
146 nlohmann::json getJournalEntries(int numLines) const;
147
148 /**
149 * Gets the realtime (wallclock) timestamp for the current journal entry.
150 *
151 * @param journal current journal entry
152 * @return timestamp as a date/time string
153 */
154 std::string getTimeStamp(sd_journal* journal) const;
155
156 /**
157 * Gets the value of the specified field for the current journal entry.
158 *
159 * Returns an empty string if the current journal entry does not have the
160 * specified field.
161 *
162 * @param journal current journal entry
163 * @param field journal field name
164 * @return field value
165 */
166 std::string getFieldValue(sd_journal* journal,
167 const std::string& field) const;
168
169 /**
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500170 * @brief Returns an FFDCFile holding the Logger contents
171 *
172 * @return std::unique_ptr<FFDCFile> - The file object
173 */
174 std::unique_ptr<FFDCFile> makeLogFFDCFile();
175
176 /**
177 * @brief Returns an FFDCFile holding the contents of the JSON FFDC
178 *
179 * @param[in] ffdcData - The JSON data to write to a file
180 *
181 * @return std::unique_ptr<FFDCFile> - The file object
182 */
183 std::unique_ptr<FFDCFile> makeJsonFFDCFile(const nlohmann::json& ffdcData);
184
185 /**
186 * @brief Create and returns the AdditionalData property to use for the
187 * event log.
188 *
Matt Spinlerf435eb12021-05-11 14:44:25 -0500189 * @param[in] isPowerOffError - If this is committed at the time of the
190 * power off.
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500191 * @return map<string, string> - The AdditionalData contents
192 */
Matt Spinlerf435eb12021-05-11 14:44:25 -0500193 std::map<std::string, std::string> getAdditionalData(bool isPowerOffError);
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500194
195 /**
196 * @brief The error name (The event log's 'Message' property)
197 */
198 const std::string _errorName;
199
200 /**
201 * @brief The inventory name of the failing fan
202 */
203 const std::string _fanName;
204
205 /**
206 * @brief The inventory name of the failing sensor, if there is one.
207 */
208 const std::string _sensorName;
209
210 /**
211 * @brief The severity of the event log. This is the string
212 * representation of the Entry::Level property.
213 */
214 const std::string _severity;
215};
216
217} // namespace phosphor::fan::monitor