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