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