async_mqtt 5.0.0
Loading...
Searching...
No Matches
setup_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_SETUP_LOG_HPP)
8#define ASYNC_MQTT_SETUP_LOG_HPP
9
10// This is an example implementation for logging setup.
11// If your code doesn't use Boost.Log then you can use the setup_log() directly.
12// setup_log() provides a typical console logging setup.
13// If you want to use existing Boost.Log related code with mqtt_cpp,
14// then you can write your own logging setup code.
15// setup_log() could be a good reference for your own logging setup code.
16
17#include <async_mqtt/log.hpp>
18
19#if defined(ASYNC_MQTT_USE_LOG)
20
21#include <async_mqtt/util/move.hpp>
22
23#include <boost/filesystem.hpp>
24#include <boost/date_time/posix_time/posix_time_io.hpp>
25
26#endif // defined(ASYNC_MQTT_USE_LOG)
27
28namespace async_mqtt {
29
30#if defined(ASYNC_MQTT_USE_LOG)
31
32static constexpr char const* log_color_table[] {
33 "\033[0m", // trace
34 "\033[36m", // debug
35 "\033[32m", // info
36 "\033[33m", // warning
37 "\033[35m", // error
38 "\033[31m", // fatal
39};
40
47inline
48void setup_log(std::map<std::string, severity_level> threshold) {
49 // https://www.boost.org/doc/libs/1_73_0/libs/log/doc/html/log/tutorial/advanced_filtering.html
50
51 auto fmt =
52 [](boost::log::record_view const& rec, boost::log::formatting_ostream& strm) {
53 // Timestamp custom formatting example
54 if (auto v = boost::log::extract<boost::posix_time::ptime>("TimeStamp", rec)) {
55 strm.imbue(
56 std::locale(
57 strm.getloc(),
58 // https://www.boost.org/doc/html/date_time/date_time_io.html#date_time.format_flags
59 new boost::posix_time::time_facet("%H:%M:%s") // ownership is moved here
60 )
61 );
62 strm << v.get() << " ";
63 }
64 // ThreadID example
65 if (auto v = boost::log::extract<boost::log::thread_id>("ThreadID", rec)) {
66 strm << "T:" << v.get() << " ";
67 }
68 // Adjust severity length example
69 if (auto v = boost::log::extract<severity_level>("Severity", rec)) {
70 strm << log_color_table[static_cast<std::size_t>(v.get())];
71 strm << "S:" << std::setw(7) << std::left << v.get() << " ";
72 }
73 if (auto v = boost::log::extract<channel>("Channel", rec)) {
74 strm << "C:" << std::setw(5) << std::left << v.get() << " ";
75 }
76 // Shorten file path example
77 if (auto v = boost::log::extract<std::string>("MqttFile", rec)) {
78 strm << boost::filesystem::path(v.get()).filename().string() << ":";
79 }
80 if (auto v = boost::log::extract<unsigned int>("MqttLine", rec)) {
81 strm << v.get() << " ";
82 }
83 if (auto v = boost::log::extract<void const*>("MqttAddress", rec)) {
84 strm << "A:" << v.get() << " ";
85 }
86
87#if 0 // function is ofthen noisy
88 if (auto v = boost::log::extract<std::string>("MqttFunction", rec)) {
89 strm << v << ":";
90 }
91#endif
92 strm << rec[boost::log::expressions::smessage];
93 strm << "\033[0m";
94 };
95
96 // https://www.boost.org/doc/libs/1_73_0/libs/log/doc/html/log/tutorial/sinks.html
97 boost::shared_ptr<std::ostream> stream(&std::clog, boost::null_deleter());
98
99 using text_sink = boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend>;
100 auto sink = boost::make_shared<text_sink>();
101 sink->locked_backend()->add_stream(stream);
102 sink->set_formatter(fmt);
103
104 auto fil =
105 [threshold = force_move(threshold)]
106 (boost::log::attribute_value_set const& avs) {
107 {
108 // For mqtt
109 auto chan = boost::log::extract<channel>("Channel", avs);
110 auto sev = boost::log::extract<severity_level>("Severity", avs);
111 if (chan && sev) {
112 auto it = threshold.find(chan.get());
113 if (it == threshold.end()) return false;
114 return sev.get() >= it->second;
115 }
116 }
117 return true;
118 };
119
120 boost::log::core::get()->set_filter(fil);
121 boost::log::core::get()->add_sink(sink);
122
123 boost::log::add_common_attributes();
124}
125
132inline
133void setup_log(severity_level threshold = severity_level::warning) {
134 setup_log(
135 {
136 { "mqtt_api", threshold },
137 { "mqtt_cb", threshold },
138 { "mqtt_impl", threshold },
139 { "mqtt_broker", threshold },
140 { "mqtt_test", threshold },
141 }
142 );
143}
144
145#else // defined(ASYNC_MQTT_USE_LOG)
146
147template <typename... Params>
148void setup_log(Params&&...) {}
149
150#endif // defined(ASYNC_MQTT_USE_LOG)
151
152} // namespace async_mqtt
153
154#endif // ASYNC_MQTT_SETUP_LOG_HPP
decltype(auto) get()
Get by type. If not match, then throw std::bad_variant_access exception.
Definition packet_variant.hpp:113