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