mirror of
https://github.com/KjellKod/g3log.git
synced 2025-01-19 08:46:42 +01:00
Dynamic logging levels can be enabled with a define. All levels are by default ON
This commit is contained in:
parent
beff32d718
commit
5486bbceca
@ -164,7 +164,7 @@ ENDIF(MSVC)
|
||||
option (USE_GOOGLE_GLOG_PERFORMANCE "Google's glog performance test" OFF)
|
||||
|
||||
|
||||
# 4. unit test for g2log
|
||||
# 4. unit test for g2log (cmake -DUSE_G2LOG_UNIT_TEST=ON ..)
|
||||
# remember to unzip gtest at g2log/3rdParty/gtest
|
||||
option (USE_G2LOG_UNIT_TEST "g2log unit tests" OFF)
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "std2_make_unique.hpp"
|
||||
#include "g2logworker.hpp"
|
||||
#include "crashhandler.hpp"
|
||||
#include "g2loglevels.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
|
||||
namespace {
|
||||
@ -47,19 +46,12 @@ namespace {
|
||||
namespace g2 {
|
||||
// signalhandler and internal clock is only needed to install once
|
||||
// for unit testing purposes the initializeLogging might be called
|
||||
// several times... for all other practical use, it shouldn't!
|
||||
|
||||
|
||||
// several times...
|
||||
// for all other practical use, it shouldn't!
|
||||
void initializeLogging(LogWorker *bgworker) {
|
||||
std::call_once(g_initialize_flag, []() {
|
||||
installSignalHandler(); });
|
||||
std::lock_guard<std::mutex> lock(g_logging_init_mutex);
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
setLogLevel(DEBUG, true);
|
||||
setLogLevel(INFO, true);
|
||||
setLogLevel(WARNING, true);
|
||||
setLogLevel(FATAL, true);
|
||||
#endif
|
||||
CHECK(!internal::isLoggingInitialized());
|
||||
CHECK(bgworker != nullptr);
|
||||
|
||||
@ -83,7 +75,7 @@ namespace g2 {
|
||||
return g_logger_instance != nullptr;
|
||||
}
|
||||
|
||||
/** Should be used for unit testing. Used in production code is likely wrong.*/
|
||||
/** Should be used for unit testing. Used in production code is likely, but not always, wrong.*/
|
||||
LogWorker* shutDownLogging() {
|
||||
std::lock_guard<std::mutex> lock(g_logging_init_mutex);
|
||||
CHECK(isLoggingInitialized()) << "NO Logger is instantiated ... exiting";
|
||||
|
@ -17,11 +17,13 @@ namespace g2
|
||||
{
|
||||
namespace internal {
|
||||
bool wasFatal(const LEVELS& level) {
|
||||
return level.value > WARNING.value;
|
||||
return level.value >= FATAL.value;
|
||||
}
|
||||
|
||||
// By default all are OFF. At instantiation they are turned on. DEBUG, INFO, WARNING, FATAL
|
||||
std::atomic<bool> g_log_level_status[4];
|
||||
|
||||
// All levels are by default ON: i.e. for DEBUG, INFO, WARNING, FATAL
|
||||
constexpr const int size = FATAL.value+1;
|
||||
std::atomic<bool> g_log_level_status[4]{{true}, {true}, {true},{true}};
|
||||
static_assert(4 == size, "Mismatch between number of logging levels and their use");
|
||||
} // internal
|
||||
|
||||
|
||||
@ -30,7 +32,7 @@ namespace g2
|
||||
{
|
||||
int level = log_level.value;
|
||||
CHECK((level >= DEBUG.value) && (level <= FATAL.value));
|
||||
(internal::g_log_level_status[level]).store(enabled, std::memory_order_release);
|
||||
internal::g_log_level_status[level].store(enabled, std::memory_order_release);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -40,7 +42,7 @@ namespace g2
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
int level = log_level.value;
|
||||
CHECK((level >= DEBUG.value) && (level <= FATAL.value));
|
||||
bool status = (internal::g_log_level_status[level]).load(std::memory_order_acquire);
|
||||
bool status = (internal::g_log_level_status[level].load(std::memory_order_acquire));
|
||||
return status;
|
||||
#endif
|
||||
return true;
|
||||
|
@ -18,21 +18,28 @@
|
||||
struct LEVELS
|
||||
{
|
||||
const int value;
|
||||
const std::string text;
|
||||
const char* text;
|
||||
};
|
||||
const LEVELS DEBUG = {0, "DEBUG"}, INFO = {1, "INFO"}, WARNING = {2, "WARNING"}, FATAL = {3, "FATAL"};
|
||||
|
||||
constexpr const LEVELS hej{0, "1"};
|
||||
|
||||
constexpr const LEVELS DEBUG{0, "DEBUG"},
|
||||
INFO{DEBUG.value+1, "INFO"},
|
||||
WARNING{INFO.value+1, "WARNING"},
|
||||
// Insert here *any* extra logging levels that is needed
|
||||
// 1) Remember to update the FATAL initialization below
|
||||
// 2) Remember to update the initialization of "g2loglevels.cpp/g_log_level_status"
|
||||
FATAL{WARNING.value+1, "FATAL"};
|
||||
|
||||
namespace g2 {
|
||||
namespace internal {
|
||||
const LEVELS CONTRACT = {4, "CONTRACT"}, FATAL_SIGNAL{5, "FATAL_SIGNAL"};
|
||||
const LEVELS CONTRACT = {100, "CONTRACT"}, FATAL_SIGNAL{101, "FATAL_SIGNAL"};
|
||||
|
||||
bool wasFatal(const LEVELS& level);
|
||||
}
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
// Enable/Disable a log level {DEBUG,INFO,WARNING,FATAL}
|
||||
// Obviously: 'enabled_status' set to 'false' - means to disable that log level
|
||||
// WARNING: This should be used AFTER \ref g2::initializeLogging
|
||||
void setLogLevel(LEVELS level, bool enabled_status);
|
||||
#endif
|
||||
bool logLevel(LEVELS level);
|
||||
|
@ -26,16 +26,30 @@ using namespace testing_helpers;
|
||||
|
||||
|
||||
/// THIS MUST BE THE FIRST UNIT TEST TO RUN! If any unit test run before this
|
||||
/// one then it will fail. For dynamic levels all levels are turned on only AT
|
||||
/// one then it could fail. For dynamic levels all levels are turned on only AT
|
||||
/// instantiation so we do different test for dynamic logging levels
|
||||
|
||||
///
|
||||
/// TODO : (gtest issue)
|
||||
///Move out to separate unit test binary to ensure reordering of tests does not happen
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
TEST(Initialization, No_Logger_Initialized___LevelsAreONByDefault) {
|
||||
EXPECT_FALSE(g2::internal::isLoggingInitialized());
|
||||
EXPECT_TRUE(g2::logLevel(DEBUG));
|
||||
EXPECT_TRUE(g2::logLevel(INFO));
|
||||
EXPECT_TRUE(g2::logLevel(WARNING));
|
||||
EXPECT_TRUE(g2::logLevel(FATAL));
|
||||
EXPECT_EQ(DEBUG.value, 0);
|
||||
EXPECT_EQ(INFO.value, 1);
|
||||
EXPECT_EQ(WARNING.value, 2);
|
||||
EXPECT_EQ(FATAL.value, 3);
|
||||
}
|
||||
|
||||
TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKish) {
|
||||
EXPECT_FALSE(g2::internal::isLoggingInitialized());
|
||||
EXPECT_FALSE(g2::logLevel(INFO));
|
||||
EXPECT_FALSE(g2::logLevel(FATAL));
|
||||
EXPECT_FALSE(g2::logLevel(DEBUG));
|
||||
EXPECT_FALSE(g2::logLevel(WARNING));
|
||||
EXPECT_TRUE(g2::logLevel(INFO));
|
||||
EXPECT_TRUE(g2::logLevel(FATAL));
|
||||
EXPECT_TRUE(g2::logLevel(DEBUG));
|
||||
EXPECT_TRUE(g2::logLevel(WARNING));
|
||||
std::string err_msg1 = "Hey. I am not instantiated but I still should not crash. (I am g2logger)";
|
||||
std::string err_msg2_ignored = "This uninitialized message should be ignored";
|
||||
try {
|
||||
@ -51,7 +65,7 @@ TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKi
|
||||
std::string good_msg1 = "This message could have pulled in the uninitialized_call message";
|
||||
LOG(INFO) << good_msg1;
|
||||
auto content = logger.resetAndRetrieveContent(); // this synchronizes with the LOG(INFO) call if debug level would be ON.
|
||||
ASSERT_FALSE(verifyContent(content, err_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, err_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg2_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
}
|
||||
|
@ -123,6 +123,13 @@ namespace testing_helpers {
|
||||
auto filename = _handle->call(&FileSink::fileName);
|
||||
if (!filename.valid()) ADD_FAILURE();
|
||||
_log_file = filename.get();
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
g2::setLogLevel(INFO, true);
|
||||
g2::setLogLevel(DEBUG, true);
|
||||
g2::setLogLevel(WARNING, true);
|
||||
g2::setLogLevel(FATAL, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user