1 #pragma once 2 #include <phosphor-logging/elog-errors.hpp> 3 #include <phosphor-logging/elog.hpp> 4 #include "callback.hpp" 5 #include <sdbusplus/exception.hpp> 6 #include <experimental/tuple> 7 8 namespace phosphor 9 { 10 namespace dbus 11 { 12 namespace monitoring 13 { 14 15 /** @class ElogBase 16 * @brief Elog callback implementation. 17 * 18 * The elog callback logs the elog and 19 * elog metadata. 20 */ 21 class ElogBase : public Callback 22 { 23 public: 24 ElogBase(const ElogBase&) = delete; 25 ElogBase(ElogBase&&) = default; 26 ElogBase& operator=(const ElogBase&) = delete; 27 ElogBase& operator=(ElogBase&&) = default; 28 virtual ~ElogBase() = default; 29 ElogBase() : 30 Callback() {} 31 32 /** @brief Callback interface implementation. */ 33 void operator()() override; 34 35 private: 36 /** @brief Delegate type specific calls to subclasses. */ 37 virtual void log() const = 0; 38 }; 39 40 namespace detail 41 { 42 43 /** @class CallElog 44 * @brief Provide explicit call forwarding to phosphor::logging::report. 45 * 46 * @tparam T - Error log type 47 * @tparam Args - Metadata fields types. 48 */ 49 template <typename T, typename ...Args> 50 struct CallElog 51 { 52 static void op(Args&& ...args) 53 { 54 phosphor::logging::report<T>(std::forward<Args>(args)...); 55 } 56 }; 57 58 } // namespace detail 59 60 /** @class Elog 61 * @brief C++ type specific logic for the elog callback. 62 * The elog callback logs the elog and elog metadata. 63 * 64 * @tparam T - Error log type 65 * @tparam Args - Metadata fields types. 66 * @param[in] arguments - Metadata fields to be added to the error log 67 */ 68 template <typename T, typename ...Args> 69 class Elog : public ElogBase 70 { 71 public: 72 Elog(const Elog&) = delete; 73 Elog(Elog&&) = default; 74 Elog& operator=(const Elog&) = delete; 75 Elog& operator=(Elog&&) = default; 76 ~Elog() = default; 77 Elog(Args&& ... arguments) : 78 ElogBase(), args(std::forward<Args>(arguments)...) {} 79 80 private: 81 /** @brief elog interface implementation. */ 82 void log() const override 83 { 84 std::experimental::apply( 85 detail::CallElog<T, Args...>::op, 86 std::tuple_cat(args)); 87 } 88 std::tuple<Args...> args; 89 90 }; 91 92 /** @brief Argument type deduction for constructing Elog instances. 93 * 94 * @tparam T - Error log type 95 * @tparam Args - Metadata fields types. 96 * @param[in] arguments - Metadata fields to be added to the error log 97 */ 98 template <typename T, typename ...Args> 99 auto makeElog(Args&& ... arguments) 100 { 101 return std::make_unique<Elog<T, Args...>>( 102 std::forward<Args>(arguments)...); 103 } 104 105 } // namespace monitoring 106 } // namespace dbus 107 } // namespace phosphor 108