xref: /openbmc/phosphor-dbus-monitor/src/event_serialize.cpp (revision 3d6d3182ee0b0e88b81fbbbe5c91dea3e99425a9)
1 #include "config.h"
2 
3 #include "event_serialize.hpp"
4 
5 #include <cereal/archives/binary.hpp>
6 #include <cereal/types/string.hpp>
7 #include <cereal/types/vector.hpp>
8 #include <fstream>
9 #include <phosphor-logging/log.hpp>
10 
11 // Register class version
12 // From cereal documentation;
13 // "This macro should be placed at global scope"
14 CEREAL_CLASS_VERSION(phosphor::events::Entry, CLASS_VERSION);
15 
16 namespace phosphor
17 {
18 namespace events
19 {
20 
21 using namespace phosphor::logging;
22 
23 /** @brief Function required by Cereal to perform serialization.
24  *  @tparam Archive - Cereal archive type (binary in our case).
25  *  @param[in] archive - reference to Cereal archive.
26  *  @param[in] event - const reference to event entry.
27  *  @param[in] version - Class version that enables handling
28  *                       a serialized data across code levels
29  */
30 template <class Archive>
31 void save(Archive& archive, const Entry& event, const std::uint32_t version)
32 {
33     archive(event.timestamp(), event.message(), event.additionalData());
34 }
35 
36 /** @brief Function required by Cereal to perform deserialization.
37  *  @tparam Archive - Cereal archive type (binary in our case).
38  *  @param[in] archive - reference to Cereal archive.
39  *  @param[in] event - reference to event entry.
40  *  @param[in] version - Class version that enables handling
41  *                       a serialized data across code levels
42  */
43 template <class Archive>
44 void load(Archive& archive, Entry& event, const std::uint32_t version)
45 {
46     using namespace sdbusplus::xyz::openbmc_project::Logging::server;
47 
48     uint64_t timestamp{};
49     std::string message{};
50     std::vector<std::string> additionalData{};
51 
52     archive(timestamp, message, additionalData);
53 
54     event.timestamp(timestamp);
55     event.message(message);
56     event.additionalData(additionalData);
57 }
58 
59 fs::path serialize(const Entry& event, const std::string& eventName)
60 {
61     fs::path dir(EVENTS_PERSIST_PATH);
62     auto path = dir / eventName;
63     fs::create_directories(path);
64     path /= std::to_string(event.timestamp());
65     std::ofstream os(path.string(), std::ios::binary);
66     cereal::BinaryOutputArchive oarchive(os);
67     oarchive(event);
68     return path;
69 }
70 
71 bool deserialize(const fs::path& path, Entry& event)
72 {
73     try
74     {
75         if (fs::exists(path))
76         {
77             std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
78             cereal::BinaryInputArchive iarchive(is);
79             iarchive(event);
80             return true;
81         }
82         return false;
83     }
84     catch (cereal::Exception& e)
85     {
86         log<level::ERR>(e.what());
87         std::error_code ec;
88         fs::remove(path, ec);
89         return false;
90     }
91     catch (const fs::filesystem_error& e)
92     {
93         return false;
94     }
95 }
96 
97 } // namespace events
98 } // namespace phosphor
99