logger.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #ifndef OPENCV_LOGGER_HPP
  5. #define OPENCV_LOGGER_HPP
  6. #include <iostream>
  7. #include <sstream>
  8. #include <limits.h> // INT_MAX
  9. #include "logger.defines.hpp"
  10. #include "logtag.hpp"
  11. //! @addtogroup core_logging
  12. // This section describes OpenCV logging utilities.
  13. //
  14. //! @{
  15. namespace cv {
  16. namespace utils {
  17. namespace logging {
  18. /** Set global logging level
  19. @return previous logging level
  20. */
  21. CV_EXPORTS LogLevel setLogLevel(LogLevel logLevel);
  22. /** Get global logging level */
  23. CV_EXPORTS LogLevel getLogLevel();
  24. CV_EXPORTS void registerLogTag(cv::utils::logging::LogTag* plogtag);
  25. CV_EXPORTS void setLogTagLevel(const char* tag, cv::utils::logging::LogLevel level);
  26. CV_EXPORTS cv::utils::logging::LogLevel getLogTagLevel(const char* tag);
  27. namespace internal {
  28. /** Get global log tag */
  29. CV_EXPORTS cv::utils::logging::LogTag* getGlobalLogTag();
  30. /** Write log message */
  31. CV_EXPORTS void writeLogMessage(LogLevel logLevel, const char* message);
  32. /** Write log message */
  33. CV_EXPORTS void writeLogMessageEx(LogLevel logLevel, const char* tag, const char* file, int line, const char* func, const char* message);
  34. } // namespace
  35. struct LogTagAuto
  36. : public LogTag
  37. {
  38. inline LogTagAuto(const char* _name, LogLevel _level)
  39. : LogTag(_name, _level)
  40. {
  41. registerLogTag(this);
  42. }
  43. };
  44. /**
  45. * \def CV_LOG_STRIP_LEVEL
  46. *
  47. * Define CV_LOG_STRIP_LEVEL=CV_LOG_LEVEL_[DEBUG|INFO|WARN|ERROR|FATAL|SILENT] to compile out anything at that and before that logging level
  48. */
  49. #ifndef CV_LOG_STRIP_LEVEL
  50. # if defined NDEBUG
  51. # define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG
  52. # else
  53. # define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE
  54. # endif
  55. #endif
  56. #define CV_LOGTAG_PTR_CAST(expr) static_cast<const cv::utils::logging::LogTag*>(expr)
  57. // CV_LOGTAG_EXPAND_NAME is intended to be re-defined (undef and then define again)
  58. // to allows logging users to use a shorter name argument when calling
  59. // CV_LOG_WITH_TAG or its related macros such as CV_LOG_INFO.
  60. //
  61. // This macro is intended to modify the tag argument as a string (token), via
  62. // preprocessor token pasting or metaprogramming techniques. A typical usage
  63. // is to apply a prefix, such as
  64. // ...... #define CV_LOGTAG_EXPAND_NAME(tag) cv_logtag_##tag
  65. //
  66. // It is permitted to re-define to a hard-coded expression, ignoring the tag.
  67. // This would work identically like the CV_LOGTAG_FALLBACK macro.
  68. //
  69. // Important: When the logging macro is called with tag being NULL, a user-defined
  70. // CV_LOGTAG_EXPAND_NAME may expand it into cv_logtag_0, cv_logtag_NULL, or
  71. // cv_logtag_nullptr. Use with care. Also be mindful of C++ symbol redefinitions.
  72. //
  73. // If there is significant amount of logging code with tag being NULL, it is
  74. // recommended to use (re-define) CV_LOGTAG_FALLBACK to inject locally a default
  75. // tag at the beginning of a compilation unit, to minimize lines of code changes.
  76. //
  77. #define CV_LOGTAG_EXPAND_NAME(tag) tag
  78. // CV_LOGTAG_FALLBACK is intended to be re-defined (undef and then define again)
  79. // by any other compilation units to provide a log tag when the logging statement
  80. // does not specify one. The macro needs to expand into a C++ expression that can
  81. // be static_cast into (cv::utils::logging::LogTag*). Null (nullptr) is permitted.
  82. #define CV_LOGTAG_FALLBACK nullptr
  83. // CV_LOGTAG_GLOBAL is the tag used when a log tag is not specified in the logging
  84. // statement nor the compilation unit. The macro needs to expand into a C++
  85. // expression that can be static_cast into (cv::utils::logging::LogTag*). Must be
  86. // non-null. Do not re-define.
  87. #define CV_LOGTAG_GLOBAL cv::utils::logging::internal::getGlobalLogTag()
  88. #define CV_LOG_WITH_TAG(tag, msgLevel, ...) \
  89. for(;;) { \
  90. const auto cv_temp_msglevel = (cv::utils::logging::LogLevel)(msgLevel); \
  91. if (cv_temp_msglevel >= (CV_LOG_STRIP_LEVEL)) break; \
  92. auto cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_EXPAND_NAME(tag)); \
  93. if (!cv_temp_logtagptr) cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_FALLBACK); \
  94. if (!cv_temp_logtagptr) cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_GLOBAL); \
  95. if (cv_temp_logtagptr && (cv_temp_msglevel > cv_temp_logtagptr->level)) break; \
  96. std::stringstream cv_temp_logstream; \
  97. cv_temp_logstream << __VA_ARGS__; \
  98. cv::utils::logging::internal::writeLogMessageEx( \
  99. cv_temp_msglevel, \
  100. (cv_temp_logtagptr ? cv_temp_logtagptr->name : nullptr), \
  101. __FILE__, \
  102. __LINE__, \
  103. CV_Func, \
  104. cv_temp_logstream.str().c_str()); \
  105. break; \
  106. }
  107. #define CV_LOG_FATAL(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_FATAL, __VA_ARGS__)
  108. #define CV_LOG_ERROR(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_ERROR, __VA_ARGS__)
  109. #define CV_LOG_WARNING(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_WARNING, __VA_ARGS__)
  110. #define CV_LOG_INFO(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_INFO, __VA_ARGS__)
  111. #define CV_LOG_DEBUG(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_DEBUG, __VA_ARGS__)
  112. #define CV_LOG_VERBOSE(tag, v, ...) CV_LOG_WITH_TAG(tag, (cv::utils::logging::LOG_LEVEL_VERBOSE + (int)(v)), __VA_ARGS__)
  113. #if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_INFO
  114. # undef CV_LOG_INFO
  115. # define CV_LOG_INFO(tag, ...)
  116. #endif
  117. #if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_DEBUG
  118. # undef CV_LOG_DEBUG
  119. # define CV_LOG_DEBUG(tag, ...)
  120. #endif
  121. #if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_VERBOSE
  122. # undef CV_LOG_VERBOSE
  123. # define CV_LOG_VERBOSE(tag, v, ...)
  124. #endif
  125. }}} // namespace
  126. //! @}
  127. #endif // OPENCV_LOGGER_HPP