blob: 1ed63ede572d31b9e9b6e127969d5dfb4ff0e0fd [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>
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -05009#include <phosphor-logging/log.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);
Willy Tu6ddbf692023-09-05 10:54:16 -070095 e.sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
Matt Spinleref952af2021-08-19 10:23:05 -050096 resolved, true);
97 e.associations(associations, true);
98 e.version(fwVersion, true);
Willy Tu6ddbf692023-09-05 10:54:16 -070099 e.purpose(sdbusplus::server::xyz::openbmc_project::software::Version::
Matt Spinleref952af2021-08-19 10:23:05 -0500100 VersionPurpose::BMC,
101 true);
102 e.updateTimestamp(updateTimestamp, true);
103 e.eventId(eventId, true);
104 e.resolution(resolution, true);
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500105}
106
Matt Spinlerfb978da2022-01-21 08:42:24 -0600107fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
108{
109 return dir / std::to_string(id);
110}
111
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500112fs::path serialize(const Entry& e, const fs::path& dir)
113{
Matt Spinlerfb978da2022-01-21 08:42:24 -0600114 auto path = getEntrySerializePath(e.id(), dir);
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500115 std::ofstream os(path.c_str(), std::ios::binary);
116 cereal::BinaryOutputArchive oarchive(os);
117 oarchive(e);
118 return path;
119}
120
121bool deserialize(const fs::path& path, Entry& e)
122{
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500123 try
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500124 {
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500125 if (fs::exists(path))
126 {
127 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
128 cereal::BinaryInputArchive iarchive(is);
129 iarchive(e);
130 return true;
131 }
132 return false;
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500133 }
Matt Spinler4a375952022-07-01 11:15:33 -0500134 catch (const cereal::Exception& ex)
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500135 {
Matt Spinler4a375952022-07-01 11:15:33 -0500136 log<level::ERR>(ex.what());
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500137 fs::remove(path);
138 return false;
139 }
Matt Spinler4a375952022-07-01 11:15:33 -0500140 catch (const std::length_error& ex)
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530141 {
142 // Running into: USCiLab/cereal#192
143 // This may be indicating some other issue in the
144 // way vector may have been used inside the logging.
145 // possibly associations ??. But handling it here for
146 // now since we are anyway tossing the log
147 // TODO: openbmc/phosphor-logging#8
Matt Spinler4a375952022-07-01 11:15:33 -0500148 log<level::ERR>(ex.what());
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530149 fs::remove(path);
150 return false;
151 }
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500152}
153
154} // namespace logging
155} // namespace phosphor