blob: e4f545605182efeeb6b4a0b7bca3ea63bbc432c5 [file] [log] [blame]
Gunnar Mills9679d432017-08-03 15:54:43 -05001#pragma once
2#include <phosphor-logging/elog-errors.hpp>
3#include <phosphor-logging/elog.hpp>
4#include "callback.hpp"
5#include <sdbusplus/exception.hpp>
Gunnar Mills30474cf2017-08-11 09:38:54 -05006#include <experimental/tuple>
Gunnar Mills9679d432017-08-03 15:54:43 -05007
8namespace phosphor
9{
10namespace dbus
11{
12namespace monitoring
13{
14
15/** @class ElogBase
16 * @brief Elog callback implementation.
17 *
18 * The elog callback logs the elog and
19 * elog metadata.
20 */
21class 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() :
Gunnar Mills30474cf2017-08-11 09:38:54 -050030 Callback() {}
Gunnar Mills9679d432017-08-03 15:54:43 -050031
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
Gunnar Mills30474cf2017-08-11 09:38:54 -050040namespace 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 */
49template <typename T, typename ...Args>
50struct CallElog
51{
52 static void op(Args&& ...args)
53 {
54 phosphor::logging::report<T>(std::forward<Args>(args)...);
55 }
56};
57
58} // namespace detail
Gunnar Mills9679d432017-08-03 15:54:43 -050059
60/** @class Elog
61 * @brief C++ type specific logic for the elog callback.
Gunnar Mills30474cf2017-08-11 09:38:54 -050062 * The elog callback logs the elog and elog metadata.
Gunnar Mills9679d432017-08-03 15:54:43 -050063 *
64 * @tparam T - Error log type
Gunnar Mills30474cf2017-08-11 09:38:54 -050065 * @tparam Args - Metadata fields types.
66 * @param[in] arguments - Metadata fields to be added to the error log
Gunnar Mills9679d432017-08-03 15:54:43 -050067 */
Gunnar Mills30474cf2017-08-11 09:38:54 -050068template <typename T, typename ...Args>
Gunnar Mills9679d432017-08-03 15:54:43 -050069class 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;
Gunnar Mills30474cf2017-08-11 09:38:54 -050077 Elog(Args&& ... arguments) :
78 ElogBase(), args(std::forward<Args>(arguments)...) {}
Gunnar Mills9679d432017-08-03 15:54:43 -050079
80 private:
81 /** @brief elog interface implementation. */
82 void log() const override
83 {
Gunnar Mills30474cf2017-08-11 09:38:54 -050084 std::experimental::apply(
85 detail::CallElog<T, Args...>::op,
86 std::tuple_cat(args));
Gunnar Mills9679d432017-08-03 15:54:43 -050087 }
Gunnar Mills30474cf2017-08-11 09:38:54 -050088 std::tuple<Args...> args;
89
Gunnar Mills9679d432017-08-03 15:54:43 -050090};
91
Gunnar Mills30474cf2017-08-11 09:38:54 -050092/** @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 */
98template <typename T, typename ...Args>
99auto makeElog(Args&& ... arguments)
100{
101 return std::make_unique<Elog<T, Args...>>(
102 std::forward<Args>(arguments)...);
103}
104
Gunnar Mills9679d432017-08-03 15:54:43 -0500105} // namespace monitoring
106} // namespace dbus
107} // namespace phosphor