Skip to content

Commit ae8bb71

Browse files
committed
Merge pull request opencv#10340 from alalek:log_level_option
2 parents eecb64a + b450811 commit ae8bb71

File tree

3 files changed

+128
-19
lines changed

3 files changed

+128
-19
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
5+
#ifndef OPENCV_LOGGER_DEFINES_HPP
6+
#define OPENCV_LOGGER_DEFINES_HPP
7+
8+
//! @addtogroup core_logging
9+
//! @{
10+
11+
// Supported logging levels and their semantic
12+
#define CV_LOG_LEVEL_SILENT 0 //!< for using in setLogLevel() call
13+
#define CV_LOG_LEVEL_FATAL 1 //!< Fatal (critical) error (unrecoverable internal error)
14+
#define CV_LOG_LEVEL_ERROR 2 //!< Error message
15+
#define CV_LOG_LEVEL_WARN 3 //!< Warning message
16+
#define CV_LOG_LEVEL_INFO 4 //!< Info message
17+
#define CV_LOG_LEVEL_DEBUG 5 //!< Debug message. Disabled in the "Release" build.
18+
#define CV_LOG_LEVEL_VERBOSE 6 //!< Verbose (trace) messages. Requires verbosity level. Disabled in the "Release" build.
19+
20+
//! @}
21+
22+
#endif // OPENCV_LOGGER_DEFINES_HPP

modules/core/include/opencv2/core/utils/logger.hpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// It is subject to the license terms in the LICENSE file found in the top-level directory
33
// of this distribution and at http://opencv.org/license.html.
44

5-
#ifndef OPENCV_LOGGING_HPP
6-
#define OPENCV_LOGGING_HPP
5+
#ifndef OPENCV_LOGGER_HPP
6+
#define OPENCV_LOGGER_HPP
77

88
#include <iostream>
99
#include <sstream>
1010
#include <limits.h> // INT_MAX
1111

12-
// TODO This file contains just interface part with implementation stubs.
12+
#include "logger.defines.hpp"
1313

