123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- // Copyright Takatoshi Kondo 2020
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #if !defined(MQTT_SETUP_LOG_HPP)
- #define MQTT_SETUP_LOG_HPP
- // This is an example implementation for logging setup.
- // If your code doesn't use Boost.Log then you can use the setup_log() directly.
- // setup_log() provides a typical console logging setup.
- // If you want to use existing Boost.Log related code with mqtt_cpp,
- // then you can write your own logging setup code.
- // setup_log() could be a good reference for your own logging setup code.
- #include <mqtt/namespace.hpp>
- #include <mqtt/log.hpp>
- #if defined(MQTT_USE_LOG)
- #include <mqtt/move.hpp>
- #include <boost/filesystem.hpp>
- #include <boost/date_time/posix_time/posix_time_io.hpp>
- #endif // defined(MQTT_USE_LOG)
- namespace MQTT_NS {
- #if defined(MQTT_USE_LOG)
- static constexpr char const* log_color_table[] {
- "\033[0m", // trace
- "\033[36m", // debug
- "\033[32m", // info
- "\033[33m", // warning
- "\033[35m", // error
- "\033[31m", // fatal
- };
- /**
- * @brief Setup logging
- * @param threshold
- * Set threshold severity_level by channel
- * If the log severity_level >= threshold then log message outputs.
- */
- inline
- void setup_log(std::map<std::string, severity_level> threshold) {
- // https://www.boost.org/doc/libs/1_73_0/libs/log/doc/html/log/tutorial/advanced_filtering.html
- auto fmt =
- [](boost::log::record_view const& rec, boost::log::formatting_ostream& strm) {
- // Timestamp custom formatting example
- if (auto v = boost::log::extract<boost::posix_time::ptime>("TimeStamp", rec)) {
- strm.imbue(
- std::locale(
- strm.getloc(),
- // https://www.boost.org/doc/html/date_time/date_time_io.html#date_time.format_flags
- new boost::posix_time::time_facet("%H:%M:%s") // ownership is moved here
- )
- );
- strm << v.get() << " ";
- }
- // ThreadID example
- if (auto v = boost::log::extract<boost::log::thread_id>("ThreadID", rec)) {
- strm << "T:" << v.get() << " ";
- }
- // Adjust severity length example
- if (auto v = boost::log::extract<severity_level>("Severity", rec)) {
- strm << log_color_table[static_cast<std::size_t>(v.get())];
- strm << "S:" << std::setw(7) << std::left << v.get() << " ";
- }
- if (auto v = boost::log::extract<channel>("Channel", rec)) {
- strm << "C:" << std::setw(5) << std::left << v.get() << " ";
- }
- // Shorten file path example
- if (auto v = boost::log::extract<std::string>("MqttFile", rec)) {
- strm << boost::filesystem::path(v.get()).filename().string() << ":";
- }
- if (auto v = boost::log::extract<unsigned int>("MqttLine", rec)) {
- strm << v.get() << " ";
- }
- if (auto v = boost::log::extract<void const*>("MqttAddress", rec)) {
- strm << "A:" << v.get() << " ";
- }
- #if 0 // function is ofthen noisy
- if (auto v = boost::log::extract<std::string>("MqttFunction", rec)) {
- strm << v << ":";
- }
- #endif
- strm << rec[boost::log::expressions::smessage];
- strm << "\033[0m";
- };
- // https://www.boost.org/doc/libs/1_73_0/libs/log/doc/html/log/tutorial/sinks.html
- boost::shared_ptr<std::ostream> stream(&std::clog, boost::null_deleter());
- using text_sink = boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend>;
- auto sink = boost::make_shared<text_sink>();
- sink->locked_backend()->add_stream(stream);
- sink->set_formatter(fmt);
- auto fil =
- [threshold = force_move(threshold)]
- (boost::log::attribute_value_set const& avs) {
- {
- // For mqtt
- auto chan = boost::log::extract<channel>("Channel", avs);
- auto sev = boost::log::extract<severity_level>("Severity", avs);
- if (chan && sev) {
- auto it = threshold.find(chan.get());
- if (it == threshold.end()) return false;
- return sev.get() >= it->second;
- }
- }
- return true;
- };
- boost::log::core::get()->set_filter(fil);
- boost::log::core::get()->add_sink(sink);
- boost::log::add_common_attributes();
- }
- /**
- * @brief Setup logging
- * @param threshold
- * Set threshold severity_level for all channels
- * If the log severity_level >= threshold then log message outputs.
- */
- inline
- void setup_log(severity_level threshold = severity_level::warning) {
- setup_log(
- {
- { "mqtt_api", threshold },
- { "mqtt_cb", threshold },
- { "mqtt_impl", threshold },
- { "mqtt_broker", threshold },
- { "mqtt_test", threshold },
- }
- );
- }
- #else // defined(MQTT_USE_LOG)
- template <typename... Params>
- void setup_log(Params&&...) {}
- #endif // defined(MQTT_USE_LOG)
- } // namespace MQTT_NS
- #endif // MQTT_SETUP_LOG_HPP
|