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