blob: 446e5134f4dfb15a5cbfb913461767a42d981862 [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) :
Patrick Williamsdfddd642024-08-16 15:21:51 -0400100 _errorName(error), _fanName(fan), _sensorName(sensor),
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500101 _severity(
102 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
103 severity))
104 {}
105
106 /**
Matt Spinlerbb449c12021-06-14 11:45:28 -0600107 * @brief Constructor
108 *
109 * This version doesn't take a fan or sensor name.
110 *
111 * @param[in] error - The error name, like
112 * xyz.openbmc_project.Fan.Error.Fault
113 * @param[in] severity - The severity of the error
114 */
115 FanError(const std::string& error,
116 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level
117 severity) :
118 _errorName(error),
119 _severity(
120 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
121 severity))
122 {}
123
124 /**
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500125 * @brief Commits the error by calling the D-Bus method to create
126 * the event log.
127 *
128 * The FFDC is passed in here so that if an error is committed
129 * more than once it can have up to date FFDC.
130 *
131 * @param[in] jsonFFDC - Free form JSON data that should be sent in as
132 * FFDC.
Matt Spinlerf435eb12021-05-11 14:44:25 -0500133 * @param[in] isPowerOffError - If this is committed at the time of the
134 * power off.
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500135 */
Matt Spinlerf435eb12021-05-11 14:44:25 -0500136 void commit(const nlohmann::json& jsonFFDC, bool isPowerOffError = false);
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500137
138 private:
139 /**
Mike Capps8beef172022-06-01 11:16:13 -0400140 * @brief returns a JSON structure containing the previous N journal
141 * entries.
142 *
143 * @param[in] numLines - Number of lines of journal to retrieve
144 */
145 nlohmann::json getJournalEntries(int numLines) const;
146
147 /**
148 * Gets the realtime (wallclock) timestamp for the current journal entry.
149 *
150 * @param journal current journal entry
151 * @return timestamp as a date/time string
152 */
153 std::string getTimeStamp(sd_journal* journal) const;
154
155 /**
156 * Gets the value of the specified field for the current journal entry.
157 *
158 * Returns an empty string if the current journal entry does not have the
159 * specified field.
160 *
161 * @param journal current journal entry
162 * @param field journal field name
163 * @return field value
164 */
165 std::string getFieldValue(sd_journal* journal,
166 const std::string& field) const;
167
168 /**
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500169 * @brief Returns an FFDCFile holding the Logger contents
170 *
171 * @return std::unique_ptr<FFDCFile> - The file object
172 */
173 std::unique_ptr<FFDCFile> makeLogFFDCFile();
174
175 /**
176 * @brief Returns an FFDCFile holding the contents of the JSON FFDC
177 *
178 * @param[in] ffdcData - The JSON data to write to a file
179 *
180 * @return std::unique_ptr<FFDCFile> - The file object
181 */
182 std::unique_ptr<FFDCFile> makeJsonFFDCFile(const nlohmann::json& ffdcData);
183
184 /**
185 * @brief Create and returns the AdditionalData property to use for the
186 * event log.
187 *
Matt Spinlerf435eb12021-05-11 14:44:25 -0500188 * @param[in] isPowerOffError - If this is committed at the time of the
189 * power off.
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500190 * @return map<string, string> - The AdditionalData contents
191 */
Matt Spinlerf435eb12021-05-11 14:44:25 -0500192 std::map<std::string, std::string> getAdditionalData(bool isPowerOffError);
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500193
194 /**
195 * @brief The error name (The event log's 'Message' property)
196 */
197 const std::string _errorName;
198
199 /**
200 * @brief The inventory name of the failing fan
201 */
202 const std::string _fanName;
203
204 /**
205 * @brief The inventory name of the failing sensor, if there is one.
206 */
207 const std::string _sensorName;
208
209 /**
210 * @brief The severity of the event log. This is the string
211 * representation of the Entry::Level property.
212 */
213 const std::string _severity;
214};
215
216} // namespace phosphor::fan::monitor