log.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #if !defined(MQTT_LOG_HPP)
  7. #define MQTT_LOG_HPP
  8. #include <cstddef>
  9. #include <ostream>
  10. #include <string>
  11. #if defined(MQTT_USE_LOG)
  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. #endif // defined(MQTT_USE_LOG)
  27. #include <mqtt/namespace.hpp>
  28. namespace MQTT_NS {
  29. struct channel : std::string {
  30. using std::string::string;
  31. };
  32. enum class severity_level {
  33. trace,
  34. debug,
  35. info,
  36. warning,
  37. error,
  38. fatal
  39. };
  40. inline std::ostream& operator<<(std::ostream& o, severity_level sev) {
  41. constexpr char const* const str[] {
  42. "trace",
  43. "debug",
  44. "info",
  45. "warning",
  46. "error",
  47. "fatal"
  48. };
  49. o << str[static_cast<std::size_t>(sev)];
  50. return o;
  51. }
  52. namespace detail {
  53. struct null_log {
  54. template <typename... Params>
  55. constexpr null_log(Params&&...) {}
  56. };
  57. template <typename T>
  58. inline constexpr null_log const& operator<<(null_log const& o, T const&) { return o; }
  59. } // namespace detail
  60. #if defined(MQTT_USE_LOG)
  61. // template arguments are defined in MQTT_NS
  62. // filter and formatter can distinguish mqtt_cpp's channel and severity by their types
  63. using global_logger_t = boost::log::sources::severity_channel_logger<severity_level, channel>;
  64. inline global_logger_t& logger() {
  65. thread_local global_logger_t l;
  66. return l;
  67. }
  68. // Normal attributes
  69. BOOST_LOG_ATTRIBUTE_KEYWORD(file, "MqttFile", std::string)
  70. BOOST_LOG_ATTRIBUTE_KEYWORD(line, "MqttLine", unsigned int)
  71. BOOST_LOG_ATTRIBUTE_KEYWORD(function, "MqttFunction", std::string)
  72. BOOST_LOG_ATTRIBUTE_KEYWORD(address, "MqttAddress", void const*)
  73. // Take any filterable parameters (FP)
  74. #define MQTT_LOG_FP(chan, sev) \
  75. BOOST_LOG_STREAM_CHANNEL_SEV(MQTT_NS::logger(), MQTT_NS::channel(chan), sev) \
  76. << boost::log::add_value(MQTT_NS::file, __FILE__) \
  77. << boost::log::add_value(MQTT_NS::line, __LINE__) \
  78. << boost::log::add_value(MQTT_NS::function, BOOST_CURRENT_FUNCTION)
  79. #define MQTT_GET_LOG_SEV_NUM(lv) BOOST_PP_CAT(MQTT_, lv)
  80. // Use can set preprocessor macro MQTT_LOG_SEV.
  81. // For example, -DMQTT_LOG_SEV=info, greater or equal to info log is generated at
  82. // compiling time.
  83. #if !defined(MQTT_LOG_SEV)
  84. #define MQTT_LOG_SEV trace
  85. #endif // !defined(MQTT_LOG_SEV)
  86. #define MQTT_trace 0
  87. #define MQTT_debug 1
  88. #define MQTT_info 2
  89. #define MQTT_warning 3
  90. #define MQTT_error 4
  91. #define MQTT_fatal 5
  92. // User can define custom MQTT_LOG implementation
  93. // By default MQTT_LOG_FP is used
  94. #if !defined(MQTT_LOG)
  95. #define MQTT_LOG(chan, sev) \
  96. BOOST_PP_IF( \
  97. BOOST_PP_GREATER_EQUAL(MQTT_GET_LOG_SEV_NUM(sev), MQTT_GET_LOG_SEV_NUM(MQTT_LOG_SEV)), \
  98. MQTT_LOG_FP(chan, MQTT_NS::severity_level::sev), \
  99. MQTT_NS::detail::null_log(chan, MQTT_NS::severity_level::sev) \
  100. )
  101. #endif // !defined(MQTT_LOG)
  102. #if !defined(MQTT_ADD_VALUE)
  103. #define MQTT_ADD_VALUE(name, val) boost::log::add_value((MQTT_NS::name), (val))
  104. #endif // !defined(MQTT_ADD_VALUE)
  105. #else // defined(MQTT_USE_LOG)
  106. #if !defined(MQTT_LOG)
  107. #define MQTT_LOG(chan, sev) MQTT_NS::detail::null_log(chan, MQTT_NS::severity_level::sev)
  108. #endif // !defined(MQTT_LOG)
  109. #if !defined(MQTT_ADD_VALUE)
  110. #define MQTT_ADD_VALUE(name, val) val
  111. #endif // !defined(MQTT_ADD_VALUE)
  112. #endif // defined(MQTT_USE_LOG)
  113. } // namespace MQTT_NS
  114. #endif // MQTT_LOG_HPP