1414
//! @addtogroup core_logging
1515
// This section describes OpenCV logging utilities.
@@ -20,15 +20,6 @@ namespace cv {
2020
namespace utils {
2121
namespace logging {
2222

23-
// Supported logging levels and their semantic
24-
#define CV_LOG_LEVEL_SILENT 0 //!< for using in setLogVevel() call
25-
#define CV_LOG_LEVEL_FATAL 1 //!< Fatal (critical) error (unrecoverable internal error)
26-
#define CV_LOG_LEVEL_ERROR 2 //!< Error message
27-
#define CV_LOG_LEVEL_WARN 3 //!< Warning message
28-
#define CV_LOG_LEVEL_INFO 4 //!< Info message
29-
#define CV_LOG_LEVEL_DEBUG 5 //!< Debug message. Disabled in the "Release" build.
30-
#define CV_LOG_LEVEL_VERBOSE 6 //!< Verbose (trace) messages. Requires verbosity level. Disabled in the "Release" build.
31-
3223
//! Supported logging levels and their semantic
3324
enum LogLevel {
3425
LOG_LEVEL_SILENT = 0, //!< for using in setLogVevel() call
@@ -43,6 +34,17 @@ enum LogLevel {
4334
#endif
4435
};
4536

37+
/** Set global logging level
38+
@return previous logging level
39+
*/
40+
CV_EXPORTS LogLevel setLogLevel(LogLevel logLevel);
41+
/** Get global logging level */
42+
CV_EXPORTS LogLevel getLogLevel();
43+
44+
namespace internal {
45+
/** Write log message */
46+
CV_EXPORTS void writeLogMessage(LogLevel logLevel, const char* message);
47+
} // namespace
4648

4749
/**
4850
* \def CV_LOG_STRIP_LEVEL
@@ -58,28 +60,28 @@ enum LogLevel {
5860
#endif
5961

6062

61-
#define CV_LOG_FATAL(tag, ...) for(;;) { std::stringstream ss; ss << "[FATAL:" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cerr << ss.str() << std::flush; break; }
62-
#define CV_LOG_ERROR(tag, ...) for(;;) { std::stringstream ss; ss << "[ERROR:" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cerr << ss.str() << std::flush; break; }
63-
#define CV_LOG_WARNING(tag, ...) for(;;) { std::stringstream ss; ss << "[ WARN:" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cout << ss.str() << std::flush; break; }
63+
#define CV_LOG_FATAL(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_FATAL) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_FATAL, ss.str().c_str()); break; }
64+
#define CV_LOG_ERROR(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_ERROR) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_ERROR, ss.str().c_str()); break; }
65+
#define CV_LOG_WARNING(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_WARNING) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_WARNING, ss.str().c_str()); break; }
6466
#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_INFO
6567
#define CV_LOG_INFO(tag, ...)
6668
#else
67-
#define CV_LOG_INFO(tag, ...) for(;;) { std::stringstream ss; ss << "[ INFO:" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cout << ss.str(); break; }
69+
#define CV_LOG_INFO(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_INFO) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_INFO, ss.str().c_str()); break; }
6870
#endif
6971
#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_DEBUG
7072
#define CV_LOG_DEBUG(tag, ...)
7173
#else
72-
#define CV_LOG_DEBUG(tag, ...) for(;;) { std::stringstream ss; ss << "[DEBUG:" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cout << ss.str(); break; }
74+
#define CV_LOG_DEBUG(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_DEBUG) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_DEBUG, ss.str().c_str()); break; }
7375
#endif
7476
#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_VERBOSE
7577
#define CV_LOG_VERBOSE(tag, v, ...)
7678
#else
77-
#define CV_LOG_VERBOSE(tag, v, ...) for(;;) { std::stringstream ss; ss << "[VERB" << v << ":" << cv::utils::getThreadID() << "] " << __VA_ARGS__ << std::endl; std::cout << ss.str(); break; }
79+
#define CV_LOG_VERBOSE(tag, v, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_VERBOSE) break; std::stringstream ss; ss << "[VERB" << v << ":" << cv::utils::getThreadID() << "] " << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_VERBOSE, ss.str().c_str()); break; }
7880
#endif
7981

8082

8183
}}} // namespace
8284

8385
//! @}
8486

85-
#endif // OPENCV_LOGGING_HPP
87+
#endif // OPENCV_LOGGER_HPP

modules/core/src/logger.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
5+
#include <precomp.hpp>
6+
7+
#include <opencv2/core/utils/configuration.private.hpp>
8+
#include <opencv2/core/utils/logger.hpp>
9+
10+
#include <sstream>
11+
#include <iostream>
12+
#include <fstream>
13+
14+
namespace cv {
15+
namespace utils {
16+
namespace logging {
17+
18+
static LogLevel parseLogLevelConfiguration()
19+
{
20+
static cv::String param_log_level = utils::getConfigurationParameterString("OPENCV_LOG_LEVEL", "INFO");
21+
if (param_log_level == "DISABLED" || param_log_level == "disabled" ||
22+
param_log_level == "0" || param_log_level == "OFF" || param_log_level == "off")
23+
return LOG_LEVEL_SILENT;
24+
if (param_log_level == "FATAL" || param_log_level == "fatal")
25+
return LOG_LEVEL_FATAL;
26+
if (param_log_level == "ERROR" || param_log_level == "error")
27+
return LOG_LEVEL_ERROR;
28+
if (param_log_level == "WARNING" || param_log_level == "warning" ||
29+
param_log_level == "WARNINGS" || param_log_level == "warnings" ||
30+
param_log_level == "WARN" || param_log_level == "warn")
31+
return LOG_LEVEL_WARNING;
32+
if (param_log_level == "INFO" || param_log_level == "info")
33+
return LOG_LEVEL_INFO;
34+
if (param_log_level == "DEBUG" || param_log_level == "debug")
35+
return LOG_LEVEL_DEBUG;
36+
if (param_log_level == "VERBOSE" || param_log_level == "verbose")
37+
return LOG_LEVEL_VERBOSE;
38+
std::cerr << "ERROR: Unexpected logging level value: " << param_log_level << std::endl;
39+
return LOG_LEVEL_INFO;
40+
}
41+
42+
static LogLevel& getLogLevelVariable()
43+
{
44+
static LogLevel g_logLevel = parseLogLevelConfiguration();
45+
return g_logLevel;
46+
}
47+
48+
LogLevel setLogLevel(LogLevel logLevel)
49+
{
50+
LogLevel old = getLogLevelVariable();
51+
getLogLevelVariable() = logLevel;
52+
return old;
53+
}
54+
55+
LogLevel getLogLevel()
56+
{
57+
return getLogLevelVariable();
58+
}
59+
60+
namespace internal {
61+
62+
void writeLogMessage(LogLevel logLevel, const char* message)
63+
{
64+
const int threadID = cv::utils::getThreadID();
65+
std::ostream* out = (logLevel <= LOG_LEVEL_WARNING) ? &std::cerr : &std::cout;
66+
std::stringstream ss;
67+
switch (logLevel)
68+
{
69+
case LOG_LEVEL_FATAL: ss << "[FATAL:" << threadID << "] " << message << std::endl; break;
70+
case LOG_LEVEL_ERROR: ss << "[ERROR:" << threadID << "] " << message << std::endl; break;
71+
case LOG_LEVEL_WARNING: ss << "[ WARN:" << threadID << "] " << message << std::endl; break;
72+
case LOG_LEVEL_INFO: ss << "[ INFO:" << threadID << "] " << message << std::endl; break;
73+
case LOG_LEVEL_DEBUG: ss << "[DEBUG:" << threadID << "] " << message << std::endl; break;
74+
case LOG_LEVEL_VERBOSE: ss << message << std::endl; break;
75+
default:
76+
return;
77+
}
78+
(*out) << ss.str();
79+
if (logLevel <= LOG_LEVEL_WARNING)
80+
(*out) << std::flush;
81+
}
82+
83+
} // namespace
84+
85+
}}} // namespace

0 commit comments

Comments
 (0)