blob: 1fd5a1f9f0a37c511a244557cab34ded1490dc1e [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>
6#include <cereal/types/string.hpp>
7#include <cereal/types/tuple.hpp>
8#include <cereal/types/vector.hpp>
Arya K Padman5bc26532024-04-10 06:19:25 -05009#include <phosphor-logging/lg2.hpp>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053010
Patrick Williams2544b412022-10-04 08:41:06 -050011#include <fstream>
12
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053013// Register class version
14// From cereal documentation;
15// "This macro should be placed at global scope"
Patrick Williamsf40323d2021-04-16 15:35:17 -050016CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION)
Deepak Kodihalli72654f12017-06-12 04:33:29 -050017
18namespace phosphor
19{
20namespace logging
21{
22
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050023/** @brief Function required by Cereal to perform serialization.
24 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053025 * @param[in] a - reference to Cereal archive.
26 * @param[in] e - const reference to error entry.
27 * @param[in] version - Class version that enables handling
28 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050029 */
Patrick Venturef18bf832018-10-26 18:14:00 -070030template <class Archive>
Patrick Williamsf40323d2021-04-16 15:35:17 -050031void save(Archive& a, const Entry& e, const std::uint32_t /*version*/)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050032{
Patrick Venturef18bf832018-10-26 18:14:00 -070033 a(e.id(), e.severity(), e.timestamp(), e.message(), e.additionalData(),
Vijay Lobod354a392021-06-01 16:21:02 -050034 e.associations(), e.resolved(), e.version(), e.updateTimestamp(),
Vijay Lobo593a4c62021-06-16 14:25:26 -050035 e.eventId(), e.resolution());
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050036}
37
38/** @brief Function required by Cereal to perform deserialization.
39 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053040 * @param[in] a - reference to Cereal archive.
41 * @param[in] e - reference to error entry.
42 * @param[in] version - Class version that enables handling
43 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050044 */
Patrick Venturef18bf832018-10-26 18:14:00 -070045template <class Archive>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053046void load(Archive& a, Entry& e, const std::uint32_t version)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050047{
Willy Tu6ddbf692023-09-05 10:54:16 -070048 using namespace sdbusplus::server::xyz::openbmc_project::logging;
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050049
50 uint32_t id{};
51 Entry::Level severity{};
52 uint64_t timestamp{};
53 std::string message{};
54 std::vector<std::string> additionalData{};
55 bool resolved{};
56 AssociationList associations{};
Matt Spinler375ac9b2018-05-01 15:20:55 -050057 std::string fwVersion{};
Matt Spinler1e71a4d2020-03-04 13:40:22 -060058 uint64_t updateTimestamp{};
Vijay Lobod354a392021-06-01 16:21:02 -050059 std::string eventId{};
Vijay Lobo593a4c62021-06-16 14:25:26 -050060 std::string resolution{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050061
Matt Spinler375ac9b2018-05-01 15:20:55 -050062 if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
63 {
Patrick Venturef18bf832018-10-26 18:14:00 -070064 a(id, severity, timestamp, message, additionalData, associations,
65 resolved);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060066 updateTimestamp = timestamp;
67 }
68 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_UPDATE_TS))
69 {
70 a(id, severity, timestamp, message, additionalData, associations,
71 resolved, fwVersion);
72 updateTimestamp = timestamp;
Matt Spinler375ac9b2018-05-01 15:20:55 -050073 }
Vijay Lobod354a392021-06-01 16:21:02 -050074 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_EVENTID))
Matt Spinler375ac9b2018-05-01 15:20:55 -050075 {
Patrick Venturef18bf832018-10-26 18:14:00 -070076 a(id, severity, timestamp, message, additionalData, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060077 resolved, fwVersion, updateTimestamp);
Matt Spinler375ac9b2018-05-01 15:20:55 -050078 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050079 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION))
Vijay Lobod354a392021-06-01 16:21:02 -050080 {
81 a(id, severity, timestamp, message, additionalData, associations,
82 resolved, fwVersion, updateTimestamp, eventId);
83 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050084 else
85 {
86 a(id, severity, timestamp, message, additionalData, associations,
87 resolved, fwVersion, updateTimestamp, eventId, resolution);
88 }
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050089
Matt Spinleref952af2021-08-19 10:23:05 -050090 e.id(id, true);
91 e.severity(severity, true);
92 e.timestamp(timestamp, true);
93 e.message(message, true);
94 e.additionalData(additionalData, true);
Patrick Williamse7e741e2024-11-21 16:21:56 -050095 e.additionalData2(util::additional_data::parse(additionalData), true);
Willy Tu6ddbf692023-09-05 10:54:16 -070096 e.sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
Matt Spinleref952af2021-08-19 10:23:05 -050097 resolved, true);
98 e.associations(associations, true);
99 e.version(fwVersion, true);
Willy Tu6ddbf692023-09-05 10:54:16 -0700100 e.purpose(sdbusplus::server::xyz::openbmc_project::software::Version::
Matt Spinleref952af2021-08-19 10:23:05 -0500101 VersionPurpose::BMC,
102 true);
103 e.updateTimestamp(updateTimestamp, true);
104 e.eventId(eventId, true);
105 e.resolution(resolution, true);
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500106}
107
Matt Spinlerfb978da2022-01-21 08:42:24 -0600108fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
109{
110 return dir / std::to_string(id);
111}
112
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500113fs::path serialize(const Entry& e, const fs::path& dir)
114{
Matt Spinlerfb978da2022-01-21 08:42:24 -0600115 auto path = getEntrySerializePath(e.id(), dir);
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500116 std::ofstream os(path.c_str(), std::ios::binary);
117 cereal::BinaryOutputArchive oarchive(os);
118 oarchive(e);
119 return path;
120}
121
122bool deserialize(const fs::path& path, Entry& e)
123{
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500124 try
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500125 {
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500126 if (fs::exists(path))
127 {
128 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
129 cereal::BinaryInputArchive iarchive(is);
130 iarchive(e);
131 return true;
132 }
133 return false;
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500134 }
Matt Spinler4a375952022-07-01 11:15:33 -0500135 catch (const cereal::Exception& ex)
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500136 {
Arya K Padman5bc26532024-04-10 06:19:25 -0500137 lg2::error("{EXCEPTION}", "EXCEPTION", ex);
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500138 fs::remove(path);
139 return false;
140 }
Matt Spinler4a375952022-07-01 11:15:33 -0500141 catch (const std::length_error& ex)
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530142 {
143 // Running into: USCiLab/cereal#192
144 // This may be indicating some other issue in the
145 // way vector may have been used inside the logging.
146 // possibly associations ??. But handling it here for
147 // now since we are anyway tossing the log
148 // TODO: openbmc/phosphor-logging#8
Arya K Padman5bc26532024-04-10 06:19:25 -0500149 lg2::error("{EXCEPTION}", "EXCEPTION", ex);
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530150 fs::remove(path);
151 return false;
152 }
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500153}
154
155} // namespace logging
156} // namespace phosphor