1 #pragma once
2 
3 #include <phosphor-logging/log.hpp>
4 #include "callback.hpp"
5 #include "format.hpp"
6 
7 namespace phosphor
8 {
9 namespace dbus
10 {
11 namespace monitoring
12 {
13 
14 /** @class JournalBase
15  *  @brief Journal callback implementation.
16  *
17  *  The journal callback logs the client message and
18  *  journal metadata key value pairs as specified by the
19  *  client supplied property index.
20  */
21 class JournalBase : public IndexedCallback
22 {
23   public:
24     JournalBase() = delete;
25     JournalBase(const JournalBase&) = delete;
26     JournalBase(JournalBase&&) = default;
27     JournalBase& operator=(const JournalBase&) = delete;
28     JournalBase& operator=(JournalBase&&) = default;
29     virtual ~JournalBase() = default;
30     JournalBase(const char* msg, const PropertyIndex& index) :
31         IndexedCallback(index), message(msg)
32     {
33     }
34 
35     /** @brief Callback interface implementation. */
36     void operator()(Context ctx) override;
37 
38   private:
39     /** @brief Delegate type specific calls to subclasses. */
40     virtual void log(const char* message, const std::string& pathMeta,
41                      const std::string& path, const std::string& propertyMeta,
42                      const any_ns::any& value) const = 0;
43 
44     /** @brief The client provided message to be traced.  */
45     const char* message;
46 };
47 
48 /** @struct Display
49  *  @brief Convert strings to const char*.
50  */
51 namespace detail
52 {
53 template <typename T> struct Display
54 {
55     static auto op(T&& value)
56     {
57         return std::forward<T>(value);
58     }
59 };
60 
61 template <> struct Display<std::string>
62 {
63     static auto op(const std::string& value)
64     {
65         return value.c_str();
66     }
67 };
68 } // namespace detail
69 
70 /** @class Journal
71  *  @brief C++ type specific logic for the journal callback.
72  *
73  *  @tparam T - The C++ type of the property values being traced.
74  *  @tparam Severity - The log severity of the log entry.
75  */
76 template <typename T, phosphor::logging::level Severity>
77 class Journal : public JournalBase
78 {
79   public:
80     Journal() = delete;
81     Journal(const Journal&) = delete;
82     Journal(Journal&&) = default;
83     Journal& operator=(const Journal&) = delete;
84     Journal& operator=(Journal&&) = default;
85     ~Journal() = default;
86     Journal(const char* msg, const PropertyIndex& index) :
87         JournalBase(msg, index)
88     {
89     }
90 
91   private:
92     /** @brief log interface implementation. */
93     void log(const char* message, const std::string& pathMeta,
94              const std::string& path, const std::string& propertyMeta,
95              const any_ns::any& value) const override
96     {
97         phosphor::logging::log<Severity>(
98             message,
99             phosphor::logging::entry(
100                 (pathMeta + GetFormat<decltype(pathMeta)>::format).c_str(),
101                 path.c_str()),
102             phosphor::logging::entry(
103                 (propertyMeta + GetFormat<T>::format).c_str(),
104                 detail::Display<T>::op(any_ns::any_cast<T>(value))));
105     }
106 };
107 
108 } // namespace monitoring
109 } // namespace dbus
110 } // namespace phosphor
111