loggingmacros.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. // -*- C++ -*-
  2. // Module: Log4CPLUS
  3. // File: loggingmacros.h
  4. // Created: 8/2003
  5. // Author: Tad E. Smith
  6. //
  7. //
  8. // Copyright 2003-2017 Tad E. Smith
  9. //
  10. // Licensed under the Apache License, Version 2.0 (the "License");
  11. // you may not use this file except in compliance with the License.
  12. // You may obtain a copy of the License at
  13. //
  14. // http://www.apache.org/licenses/LICENSE-2.0
  15. //
  16. // Unless required by applicable law or agreed to in writing, software
  17. // distributed under the License is distributed on an "AS IS" BASIS,
  18. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. // See the License for the specific language governing permissions and
  20. // limitations under the License.
  21. /** @file
  22. * This header defines the logging macros. */
  23. #ifndef LOG4CPLUS_LOGGING_MACROS_HEADER_
  24. #define LOG4CPLUS_LOGGING_MACROS_HEADER_
  25. #include <log4cplus/config.hxx>
  26. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  27. #pragma once
  28. #endif
  29. #include <log4cplus/streams.h>
  30. #include <log4cplus/logger.h>
  31. #include <log4cplus/helpers/snprintf.h>
  32. #include <log4cplus/tracelogger.h>
  33. #include <sstream>
  34. #include <utility>
  35. #if defined(_MSC_VER)
  36. #define LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  37. __pragma (warning (push)) \
  38. __pragma (warning (disable:4127))
  39. #define LOG4CPLUS_RESTORE_DOWHILE_WARNING() \
  40. __pragma (warning (pop))
  41. #else
  42. #define LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() /* empty */
  43. #define LOG4CPLUS_RESTORE_DOWHILE_WARNING() /* empty */
  44. #endif
  45. #define LOG4CPLUS_DOWHILE_NOTHING() \
  46. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  47. do { } while (0) \
  48. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  49. #if defined(LOG4CPLUS_DISABLE_FATAL) && !defined(LOG4CPLUS_DISABLE_ERROR)
  50. #define LOG4CPLUS_DISABLE_ERROR
  51. #endif
  52. #if defined(LOG4CPLUS_DISABLE_ERROR) && !defined(LOG4CPLUS_DISABLE_WARN)
  53. #define LOG4CPLUS_DISABLE_WARN
  54. #endif
  55. #if defined(LOG4CPLUS_DISABLE_WARN) && !defined(LOG4CPLUS_DISABLE_INFO)
  56. #define LOG4CPLUS_DISABLE_INFO
  57. #endif
  58. #if defined(LOG4CPLUS_DISABLE_INFO) && !defined(LOG4CPLUS_DISABLE_DEBUG)
  59. #define LOG4CPLUS_DISABLE_DEBUG
  60. #endif
  61. #if defined(LOG4CPLUS_DISABLE_DEBUG) && !defined(LOG4CPLUS_DISABLE_TRACE)
  62. #define LOG4CPLUS_DISABLE_TRACE
  63. #endif
  64. namespace log4cplus
  65. {
  66. namespace detail
  67. {
  68. inline
  69. Logger
  70. macros_get_logger (Logger const & logger)
  71. {
  72. return logger;
  73. }
  74. inline
  75. Logger const &
  76. macros_get_logger (Logger & logger)
  77. {
  78. return logger;
  79. }
  80. inline
  81. Logger
  82. macros_get_logger (Logger && logger)
  83. {
  84. return std::move (logger);
  85. }
  86. inline
  87. Logger
  88. macros_get_logger (tstring const & logger)
  89. {
  90. return Logger::getInstance (logger);
  91. }
  92. inline
  93. Logger
  94. macros_get_logger (tchar const * logger)
  95. {
  96. return Logger::getInstance (logger);
  97. }
  98. LOG4CPLUS_EXPORT void clear_tostringstream (tostringstream &);
  99. LOG4CPLUS_EXPORT log4cplus::tostringstream & get_macro_body_oss ();
  100. LOG4CPLUS_EXPORT log4cplus::helpers::snprintf_buf & get_macro_body_snprintf_buf ();
  101. LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
  102. log4cplus::LogLevel, log4cplus::tstring const &, char const *, int,
  103. char const *);
  104. LOG4CPLUS_EXPORT void macro_forced_log (log4cplus::Logger const &,
  105. log4cplus::LogLevel, log4cplus::tchar const *, char const *, int,
  106. char const *);
  107. } // namespace detail
  108. } // namespace log4cplus
  109. #undef LOG4CPLUS_MACRO_FUNCTION
  110. #define LOG4CPLUS_MACRO_FUNCTION() nullptr
  111. #if ! defined (LOG4CPLUS_DISABLE_FUNCTION_MACRO)
  112. # if defined (LOG4CPLUS_HAVE_FUNCSIG_MACRO)
  113. # undef LOG4CPLUS_MACRO_FUNCTION
  114. # define LOG4CPLUS_MACRO_FUNCTION() __FUNCSIG__
  115. # elif defined (LOG4CPLUS_HAVE_PRETTY_FUNCTION_MACRO)
  116. # undef LOG4CPLUS_MACRO_FUNCTION
  117. # define LOG4CPLUS_MACRO_FUNCTION() __PRETTY_FUNCTION__
  118. # elif defined (LOG4CPLUS_HAVE_FUNCTION_MACRO)
  119. # undef LOG4CPLUS_MACRO_FUNCTION
  120. # define LOG4CPLUS_MACRO_FUNCTION() __FUNCTION__
  121. # elif defined (LOG4CPLUS_HAVE_FUNC_SYMBOL)
  122. # undef LOG4CPLUS_MACRO_FUNCTION
  123. # define LOG4CPLUS_MACRO_FUNCTION() __func__
  124. # endif
  125. #endif
  126. #undef LOG4CPLUS_MACRO_FILE
  127. #define LOG4CPLUS_MACRO_FILE() nullptr
  128. #if ! defined (LOG4CPLUS_DISABLE_FILE_MACRO)
  129. # undef LOG4CPLUS_MACRO_FILE
  130. # define LOG4CPLUS_MACRO_FILE() __FILE__
  131. #endif
  132. // Make TRACE and DEBUG log level unlikely and INFO, WARN, ERROR and
  133. // FATAL log level likely.
  134. #define LOG4CPLUS_MACRO_TRACE_LOG_LEVEL(pred) \
  135. LOG4CPLUS_UNLIKELY (pred)
  136. #define LOG4CPLUS_MACRO_DEBUG_LOG_LEVEL(pred) \
  137. LOG4CPLUS_UNLIKELY (pred)
  138. #define LOG4CPLUS_MACRO_INFO_LOG_LEVEL(pred) \
  139. LOG4CPLUS_LIKELY (pred)
  140. #define LOG4CPLUS_MACRO_WARN_LOG_LEVEL(pred) \
  141. LOG4CPLUS_LIKELY (pred)
  142. #define LOG4CPLUS_MACRO_ERROR_LOG_LEVEL(pred) \
  143. LOG4CPLUS_LIKELY (pred)
  144. #define LOG4CPLUS_MACRO_FATAL_LOG_LEVEL(pred) \
  145. LOG4CPLUS_LIKELY (pred)
  146. //! Dispatch to LOG4CPLUS_MACRO_LOGLEVEL_* depending on log level.
  147. #define LOG4CPLUS_MACRO_LOGLEVEL_PRED(pred, logLevel) \
  148. LOG4CPLUS_MACRO_ ## logLevel (pred)
  149. // Either use temporary instances of ostringstream
  150. // and snprintf_buf, or use thread-local instances.
  151. #if defined (LOG4CPLUS_MACRO_DISABLE_TLS)
  152. # define LOG4CPLUS_MACRO_INSTANTIATE_OSTRINGSTREAM(var) \
  153. log4cplus::tostringstream var
  154. # define LOG4CPLUS_MACRO_INSTANTIATE_SNPRINTF_BUF(var) \
  155. log4cplus::helpers::snprintf_buf var
  156. #else
  157. # define LOG4CPLUS_MACRO_INSTANTIATE_OSTRINGSTREAM(var) \
  158. log4cplus::tostringstream & var \
  159. = log4cplus::detail::get_macro_body_oss ()
  160. # define LOG4CPLUS_MACRO_INSTANTIATE_SNPRINTF_BUF(var) \
  161. log4cplus::helpers::snprintf_buf & var \
  162. = log4cplus::detail::get_macro_body_snprintf_buf ()
  163. #endif
  164. #define LOG4CPLUS_MACRO_BODY(logger, logEvent, logLevel) \
  165. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  166. do { \
  167. log4cplus::Logger const & _l \
  168. = log4cplus::detail::macros_get_logger (logger); \
  169. if (LOG4CPLUS_MACRO_LOGLEVEL_PRED ( \
  170. _l.isEnabledFor (log4cplus::logLevel), logLevel)) { \
  171. LOG4CPLUS_MACRO_INSTANTIATE_OSTRINGSTREAM (_log4cplus_buf); \
  172. _log4cplus_buf << logEvent; \
  173. log4cplus::detail::macro_forced_log (_l, \
  174. log4cplus::logLevel, _log4cplus_buf.str(), \
  175. LOG4CPLUS_MACRO_FILE (), __LINE__, \
  176. LOG4CPLUS_MACRO_FUNCTION ()); \
  177. } \
  178. } while (0) \
  179. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  180. #define LOG4CPLUS_MACRO_STR_BODY(logger, logEvent, logLevel) \
  181. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  182. do { \
  183. log4cplus::Logger const & _l \
  184. = log4cplus::detail::macros_get_logger (logger); \
  185. if (LOG4CPLUS_MACRO_LOGLEVEL_PRED ( \
  186. _l.isEnabledFor (log4cplus::logLevel), logLevel)) { \
  187. log4cplus::detail::macro_forced_log (_l, \
  188. log4cplus::logLevel, logEvent, \
  189. LOG4CPLUS_MACRO_FILE (), __LINE__, \
  190. LOG4CPLUS_MACRO_FUNCTION ()); \
  191. } \
  192. } while(0) \
  193. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  194. #define LOG4CPLUS_MACRO_FMT_BODY(logger, logLevel, ...) \
  195. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  196. do { \
  197. log4cplus::Logger const & _l \
  198. = log4cplus::detail::macros_get_logger (logger); \
  199. if (LOG4CPLUS_MACRO_LOGLEVEL_PRED ( \
  200. _l.isEnabledFor (log4cplus::logLevel), logLevel)) { \
  201. LOG4CPLUS_MACRO_INSTANTIATE_SNPRINTF_BUF (_snpbuf); \
  202. log4cplus::tchar const * _logEvent \
  203. = _snpbuf.print (__VA_ARGS__); \
  204. log4cplus::detail::macro_forced_log (_l, \
  205. log4cplus::logLevel, _logEvent, \
  206. LOG4CPLUS_MACRO_FILE (), __LINE__, \
  207. LOG4CPLUS_MACRO_FUNCTION ()); \
  208. } \
  209. } while(0) \
  210. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  211. /**
  212. * @def LOG4CPLUS_TRACE(logger, logEvent) This macro creates a
  213. * TraceLogger to log a TRACE_LOG_LEVEL message to <code>logger</code>
  214. * upon entry and exiting of a method.
  215. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  216. */
  217. #if !defined(LOG4CPLUS_DISABLE_TRACE)
  218. #define LOG4CPLUS_TRACE_METHOD(logger, logEvent) \
  219. log4cplus::TraceLogger _log4cplus_trace_logger(logger, logEvent, \
  220. LOG4CPLUS_MACRO_FILE (), __LINE__, \
  221. LOG4CPLUS_MACRO_FUNCTION ());
  222. #define LOG4CPLUS_TRACE(logger, logEvent) \
  223. LOG4CPLUS_MACRO_BODY (logger, logEvent, TRACE_LOG_LEVEL)
  224. #define LOG4CPLUS_TRACE_STR(logger, logEvent) \
  225. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, TRACE_LOG_LEVEL)
  226. #define LOG4CPLUS_TRACE_FMT(logger, ...) \
  227. LOG4CPLUS_MACRO_FMT_BODY (logger, TRACE_LOG_LEVEL, __VA_ARGS__)
  228. #else
  229. #define LOG4CPLUS_TRACE_METHOD(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  230. #define LOG4CPLUS_TRACE(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  231. #define LOG4CPLUS_TRACE_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  232. #define LOG4CPLUS_TRACE_FMT(logger, logFmt, ...) LOG4CPLUS_DOWHILE_NOTHING()
  233. #endif
  234. /**
  235. * @def LOG4CPLUS_DEBUG(logger, logEvent) This macro is used to log a
  236. * DEBUG_LOG_LEVEL message to <code>logger</code>.
  237. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  238. */
  239. #if !defined(LOG4CPLUS_DISABLE_DEBUG)
  240. #define LOG4CPLUS_DEBUG(logger, logEvent) \
  241. LOG4CPLUS_MACRO_BODY (logger, logEvent, DEBUG_LOG_LEVEL)
  242. #define LOG4CPLUS_DEBUG_STR(logger, logEvent) \
  243. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, DEBUG_LOG_LEVEL)
  244. #define LOG4CPLUS_DEBUG_FMT(logger, ...) \
  245. LOG4CPLUS_MACRO_FMT_BODY (logger, DEBUG_LOG_LEVEL, __VA_ARGS__)
  246. #else
  247. #define LOG4CPLUS_DEBUG(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  248. #define LOG4CPLUS_DEBUG_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  249. #define LOG4CPLUS_DEBUG_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
  250. #endif
  251. /**
  252. * @def LOG4CPLUS_INFO(logger, logEvent) This macro is used to log a
  253. * INFO_LOG_LEVEL message to <code>logger</code>.
  254. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  255. */
  256. #if !defined(LOG4CPLUS_DISABLE_INFO)
  257. #define LOG4CPLUS_INFO(logger, logEvent) \
  258. LOG4CPLUS_MACRO_BODY (logger, logEvent, INFO_LOG_LEVEL)
  259. #define LOG4CPLUS_INFO_STR(logger, logEvent) \
  260. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, INFO_LOG_LEVEL)
  261. #define LOG4CPLUS_INFO_FMT(logger, ...) \
  262. LOG4CPLUS_MACRO_FMT_BODY (logger, INFO_LOG_LEVEL, __VA_ARGS__)
  263. #else
  264. #define LOG4CPLUS_INFO(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  265. #define LOG4CPLUS_INFO_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  266. #define LOG4CPLUS_INFO_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
  267. #endif
  268. /**
  269. * @def LOG4CPLUS_WARN(logger, logEvent) This macro is used to log a
  270. * WARN_LOG_LEVEL message to <code>logger</code>.
  271. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  272. */
  273. #if !defined(LOG4CPLUS_DISABLE_WARN)
  274. #define LOG4CPLUS_WARN(logger, logEvent) \
  275. LOG4CPLUS_MACRO_BODY (logger, logEvent, WARN_LOG_LEVEL)
  276. #define LOG4CPLUS_WARN_STR(logger, logEvent) \
  277. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, WARN_LOG_LEVEL)
  278. #define LOG4CPLUS_WARN_FMT(logger, ...) \
  279. LOG4CPLUS_MACRO_FMT_BODY (logger, WARN_LOG_LEVEL, __VA_ARGS__)
  280. #else
  281. #define LOG4CPLUS_WARN(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  282. #define LOG4CPLUS_WARN_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  283. #define LOG4CPLUS_WARN_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
  284. #endif
  285. /**
  286. * @def LOG4CPLUS_ERROR(logger, logEvent) This macro is used to log a
  287. * ERROR_LOG_LEVEL message to <code>logger</code>.
  288. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  289. */
  290. #if !defined(LOG4CPLUS_DISABLE_ERROR)
  291. #define LOG4CPLUS_ERROR(logger, logEvent) \
  292. LOG4CPLUS_MACRO_BODY (logger, logEvent, ERROR_LOG_LEVEL)
  293. #define LOG4CPLUS_ERROR_STR(logger, logEvent) \
  294. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, ERROR_LOG_LEVEL)
  295. #define LOG4CPLUS_ERROR_FMT(logger, ...) \
  296. LOG4CPLUS_MACRO_FMT_BODY (logger, ERROR_LOG_LEVEL, __VA_ARGS__)
  297. #else
  298. #define LOG4CPLUS_ERROR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  299. #define LOG4CPLUS_ERROR_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  300. #define LOG4CPLUS_ERROR_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
  301. #endif
  302. /**
  303. * @def LOG4CPLUS_FATAL(logger, logEvent) This macro is used to log a
  304. * FATAL_LOG_LEVEL message to <code>logger</code>.
  305. * <code>logEvent</code> will be streamed into an <code>ostream</code>.
  306. */
  307. #if !defined(LOG4CPLUS_DISABLE_FATAL)
  308. #define LOG4CPLUS_FATAL(logger, logEvent) \
  309. LOG4CPLUS_MACRO_BODY (logger, logEvent, FATAL_LOG_LEVEL)
  310. #define LOG4CPLUS_FATAL_STR(logger, logEvent) \
  311. LOG4CPLUS_MACRO_STR_BODY (logger, logEvent, FATAL_LOG_LEVEL)
  312. #define LOG4CPLUS_FATAL_FMT(logger, ...) \
  313. LOG4CPLUS_MACRO_FMT_BODY (logger, FATAL_LOG_LEVEL, __VA_ARGS__)
  314. #else
  315. #define LOG4CPLUS_FATAL(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  316. #define LOG4CPLUS_FATAL_STR(logger, logEvent) LOG4CPLUS_DOWHILE_NOTHING()
  317. #define LOG4CPLUS_FATAL_FMT(logger, ...) LOG4CPLUS_DOWHILE_NOTHING()
  318. #endif
  319. //! Helper macro for LOG4CPLUS_ASSERT() macro.
  320. #define LOG4CPLUS_ASSERT_STRINGIFY(X) #X
  321. //! If the `condition` evaluates false, this macro logs it using FATAL
  322. //! log level, including the `condition`'s source text.
  323. #define LOG4CPLUS_ASSERT(logger, condition) \
  324. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  325. do { \
  326. if (LOG4CPLUS_UNLIKELY(! (condition))) \
  327. LOG4CPLUS_FATAL_STR ((logger), \
  328. LOG4CPLUS_TEXT ("failed condition: ") \
  329. LOG4CPLUS_TEXT (LOG4CPLUS_ASSERT_STRINGIFY (condition))); \
  330. } while (0) \
  331. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  332. //! If the `condition` evaluates false, this macro logs a message
  333. //! formatted from `printf` format string passed in 3rd and remaining
  334. //! arguments.
  335. #define LOG4CPLUS_ASSERT_FMT(logger, condition, ...) \
  336. LOG4CPLUS_SUPPRESS_DOWHILE_WARNING() \
  337. do { \
  338. if (! (condition)) [[unlikely]] { \
  339. LOG4CPLUS_FATAL_FMT ((logger), __VA_ARGS__); \
  340. } \
  341. } while (false) \
  342. LOG4CPLUS_RESTORE_DOWHILE_WARNING()
  343. #endif /* LOG4CPLUS_LOGGING_MACROS_HEADER_ */