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