1 #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 12 namespace 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 */ 22 class 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 */ ~FFDCFile()43 ~FFDCFile() 44 { 45 std::filesystem::remove(_name); 46 } 47 48 /** 49 * @brief Returns the file descriptor 50 * 51 * @return int - The descriptor 52 */ fd()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 */ 76 class 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 */ FanError(const std::string & error,const std::string & fan,const std::string & sensor,sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity)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), _fanName(fan), _sensorName(sensor), 101 _severity( 102 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage( 103 severity)) 104 {} 105 106 /** 107 * @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 */ FanError(const std::string & error,sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity)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 /** 125 * @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. 133 * @param[in] isPowerOffError - If this is committed at the time of the 134 * power off. 135 */ 136 void commit(const nlohmann::json& jsonFFDC, bool isPowerOffError = false); 137 138 private: 139 /** 140 * @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 /** 169 * @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 * 188 * @param[in] isPowerOffError - If this is committed at the time of the 189 * power off. 190 * @return map<string, string> - The AdditionalData contents 191 */ 192 std::map<std::string, std::string> getAdditionalData(bool isPowerOffError); 193 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 217