blob: 6a2dac44207957c182a5c492414b12d3cd86912d [file] [log] [blame]
Patrick Venturef18bf832018-10-26 18:14:00 -07001#include "config.h"
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -05002
Deepak Kodihalli72654f12017-06-12 04:33:29 -05003#include "elog_serialize.hpp"
Patrick Venturef18bf832018-10-26 18:14:00 -07004
5#include <cereal/archives/binary.hpp>
Patrick Williams5402fa62024-11-22 14:42:52 -05006#include <cereal/types/map.hpp>
Patrick Venturef18bf832018-10-26 18:14:00 -07007#include <cereal/types/string.hpp>
8#include <cereal/types/tuple.hpp>
9#include <cereal/types/vector.hpp>
Arya K Padman5bc26532024-04-10 06:19:25 -050010#include <phosphor-logging/lg2.hpp>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053011
Patrick Williams2544b412022-10-04 08:41:06 -050012#include <fstream>
13
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053014// Register class version
15// From cereal documentation;
16// "This macro should be placed at global scope"
Patrick Williamsf40323d2021-04-16 15:35:17 -050017CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION)
Deepak Kodihalli72654f12017-06-12 04:33:29 -050018
19namespace phosphor
20{
21namespace logging
22{
23
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050024/** @brief Function required by Cereal to perform serialization.
25 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053026 * @param[in] a - reference to Cereal archive.
27 * @param[in] e - const reference to error entry.
28 * @param[in] version - Class version that enables handling
29 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050030 */
Patrick Venturef18bf832018-10-26 18:14:00 -070031template <class Archive>
Patrick Williamsf40323d2021-04-16 15:35:17 -050032void save(Archive& a, const Entry& e, const std::uint32_t /*version*/)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050033{
Patrick Williams5402fa62024-11-22 14:42:52 -050034 a(e.id(), e.severity(), e.timestamp(), e.message(), e.additionalData2(),
Vijay Lobod354a392021-06-01 16:21:02 -050035 e.associations(), e.resolved(), e.version(), e.updateTimestamp(),
Vijay Lobo593a4c62021-06-16 14:25:26 -050036 e.eventId(), e.resolution());
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050037}
38
39/** @brief Function required by Cereal to perform deserialization.
40 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053041 * @param[in] a - reference to Cereal archive.
42 * @param[in] e - reference to error entry.
43 * @param[in] version - Class version that enables handling
44 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050045 */
Patrick Venturef18bf832018-10-26 18:14:00 -070046template <class Archive>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053047void load(Archive& a, Entry& e, const std::uint32_t version)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050048{
Willy Tu6ddbf692023-09-05 10:54:16 -070049 using namespace sdbusplus::server::xyz::openbmc_project::logging;
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050050
51 uint32_t id{};
52 Entry::Level severity{};
53 uint64_t timestamp{};
54 std::string message{};
Patrick Williams5402fa62024-11-22 14:42:52 -050055 std::map<std::string, std::string> additionalData{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050056 bool resolved{};
57 AssociationList associations{};
Matt Spinler375ac9b2018-05-01 15:20:55 -050058 std::string fwVersion{};
Matt Spinler1e71a4d2020-03-04 13:40:22 -060059 uint64_t updateTimestamp{};
Vijay Lobod354a392021-06-01 16:21:02 -050060 std::string eventId{};
Vijay Lobo593a4c62021-06-16 14:25:26 -050061 std::string resolution{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050062
Matt Spinler375ac9b2018-05-01 15:20:55 -050063 if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
64 {
Patrick Williams5402fa62024-11-22 14:42:52 -050065 std::vector<std::string> additionalData_old{};
66 a(id, severity, timestamp, message, additionalData_old, associations,
Patrick Venturef18bf832018-10-26 18:14:00 -070067 resolved);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060068 updateTimestamp = timestamp;
Patrick Williams5402fa62024-11-22 14:42:52 -050069 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060070 }
71 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_UPDATE_TS))
72 {
Patrick Williams5402fa62024-11-22 14:42:52 -050073 std::vector<std::string> additionalData_old{};
74 a(id, severity, timestamp, message, additionalData_old, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060075 resolved, fwVersion);
76 updateTimestamp = timestamp;
Patrick Williams5402fa62024-11-22 14:42:52 -050077 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler375ac9b2018-05-01 15:20:55 -050078 }
Vijay Lobod354a392021-06-01 16:21:02 -050079 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_EVENTID))
Matt Spinler375ac9b2018-05-01 15:20:55 -050080 {
Patrick Williams5402fa62024-11-22 14:42:52 -050081 std::vector<std::string> additionalData_old{};
82 a(id, severity, timestamp, message, additionalData_old, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060083 resolved, fwVersion, updateTimestamp);
Patrick Williams5402fa62024-11-22 14:42:52 -050084 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler375ac9b2018-05-01 15:20:55 -050085 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050086 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION))
Vijay Lobod354a392021-06-01 16:21:02 -050087 {
Patrick Williams5402fa62024-11-22 14:42:52 -050088 std::vector<std::string> additionalData_old{};
89 a(id, severity, timestamp, message, additionalData_old, associations,
Vijay Lobod354a392021-06-01 16:21:02 -050090 resolved, fwVersion, updateTimestamp, eventId);
Patrick Williams5402fa62024-11-22 14:42:52 -050091 additionalData = util::additional_data::parse(additionalData_old);
92 }
93 else if (version <
94 std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_METADATA_DICT))
95 {
96 std::vector<std::string> additionalData_old{};
97 a(id, severity, timestamp, message, additionalData_old, associations,
98 resolved, fwVersion, updateTimestamp, eventId, resolution);
99 additionalData = util::additional_data::parse(additionalData_old);
Vijay Lobod354a392021-06-01 16:21:02 -0500100 }
Vijay Lobo593a4c62021-06-16 14:25:26 -0500101 else
102 {
103 a(id, severity, timestamp, message, additionalData, associations,
104 resolved, fwVersion, updateTimestamp, eventId, resolution);
105 }
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500106
Matt Spinleref952af2021-08-19 10:23:05 -0500107 e.id(id, true);
108 e.severity(severity, true);
109 e.timestamp(timestamp, true);
110 e.message(message, true);
Patrick Williams5402fa62024-11-22 14:42:52 -0500111 e.additionalData(util::additional_data::combine(additionalData), true);
112 e.additionalData2(additionalData, true);
Willy Tu6ddbf692023-09-05 10:54:16 -0700113 e.sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
Matt Spinleref952af2021-08-19 10:23:05 -0500114 resolved, true);
115 e.associations(associations, true);
116 e.version(fwVersion, true);
Willy Tu6ddbf692023-09-05 10:54:16 -0700117 e.purpose(sdbusplus::server::xyz::openbmc_project::software::Version::
Matt Spinleref952af2021-08-19 10:23:05 -0500118 VersionPurpose::BMC,
119 true);
120 e.updateTimestamp(updateTimestamp, true);
121 e.eventId(eventId, true);
122 e.resolution(resolution, true);
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500123}
124
Matt Spinlerfb978da2022-01-21 08:42:24 -0600125fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
126{
127 return dir / std::to_string(id);
128}
129
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500130fs::path serialize(const Entry& e, const fs::path& dir)
131{
Matt Spinlerfb978da2022-01-21 08:42:24 -0600132 auto path = getEntrySerializePath(e.id(), dir);
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500133 std::ofstream os(path.c_str(), std::ios::binary);
134 cereal::BinaryOutputArchive oarchive(os);
135 oarchive(e);
136 return path;
137}
138
139bool deserialize(const fs::path& path, Entry& e)
140{
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500141 try
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500142 {
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500143 if (fs::exists(path))
144 {
145 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
146 cereal::BinaryInputArchive iarchive(is);
147 iarchive(e);
148 return true;
149 }
150 return false;
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500151 }
Matt Spinler4a375952022-07-01 11:15:33 -0500152 catch (const cereal::Exception& ex)
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500153 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500154 lg2::error("{EXCEPTION}", "EXCEPTION", ex);
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500155 fs::remove(path);
156 return false;
157 }
Matt Spinler4a375952022-07-01 11:15:33 -0500158 catch (const std::length_error& ex)
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530159 {
160 // Running into: USCiLab/cereal#192
161 // This may be indicating some other issue in the
162 // way vector may have been used inside the logging.
163 // possibly associations ??. But handling it here for
164 // now since we are anyway tossing the log
165 // TODO: openbmc/phosphor-logging#8
Arya K Padman5bc26532024-04-10 06:19:25 -0500166 lg2::error("{EXCEPTION}", "EXCEPTION", ex);
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530167 fs::remove(path);
168 return false;
169 }
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500170}
171
172} // namespace logging
173} // namespace phosphor