diff options
Diffstat (limited to 'src/elog.hpp')
-rw-r--r-- | src/elog.hpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/elog.hpp b/src/elog.hpp index c3b0d02..3f8ae3b 100644 --- a/src/elog.hpp +++ b/src/elog.hpp @@ -12,6 +12,25 @@ namespace dbus namespace monitoring { +/** @struct ToString + * @brief Convert numbers to strings + */ +template <typename T> struct ToString +{ + static auto op(T&& value) + { + return std::to_string(std::forward<T>(value)); + } +}; + +template <> struct ToString<std::string> +{ + static auto op(const std::string& value) + { + return value; + } +}; + /** @class ElogBase * @brief Elog callback implementation. * @@ -89,6 +108,103 @@ class Elog : public ElogBase }; + +/** + * @class ElogWithMetadataCapture + * + * @brief A callback class that will save the paths, names, and + * current values of certain properties in the metadata of the + * error log it creates. + * + * The intended use case of this class is to create an error log with + * metadata that includes the property names and values that caused + * the condition to issue this callback. When the condition ran, it had + * set the pass/fail field on each property it checked in the properties' + * entries in the Storage array. This class then looks at those pass/fail + * fields to see which properties to log. + * + * Note that it's OK if different conditions and callbacks share the same + * properties because everything runs serially, so another condition can't + * touch those pass/fail fields until all of the first condition's callbacks + * are done. + * + * This class requires that the error log created only have 1 metadata field, + * and it must take a string. + * + * @tparam errorType - Error log type + * @tparam metadataType - The metadata to use + * @tparam propertyType - The data type of the captured properties + */ +template<typename errorType, + typename metadataType, + typename propertyType> +class ElogWithMetadataCapture : public IndexedCallback +{ + public: + ElogWithMetadataCapture() = delete; + ElogWithMetadataCapture(const ElogWithMetadataCapture&) = delete; + ElogWithMetadataCapture(ElogWithMetadataCapture&&) = default; + ElogWithMetadataCapture& operator=( + const ElogWithMetadataCapture&) = delete; + ElogWithMetadataCapture& operator=( + ElogWithMetadataCapture&&) = default; + virtual ~ElogWithMetadataCapture() = default; + explicit ElogWithMetadataCapture( + const PropertyIndex& index) : + IndexedCallback(index) {} + + /** + * @brief Callback interface implementation that + * creates an error log + */ + void operator()(Context ctx) override + { + auto data = captureMetadata(); + + phosphor::logging::report<errorType>( + metadataType(data.c_str())); + } + + private: + + /** + * @brief Builds a metadata string with property information + * + * Finds all of the properties in the index that have + * their condition pass/fail fields (get<1>(storage)) + * set to true, and then packs those paths, names, and values + * into a metadata string that looks like: + * + * |path1:name1=value1|path2:name2=value2|... + * + * @return The metadata string + */ + std::string captureMetadata() + { + std::string metadata{'|'}; + + for (const auto& n : index) + { + const auto& storage = std::get<2>(n.second).get(); + const auto& result = std::get<1>(storage); + + if (!result.empty() && any_ns::any_cast<bool>(result)) + { + const auto& path = std::get<0>(n.first).get(); + const auto& propertyName = std::get<2>(n.first).get(); + auto value = ToString<propertyType>::op( + any_ns::any_cast<propertyType>( + std::get<0>(storage))); + + metadata += path + ":" + propertyName + + '=' + value + '|'; + } + } + + return metadata; + }; +}; + /** @brief Argument type deduction for constructing Elog instances. * * @tparam T - Error log type |