mqtt_cpp
log.hpp
Go to the documentation of this file.
1 // Copyright Takatoshi Kondo 2020
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #if !defined(MQTT_LOG_HPP)
8 #define MQTT_LOG_HPP
9 
10 #include <tuple>
11 
12 #include <boost/log/core.hpp>
13 #include <boost/log/attributes.hpp>
14 #include <boost/log/attributes/scoped_attribute.hpp>
15 #include <boost/log/expressions.hpp>
16 #include <boost/log/expressions/keyword.hpp>
17 #include <boost/log/sources/global_logger_storage.hpp>
18 #include <boost/log/sources/severity_channel_logger.hpp>
19 #include <boost/log/trivial.hpp>
20 #include <boost/log/utility/manipulators/add_value.hpp>
21 #include <boost/log/utility/setup/common_attributes.hpp>
22 #include <boost/log/utility/setup/console.hpp>
23 #include <boost/preprocessor/if.hpp>
24 #include <boost/preprocessor/cat.hpp>
25 #include <boost/preprocessor/comparison/greater_equal.hpp>
26 
27 #include <mqtt/namespace.hpp>
28 
29 namespace MQTT_NS {
30 
31 namespace log = boost::log;
32 
33 struct channel : std::string {
34  using std::string::string;
35 };
36 
37 enum class severity_level {
38  trace,
39  debug,
40  info,
41  warning,
42  error,
43  fatal
44 };
45 
46 inline std::ostream& operator<<(std::ostream& o, severity_level sev) {
47  constexpr char const* const str[] {
48  "trace",
49  "debug",
50  "info",
51  "warning",
52  "error",
53  "fatal"
54  };
55  o << str[static_cast<std::size_t>(sev)];
56  return o;
57 }
58 
59 namespace detail {
60 
61 struct null_log {
62  template <typename... Params>
63  constexpr null_log(Params&&...) {}
64 };
65 
66 template <typename T>
67 inline constexpr null_log const& operator<<(null_log const& o, T const&) { return o; }
68 
69 } // namespace detail
70 
71 #if defined(MQTT_USE_LOG)
72 
73 // template arguments are defined in MQTT_NS
74 // filter and formatter can distinguish mqtt_cpp's channel and severity by their types
75 using global_logger_t = log::sources::severity_channel_logger<severity_level, channel>;
76 inline global_logger_t& logger() {
77  thread_local global_logger_t l;
78  return l;
79 }
80 
81 // Normal attributes
82 BOOST_LOG_ATTRIBUTE_KEYWORD(file, "MqttFile", std::string)
83 BOOST_LOG_ATTRIBUTE_KEYWORD(line, "MqttLine", unsigned int)
84 BOOST_LOG_ATTRIBUTE_KEYWORD(function, "MqttFunction", std::string)
85 BOOST_LOG_ATTRIBUTE_KEYWORD(address, "MqttAddress", void const*)
86 
87 
88 // Take any filterable parameters (FP)
89 #define MQTT_LOG_FP(chan, sev) \
90  BOOST_LOG_STREAM_CHANNEL_SEV(MQTT_NS::logger(), MQTT_NS::channel(chan), sev) \
91  << boost::log::add_value(MQTT_NS::file, __FILE__) \
92  << boost::log::add_value(MQTT_NS::line, __LINE__) \
93  << boost::log::add_value(MQTT_NS::function, BOOST_CURRENT_FUNCTION)
94 
95 #define MQTT_GET_LOG_SEV_NUM(lv) BOOST_PP_CAT(MQTT_, lv)
96 
97 // Use can set preprocessor macro MQTT_LOG_SEV.
98 // For example, -DMQTT_LOG_SEV=info, greater or equal to info log is generated at
99 // compiling time.
100 
101 #if !defined(MQTT_LOG_SEV)
102 #define MQTT_LOG_SEV trace
103 #endif // !defined(MQTT_LOG_SEV)
104 
105 #define MQTT_trace 0
106 #define MQTT_debug 1
107 #define MQTT_info 2
108 #define MQTT_warning 3
109 #define MQTT_error 4
110 #define MQTT_fatal 5
111 
112 // User can define custom MQTT_LOG implementation
113 // By default MQTT_LOG_FP is used
114 
115 
116 #if !defined(MQTT_LOG)
117 
118 #define MQTT_LOG(chan, sev) \
119  BOOST_PP_IF( \
120  BOOST_PP_GREATER_EQUAL(MQTT_GET_LOG_SEV_NUM(sev), MQTT_GET_LOG_SEV_NUM(MQTT_LOG_SEV)), \
121  MQTT_LOG_FP(chan, MQTT_NS::severity_level::sev), \
122  MQTT_NS::detail::null_log(chan, MQTT_NS::severity_level::sev) \
123  )
124 
125 #endif // !defined(MQTT_LOG)
126 
127 #if !defined(MQTT_ADD_VALUE)
128 
129 #define MQTT_ADD_VALUE(name, val) boost::log::add_value((MQTT_NS::name), (val))
130 
131 #endif // !defined(MQTT_ADD_VALUE)
132 
133 #else // defined(MQTT_USE_LOG)
134 
135 #define MQTT_LOG(chan, sev) MQTT_NS::detail::null_log(chan, MQTT_NS::severity_level::sev)
136 #define MQTT_ADD_VALUE(name, val) val
137 
138 #endif // defined(MQTT_USE_LOG)
139 
140 } // namespace MQTT_NS
141 
142 #endif // MQTT_LOG_HPP
constexpr null_log const & operator<<(null_log const &o, T const &)
Definition: log.hpp:67
Definition: any.hpp:27
std::ostream & operator<<(std::ostream &os, connect_return_code val)
Definition: connect_return_code.hpp:43
severity_level
Definition: log.hpp:37
Definition: log.hpp:33
Definition: log.hpp:61
constexpr null_log(Params &&...)
Definition: log.hpp:63