Dynamic logging levels can be enabled with a define. All levels are by default ON

This commit is contained in:
KjellKod 2014-01-08 22:48:18 -07:00
parent beff32d718
commit 5486bbceca
7 changed files with 53 additions and 30 deletions

View File

@ -2,3 +2,4 @@ syntax: glob
g2log-sinks/*
3rdParty/*
g2log/build/*
*~

View File

@ -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)

View File

@ -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";

View File

@ -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;

View File

@ -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);

View File

@ -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 << "]";
}

View File

@ -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
}