async_mqtt 5.0.0
Loading...
Searching...
No Matches
log.hpp
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(ASYNC_MQTT_LOG_HPP)
8#define ASYNC_MQTT_LOG_HPP
9
10#include <cstddef>
11#include <ostream>
12#include <string>
13
14#if defined(ASYNC_MQTT_USE_LOG)
15
16#include <boost/log/core.hpp>
17#include <boost/log/attributes.hpp>
18#include <boost/log/attributes/scoped_attribute.hpp>
19#include <boost/log/expressions.hpp>
20#include <boost/log/expressions/keyword.hpp>
21#include <boost/log/sources/global_logger_storage.hpp>
22#include <boost/log/sources/severity_channel_logger.hpp>
23#include <boost/log/trivial.hpp>
24#include <boost/log/utility/manipulators/add_value.hpp>
25#include <boost/log/utility/setup/common_attributes.hpp>
26#include <boost/log/utility/setup/console.hpp>
27#include <boost/preprocessor/if.hpp>
28#include <boost/preprocessor/cat.hpp>
29#include <boost/preprocessor/comparison/greater_equal.hpp>
30
31#endif // defined(ASYNC_MQTT_USE_LOG)
32
33namespace async_mqtt {
34
35struct channel : std::string {
36 using std::string::string;
37};
38
39enum class severity_level {
40 trace,
41 debug,
42 info,
43 warning,
44 error,
45 fatal
46};
47
48inline std::ostream& operator<<(std::ostream& o, severity_level sev) {
49 constexpr char const* const str[] {
50 "trace",
51 "debug",
52 "info",
53 "warning",
54 "error",
55 "fatal"
56 };
57 o << str[static_cast<std::size_t>(sev)];
58 return o;
59}
60
61namespace detail {
62
63struct null_log {
64 template <typename... Params>
65 constexpr null_log(Params&&...) {}
66};
67
68template <typename T>
69inline constexpr null_log const& operator<<(null_log const& o, T const&) { return o; }
70
71} // namespace detail
72
73#if defined(ASYNC_MQTT_USE_LOG)
74
75// template arguments are defined in async_mqtt
76// filter and formatter can distinguish mqtt_cpp's channel and severity by their types
77using global_logger_t = boost::log::sources::severity_channel_logger<severity_level, channel>;
78inline global_logger_t& logger() {
79 thread_local global_logger_t l;
80 return l;
81}
82
83// Normal attributes
84BOOST_LOG_ATTRIBUTE_KEYWORD(file, "MqttFile", std::string)
85BOOST_LOG_ATTRIBUTE_KEYWORD(line, "MqttLine", unsigned int)
86BOOST_LOG_ATTRIBUTE_KEYWORD(function, "MqttFunction", std::string)
87BOOST_LOG_ATTRIBUTE_KEYWORD(address, "MqttAddress", void const*)
88
89
90// Take any filterable parameters (FP)
91#define ASYNC_MQTT_LOG_FP(chan, sev) \
92 BOOST_LOG_STREAM_CHANNEL_SEV(async_mqtt::logger(), async_mqtt::channel(chan), sev) \
93 << boost::log::add_value(async_mqtt::file, __FILE__) \
94 << boost::log::add_value(async_mqtt::line, __LINE__) \
95 << boost::log::add_value(async_mqtt::function, BOOST_CURRENT_FUNCTION)
96
97#define ASYNC_MQTT_GET_LOG_SEV_NUM(lv) BOOST_PP_CAT(ASYNC_MQTT_, lv)
98
99// Use can set preprocessor macro ASYNC_MQTT_LOG_SEV.
100// For example, -DASYNC_MQTT_LOG_SEV=info, greater or equal to info log is generated at
101// compiling time.
102
103#if !defined(ASYNC_MQTT_LOG_SEV)
104#define ASYNC_MQTT_LOG_SEV trace
105#endif // !defined(ASYNC_MQTT_LOG_SEV)
106
107#define ASYNC_MQTT_trace 0
108#define ASYNC_MQTT_debug 1
109#define ASYNC_MQTT_info 2
110#define ASYNC_MQTT_warning 3
111#define ASYNC_MQTT_error 4
112#define ASYNC_MQTT_fatal 5
113
114// User can define custom ASYNC_MQTT_LOG implementation
115// By default ASYNC_MQTT_LOG_FP is used
116
117
118#if !defined(ASYNC_MQTT_LOG)
119
120#define ASYNC_MQTT_LOG(chan, sev) \
121 BOOST_PP_IF( \
122 BOOST_PP_GREATER_EQUAL(ASYNC_MQTT_GET_LOG_SEV_NUM(sev), ASYNC_MQTT_GET_LOG_SEV_NUM(ASYNC_MQTT_LOG_SEV)), \
123 ASYNC_MQTT_LOG_FP(chan, async_mqtt::severity_level::sev), \
124 async_mqtt::detail::null_log(chan, async_mqtt::severity_level::sev) \
125 )
126
127#endif // !defined(ASYNC_MQTT_LOG)
128
129#if !defined(ASYNC_MQTT_ADD_VALUE)
130
131#define ASYNC_MQTT_ADD_VALUE(name, val) boost::log::add_value((async_mqtt::name), (val))
132
133#endif // !defined(ASYNC_MQTT_ADD_VALUE)
134
135#else // defined(ASYNC_MQTT_USE_LOG)
136
137#if !defined(ASYNC_MQTT_LOG)
138
139#define ASYNC_MQTT_LOG(chan, sev) async_mqtt::detail::null_log(chan, async_mqtt::severity_level::sev)
140
141#endif // !defined(ASYNC_MQTT_LOG)
142
143#if !defined(ASYNC_MQTT_ADD_VALUE)
144
145#define ASYNC_MQTT_ADD_VALUE(name, val) val
146
147#endif // !defined(ASYNC_MQTT_ADD_VALUE)
148
149#endif // defined(ASYNC_MQTT_USE_LOG)
150
151} // namespace async_mqtt
152
153#endif // ASYNC_MQTT_LOG_HPP