blob: 087ef40dac0b848e45a322b030d516cac82b848b [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>
9#include <fstream>
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -050010#include <phosphor-logging/log.hpp>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053011
12// Register class version
13// From cereal documentation;
14// "This macro should be placed at global scope"
Patrick Williamsf40323d2021-04-16 15:35:17 -050015CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION)
Deepak Kodihalli72654f12017-06-12 04:33:29 -050016
17namespace phosphor
18{
19namespace logging
20{
21
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050022/** @brief Function required by Cereal to perform serialization.
23 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053024 * @param[in] a - reference to Cereal archive.
25 * @param[in] e - const reference to error entry.
26 * @param[in] version - Class version that enables handling
27 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050028 */
Patrick Venturef18bf832018-10-26 18:14:00 -070029template <class Archive>
Patrick Williamsf40323d2021-04-16 15:35:17 -050030void save(Archive& a, const Entry& e, const std::uint32_t /*version*/)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050031{
Patrick Venturef18bf832018-10-26 18:14:00 -070032 a(e.id(), e.severity(), e.timestamp(), e.message(), e.additionalData(),
Vijay Lobod354a392021-06-01 16:21:02 -050033 e.associations(), e.resolved(), e.version(), e.updateTimestamp(),
Vijay Lobo593a4c62021-06-16 14:25:26 -050034 e.eventId(), e.resolution());
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050035}
36
37/** @brief Function required by Cereal to perform deserialization.
38 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053039 * @param[in] a - reference to Cereal archive.
40 * @param[in] e - reference to error entry.
41 * @param[in] version - Class version that enables handling
42 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050043 */
Patrick Venturef18bf832018-10-26 18:14:00 -070044template <class Archive>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053045void load(Archive& a, Entry& e, const std::uint32_t version)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050046{
Patrick Venturef18bf832018-10-26 18:14:00 -070047 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050048
49 uint32_t id{};
50 Entry::Level severity{};
51 uint64_t timestamp{};
52 std::string message{};
53 std::vector<std::string> additionalData{};
54 bool resolved{};
55 AssociationList associations{};
Matt Spinler375ac9b2018-05-01 15:20:55 -050056 std::string fwVersion{};
Matt Spinler1e71a4d2020-03-04 13:40:22 -060057 uint64_t updateTimestamp{};
Vijay Lobod354a392021-06-01 16:21:02 -050058 std::string eventId{};
Vijay Lobo593a4c62021-06-16 14:25:26 -050059 std::string resolution{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050060
Matt Spinler375ac9b2018-05-01 15:20:55 -050061 if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
62 {
Patrick Venturef18bf832018-10-26 18:14:00 -070063 a(id, severity, timestamp, message, additionalData, associations,
64 resolved);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060065 updateTimestamp = timestamp;
66 }
67 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_UPDATE_TS))
68 {
69 a(id, severity, timestamp, message, additionalData, associations,
70 resolved, fwVersion);
71 updateTimestamp = timestamp;
Matt Spinler375ac9b2018-05-01 15:20:55 -050072 }
Vijay Lobod354a392021-06-01 16:21:02 -050073 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_EVENTID))
Matt Spinler375ac9b2018-05-01 15:20:55 -050074 {
Patrick Venturef18bf832018-10-26 18:14:00 -070075 a(id, severity, timestamp, message, additionalData, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060076 resolved, fwVersion, updateTimestamp);
Matt Spinler375ac9b2018-05-01 15:20:55 -050077 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050078 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION))
Vijay Lobod354a392021-06-01 16:21:02 -050079 {
80 a(id, severity, timestamp, message, additionalData, associations,
81 resolved, fwVersion, updateTimestamp, eventId);
82 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050083 else
84 {
85 a(id, severity, timestamp, message, additionalData, associations,
86 resolved, fwVersion, updateTimestamp, eventId, resolution);
87 }
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050088
Matt Spinleref952af2021-08-19 10:23:05 -050089 e.id(id, true);
90 e.severity(severity, true);
91 e.timestamp(timestamp, true);
92 e.message(message, true);
93 e.additionalData(additionalData, true);
Patrick Venturef18bf832018-10-26 18:14:00 -070094 e.sdbusplus::xyz::openbmc_project::Logging::server::Entry::resolved(
Matt Spinleref952af2021-08-19 10:23:05 -050095 resolved, true);
96 e.associations(associations, true);
97 e.version(fwVersion, true);
Patrick Venturef18bf832018-10-26 18:14:00 -070098 e.purpose(sdbusplus::xyz::openbmc_project::Software::server::Version::
Matt Spinleref952af2021-08-19 10:23:05 -050099 VersionPurpose::BMC,
100 true);
101 e.updateTimestamp(updateTimestamp, true);
102 e.eventId(eventId, true);
103 e.resolution(resolution, true);
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500104}
105
Matt Spinlerfb978da2022-01-21 08:42:24 -0600106fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
107{
108 return dir / std::to_string(id);
109}
110
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500111fs::path serialize(const Entry& e, const fs::path& dir)
112{
Matt Spinlerfb978da2022-01-21 08:42:24 -0600113 auto path = getEntrySerializePath(e.id(), dir);
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500114 std::ofstream os(path.c_str(), std::ios::binary);
115 cereal::BinaryOutputArchive oarchive(os);
116 oarchive(e);
117 return path;
118}
119
120bool deserialize(const fs::path& path, Entry& e)
121{
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500122 try
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500123 {
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500124 if (fs::exists(path))
125 {
126 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
127 cereal::BinaryInputArchive iarchive(is);
128 iarchive(e);
129 return true;
130 }
131 return false;
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500132 }
Patrick Williams66491c62021-10-06 12:23:37 -0500133 catch (const cereal::Exception& e)
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500134 {
135 log<level::ERR>(e.what());
136 fs::remove(path);
137 return false;
138 }
Patrick Venturef18bf832018-10-26 18:14:00 -0700139 catch (const std::length_error& e)
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530140 {
141 // Running into: USCiLab/cereal#192
142 // This may be indicating some other issue in the
143 // way vector may have been used inside the logging.
144 // possibly associations ??. But handling it here for
145 // now since we are anyway tossing the log
146 // TODO: openbmc/phosphor-logging#8
147 log<level::ERR>(e.what());
148 fs::remove(path);
149 return false;
150 }
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500151}
152
153} // namespace logging
154} // namespace phosphor