summaryrefslogtreecommitdiffstats
path: root/src/elog.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/elog.hpp')
-rw-r--r--src/elog.hpp116
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
OpenPOWER on IntegriCloud