mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-13 10:42:56 +01:00
Merge pull request #37 from KjellKod/filter
preparation for g3sinks: Filter
This commit is contained in:
commit
bc4459d779
@ -13,16 +13,17 @@
|
||||
// the DEBUG logging level for G3log. In that case they can instead use the define
|
||||
// "CHANGE_G3LOG_DEBUG_TO_DBUG" and G3log's logging level DEBUG is changed to be DBUG
|
||||
#if (defined(CHANGE_G3LOG_DEBUG_TO_DBUG))
|
||||
#if (defined(DBUG))
|
||||
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
|
||||
#endif
|
||||
#if (defined(DBUG))
|
||||
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
|
||||
#endif
|
||||
#else
|
||||
#if (defined(DEBUG))
|
||||
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
|
||||
#endif
|
||||
#if (defined(DEBUG))
|
||||
#error "DEBUG is already defined elsewhere which clashes with G3Log's log level DEBUG"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
// Levels for logging, made so that it would be easy to change, remove, add levels -- KjellKod
|
||||
@ -30,15 +31,32 @@ struct LEVELS {
|
||||
// force internal copy of the const char*. This is a simple safeguard for when g3log is used in a
|
||||
// "dynamic, runtime loading of shared libraries"
|
||||
|
||||
LEVELS(const LEVELS &other): value(other.value), text(other.text.c_str()) {}
|
||||
LEVELS(int id, const char *idtext) : value(id), text(idtext) {}
|
||||
LEVELS(const LEVELS& other): value(other.value), text(other.text.c_str()) {}
|
||||
LEVELS(int id, const char* idtext) : value(id), text(idtext) {}
|
||||
|
||||
friend bool operator==(const LEVELS &lhs, const LEVELS &rhs) {
|
||||
return (lhs.value == rhs.value && lhs.text == rhs.text);
|
||||
bool operator==(const LEVELS& rhs) const {
|
||||
return (value == rhs.value && text == rhs.text);
|
||||
}
|
||||
|
||||
const int value;
|
||||
const std::string text;
|
||||
bool operator!=(const LEVELS& rhs) const {
|
||||
return (value != rhs.value || text != rhs.text);
|
||||
}
|
||||
|
||||
friend void swap(LEVELS& first, LEVELS& second) {
|
||||
using std::swap;
|
||||
swap(first.value, second.value);
|
||||
swap(first.text, second.text);
|
||||
}
|
||||
|
||||
|
||||
LEVELS& operator=(LEVELS other) {
|
||||
swap(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
int value;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
|
||||
@ -85,7 +103,7 @@ namespace g3 {
|
||||
|
||||
/// helper function to tell the logger if a log message was fatal. If it is it will force
|
||||
/// a shutdown after all log entries are saved to the sinks
|
||||
bool wasFatal(const LEVELS &level);
|
||||
bool wasFatal(const LEVELS& level);
|
||||
}
|
||||
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
@ -95,9 +113,9 @@ namespace g3 {
|
||||
void setLogLevel(LEVELS level, bool enabled_status);
|
||||
std::string printLevels();
|
||||
void reset();
|
||||
|
||||
|
||||
} // only_change_at_initialization
|
||||
#endif
|
||||
bool logLevel(LEVELS level);
|
||||
bool logLevel(LEVELS level);
|
||||
} // g3
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
|
||||
* with no warranties. This code is yours to share, use and modify with no
|
||||
* strings attached and no restrictions or obligations.
|
||||
*
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
@ -47,7 +47,7 @@ namespace g3 {
|
||||
|
||||
/// use a different format string to get a different look on the time.
|
||||
// default look is Y/M/D H:M:S
|
||||
std::string timestamp(const std::string &time_format = {internal::date_formatted + " " + internal::time_formatted}) const;
|
||||
std::string timestamp(const std::string& time_format = {internal::date_formatted + " " + internal::time_formatted}) const;
|
||||
std::string microseconds() const {
|
||||
return std::to_string(_microseconds);
|
||||
}
|
||||
@ -55,7 +55,7 @@ namespace g3 {
|
||||
std::string message() const {
|
||||
return _message;
|
||||
}
|
||||
std::string &write() const {
|
||||
std::string& write() const {
|
||||
return _message;
|
||||
}
|
||||
|
||||
@ -74,11 +74,14 @@ namespace g3 {
|
||||
}
|
||||
|
||||
|
||||
LogMessage(const std::string &file, const int line, const std::string &function, const LEVELS &level);
|
||||
explicit LogMessage(const std::string &fatalOsSignalCrashMessage);
|
||||
LogMessage& operator=(LogMessage other);
|
||||
|
||||
LogMessage(const LogMessage &);
|
||||
LogMessage(LogMessage &&other);
|
||||
|
||||
LogMessage(const std::string& file, const int line, const std::string& function, const LEVELS& level);
|
||||
|
||||
explicit LogMessage(const std::string& fatalOsSignalCrashMessage);
|
||||
LogMessage(const LogMessage& other);
|
||||
LogMessage(LogMessage&& other);
|
||||
virtual ~LogMessage() {}
|
||||
|
||||
//
|
||||
@ -94,6 +97,23 @@ namespace g3 {
|
||||
LEVELS _level;
|
||||
std::string _expression; // only with content for CHECK(...) calls
|
||||
mutable std::string _message;
|
||||
|
||||
|
||||
|
||||
friend void swap(LogMessage& first, LogMessage& second) {
|
||||
// enable ADL (not necessary in our case, but good practice)
|
||||
using std::swap;
|
||||
swap(first._timestamp, second._timestamp);
|
||||
swap(first._call_thread_id, second._call_thread_id);
|
||||
swap(first._microseconds, second._microseconds);
|
||||
swap(first._file, second._file);
|
||||
swap(first._line, second._line);
|
||||
swap(first._function, second._function);
|
||||
swap(first._level, second._level);
|
||||
swap(first._expression, second._expression);
|
||||
swap(first._message, second._message);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -103,8 +123,8 @@ namespace g3 {
|
||||
* A thread that causes a FatalMessage will sleep forever until the
|
||||
* application has exited (after message flush) */
|
||||
struct FatalMessage : public LogMessage {
|
||||
FatalMessage(const LogMessage &details, g3::SignalType signal_id);
|
||||
FatalMessage(const FatalMessage &);
|
||||
FatalMessage(const LogMessage& details, g3::SignalType signal_id);
|
||||
FatalMessage(const FatalMessage&);
|
||||
virtual ~FatalMessage() {}
|
||||
|
||||
LogMessage copyToLogMessage() const;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
|
||||
* with no warranties. This code is yours to share, use and modify with no
|
||||
* strings attached and no restrictions or obligations.
|
||||
*
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include "g3log/crashhandler.hpp"
|
||||
#include "g3log/time.hpp"
|
||||
#include "g3log/std2_make_unique.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
@ -25,7 +25,7 @@ namespace {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
|
||||
}
|
||||
|
||||
std::string splitFileName(const std::string &str) {
|
||||
std::string splitFileName(const std::string& str) {
|
||||
size_t found;
|
||||
found = str.find_last_of("(/\\");
|
||||
return str.substr(found + 1);
|
||||
@ -38,7 +38,7 @@ namespace g3 {
|
||||
|
||||
|
||||
// helper for setting the normal log details in an entry
|
||||
std::string LogDetailsToString(const LogMessage &msg) {
|
||||
std::string LogDetailsToString(const LogMessage& msg) {
|
||||
std::string out;
|
||||
out.append("\n" + msg.timestamp() + " " + msg.microseconds() + "\t"
|
||||
+ msg.level() + " [" + msg.file() + " L: " + msg.line() + "]\t");
|
||||
@ -47,14 +47,14 @@ namespace g3 {
|
||||
|
||||
|
||||
// helper for normal
|
||||
std::string normalToString(const LogMessage &msg) {
|
||||
std::string normalToString(const LogMessage& msg) {
|
||||
auto out = LogDetailsToString(msg);
|
||||
out.append('"' + msg.message() + '"');
|
||||
return out;
|
||||
}
|
||||
|
||||
// helper for fatal signal
|
||||
std::string fatalSignalToString(const LogMessage &msg) {
|
||||
std::string fatalSignalToString(const LogMessage& msg) {
|
||||
std::string out; // clear any previous text and formatting
|
||||
out.append("\n" + msg.timestamp() + "." + msg.microseconds()
|
||||
+ "\n\n***** FATAL SIGNAL RECEIVED ******* \n"
|
||||
@ -64,7 +64,7 @@ namespace g3 {
|
||||
|
||||
|
||||
// helper for fatal exception (windows only)
|
||||
std::string fatalExceptionToString(const LogMessage &msg) {
|
||||
std::string fatalExceptionToString(const LogMessage& msg) {
|
||||
std::string out; // clear any previous text and formatting
|
||||
out.append("\n" + msg.timestamp() + "." + msg.microseconds()
|
||||
+ "\n\n***** FATAL EXCEPTION RECEIVED ******* \n"
|
||||
@ -74,7 +74,7 @@ namespace g3 {
|
||||
|
||||
|
||||
// helper for fatal LOG
|
||||
std::string fatalLogToString(const LogMessage &msg) {
|
||||
std::string fatalLogToString(const LogMessage& msg) {
|
||||
auto out = LogDetailsToString(msg);
|
||||
static const std::string fatalExitReason = {"EXIT trigger caused by LOG(FATAL) entry: "};
|
||||
out.append("\n\t*******\t " + fatalExitReason + "\n\t" + '"' + msg.message() + '"');
|
||||
@ -82,7 +82,7 @@ namespace g3 {
|
||||
}
|
||||
|
||||
// helper for fatal CHECK
|
||||
std::string fatalCheckToString(const LogMessage &msg) {
|
||||
std::string fatalCheckToString(const LogMessage& msg) {
|
||||
auto out = LogDetailsToString(msg);
|
||||
static const std::string contractExitReason = {"EXIT trigger caused by broken Contract:"};
|
||||
out.append("\n\t*******\t " + contractExitReason + " CHECK(" + msg.expression() + ")\n\t"
|
||||
@ -123,15 +123,21 @@ namespace g3 {
|
||||
|
||||
|
||||
|
||||
std::string LogMessage::timestamp(const std::string &time_look) const {
|
||||
std::string LogMessage::timestamp(const std::string& time_look) const {
|
||||
return localtime_formatted(_timestamp, time_look);
|
||||
}
|
||||
|
||||
|
||||
// By copy, not by reference. See this explanation for details:
|
||||
// http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
|
||||
LogMessage& LogMessage::operator=(LogMessage other) {
|
||||
swap(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
LogMessage::LogMessage(const std::string &file, const int line,
|
||||
const std::string &function, const LEVELS &level)
|
||||
LogMessage::LogMessage(const std::string& file, const int line,
|
||||
const std::string& function, const LEVELS& level)
|
||||
: _timestamp(g3::systemtime_now())
|
||||
, _call_thread_id(std::this_thread::get_id())
|
||||
, _microseconds(microsecondsCounter())
|
||||
@ -142,12 +148,12 @@ namespace g3 {
|
||||
{}
|
||||
|
||||
|
||||
LogMessage::LogMessage(const std::string &fatalOsSignalCrashMessage)
|
||||
: LogMessage({""}, 0, {""}, internal::FATAL_SIGNAL) {
|
||||
LogMessage::LogMessage(const std::string& fatalOsSignalCrashMessage)
|
||||
: LogMessage( {""}, 0, {""}, internal::FATAL_SIGNAL) {
|
||||
_message.append(fatalOsSignalCrashMessage);
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const LogMessage &other)
|
||||
LogMessage::LogMessage(const LogMessage& other)
|
||||
: _timestamp(other._timestamp)
|
||||
, _call_thread_id(other._call_thread_id)
|
||||
, _microseconds(other._microseconds)
|
||||
@ -156,11 +162,9 @@ namespace g3 {
|
||||
, _function(other._function)
|
||||
, _level(other._level)
|
||||
, _expression(other._expression)
|
||||
, _message(other._message)
|
||||
{
|
||||
, _message(other._message) {
|
||||
}
|
||||
|
||||
|
||||
LogMessage::LogMessage(LogMessage &&other)
|
||||
: _timestamp(other._timestamp)
|
||||
, _call_thread_id(other._call_thread_id)
|
||||
@ -174,18 +178,19 @@ namespace g3 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string LogMessage::threadID() const {
|
||||
std::ostringstream oss;
|
||||
oss << _call_thread_id;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
FatalMessage::FatalMessage(const LogMessage &details, g3::SignalType signal_id)
|
||||
FatalMessage::FatalMessage(const LogMessage& details, g3::SignalType signal_id)
|
||||
: LogMessage(details), _signal_id(signal_id) { }
|
||||
|
||||
|
||||
|
||||
FatalMessage::FatalMessage(const FatalMessage &other)
|
||||
FatalMessage::FatalMessage(const FatalMessage& other)
|
||||
: LogMessage(other), _signal_id(other._signal_id) {}
|
||||
|
||||
|
||||
|
@ -13,32 +13,32 @@
|
||||
#include "g3log/stacktrace_windows.hpp"
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
|
||||
TEST(CrashHandler_Windows, ExceptionType) {
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(123), "UNKNOWN EXCEPTION:123");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(1), "UNKNOWN EXCEPTION:1");
|
||||
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_ACCESS_VIOLATION), "EXCEPTION_ACCESS_VIOLATION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), "EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_BREAKPOINT),"EXCEPTION_BREAKPOINT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_DATATYPE_MISALIGNMENT),"EXCEPTION_DATATYPE_MISALIGNMENT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_DENORMAL_OPERAND),"EXCEPTION_FLT_DENORMAL_OPERAND");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_DIVIDE_BY_ZERO),"EXCEPTION_FLT_DIVIDE_BY_ZERO");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INEXACT_RESULT),"EXCEPTION_FLT_INEXACT_RESULT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INEXACT_RESULT),"EXCEPTION_FLT_INEXACT_RESULT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INVALID_OPERATION),"EXCEPTION_FLT_INVALID_OPERATION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_OVERFLOW),"EXCEPTION_FLT_OVERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_STACK_CHECK),"EXCEPTION_FLT_STACK_CHECK");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_UNDERFLOW),"EXCEPTION_FLT_UNDERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_ILLEGAL_INSTRUCTION),"EXCEPTION_ILLEGAL_INSTRUCTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_IN_PAGE_ERROR),"EXCEPTION_IN_PAGE_ERROR");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INT_DIVIDE_BY_ZERO),"EXCEPTION_INT_DIVIDE_BY_ZERO");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INT_OVERFLOW),"EXCEPTION_INT_OVERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INVALID_DISPOSITION),"EXCEPTION_INVALID_DISPOSITION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_NONCONTINUABLE_EXCEPTION),"EXCEPTION_NONCONTINUABLE_EXCEPTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_PRIV_INSTRUCTION),"EXCEPTION_PRIV_INSTRUCTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_SINGLE_STEP),"EXCEPTION_SINGLE_STEP");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_STACK_OVERFLOW),"EXCEPTION_STACK_OVERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_BREAKPOINT), "EXCEPTION_BREAKPOINT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_DATATYPE_MISALIGNMENT), "EXCEPTION_DATATYPE_MISALIGNMENT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_DENORMAL_OPERAND), "EXCEPTION_FLT_DENORMAL_OPERAND");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_DIVIDE_BY_ZERO), "EXCEPTION_FLT_DIVIDE_BY_ZERO");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INEXACT_RESULT), "EXCEPTION_FLT_INEXACT_RESULT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INEXACT_RESULT), "EXCEPTION_FLT_INEXACT_RESULT");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_INVALID_OPERATION), "EXCEPTION_FLT_INVALID_OPERATION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_OVERFLOW), "EXCEPTION_FLT_OVERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_STACK_CHECK), "EXCEPTION_FLT_STACK_CHECK");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_FLT_UNDERFLOW), "EXCEPTION_FLT_UNDERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_ILLEGAL_INSTRUCTION), "EXCEPTION_ILLEGAL_INSTRUCTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_IN_PAGE_ERROR), "EXCEPTION_IN_PAGE_ERROR");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INT_DIVIDE_BY_ZERO), "EXCEPTION_INT_DIVIDE_BY_ZERO");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INT_OVERFLOW), "EXCEPTION_INT_OVERFLOW");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_INVALID_DISPOSITION), "EXCEPTION_INVALID_DISPOSITION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_NONCONTINUABLE_EXCEPTION), "EXCEPTION_NONCONTINUABLE_EXCEPTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_PRIV_INSTRUCTION), "EXCEPTION_PRIV_INSTRUCTION");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_SINGLE_STEP), "EXCEPTION_SINGLE_STEP");
|
||||
EXPECT_EQ(stacktrace::exceptionIdToText(EXCEPTION_STACK_OVERFLOW), "EXCEPTION_STACK_OVERFLOW");
|
||||
}
|
||||
|
||||
#endif // defined WIN32
|
@ -2,7 +2,7 @@
|
||||
* 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
|
||||
* with no warranties. This code is yours to share, use and modify with no
|
||||
* strings attached and no restrictions or obligations.
|
||||
*
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
@ -18,19 +18,21 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
namespace {
|
||||
const std::string log_directory = "./";
|
||||
const std::string t_info = "test INFO ";
|
||||
const std::string t_info2 = "test INFO 123";
|
||||
const std::string t_debug = "test DEBUG ";
|
||||
const std::string t_debug3 = "test DEBUG 1.123456";
|
||||
const std::string t_warning = "test WARNING ";
|
||||
const std::string t_warning3 = "test WARNING yello";
|
||||
#include <algorithm>
|
||||
|
||||
std::atomic<size_t> g_fatal_counter = {0};
|
||||
void fatalCounter() {
|
||||
++g_fatal_counter;
|
||||
}
|
||||
namespace {
|
||||
const std::string log_directory = "./";
|
||||
const std::string t_info = "test INFO ";
|
||||
const std::string t_info2 = "test INFO 123";
|
||||
const std::string t_debug = "test DEBUG ";
|
||||
const std::string t_debug3 = "test DEBUG 1.123456";
|
||||
const std::string t_warning = "test WARNING ";
|
||||
const std::string t_warning3 = "test WARNING yello";
|
||||
|
||||
std::atomic<size_t> g_fatal_counter = {0};
|
||||
void fatalCounter() {
|
||||
++g_fatal_counter;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -38,12 +40,12 @@ void fatalCounter() {
|
||||
using namespace testing_helpers;
|
||||
|
||||
|
||||
/// THIS MUST BE THE FIRST UNIT TEST TO RUN! If any unit test run before this
|
||||
/// THIS MUST BE THE FIRST UNIT TEST TO RUN! If any unit test run before this
|
||||
/// 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
|
||||
///Move out to separate unit test binary to ensure reordering of tests does not happen
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
TEST(Initialization, No_Logger_Initialized___LevelsAreONByDefault) {
|
||||
EXPECT_FALSE(g3::internal::isLoggingInitialized());
|
||||
@ -81,7 +83,7 @@ TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKi
|
||||
auto content = logger.resetAndRetrieveContent(); // this synchronizes with the LOG(INFO) call if debug level would be ON.
|
||||
ASSERT_TRUE(verifyContent(content, err_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg3_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
}
|
||||
#else
|
||||
TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKish) {
|
||||
@ -109,9 +111,44 @@ TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKi
|
||||
ASSERT_TRUE(verifyContent(content, err_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg3_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
}
|
||||
}
|
||||
#endif // #ifdef G3_DYNAMIC_LOGGING
|
||||
|
||||
TEST(Basics, Levels_StdFind) {
|
||||
std::vector<LEVELS> levels = {INFO, WARNING, FATAL};
|
||||
auto info = INFO;
|
||||
auto warning = WARNING;
|
||||
auto debug = DEBUG;
|
||||
auto found_info = std::find(levels.begin(), levels.end(), info);
|
||||
EXPECT_TRUE(found_info != levels.end());
|
||||
|
||||
bool wasFound = (levels.end() != std::find(levels.begin(), levels.end(), info));
|
||||
EXPECT_TRUE(wasFound);
|
||||
|
||||
auto wasNotFound = (levels.end() == std::find(levels.begin(), levels.end(), debug));
|
||||
EXPECT_TRUE(wasNotFound);
|
||||
|
||||
auto foundWarningIterator = std::find(levels.begin(), levels.end(), WARNING);
|
||||
EXPECT_TRUE(foundWarningIterator != levels.end());
|
||||
|
||||
foundWarningIterator = std::find(levels.begin(), levels.end(), warning);
|
||||
EXPECT_TRUE(foundWarningIterator != levels.end());
|
||||
|
||||
auto wasNotFoundIterator = std::find(levels.begin(), levels.end(), DEBUG);
|
||||
EXPECT_FALSE(wasNotFoundIterator != levels.end());
|
||||
}
|
||||
|
||||
|
||||
TEST(Basics, Levels_Operator) {
|
||||
auto info = INFO;
|
||||
auto warning = WARNING;
|
||||
EXPECT_NE(INFO, WARNING);
|
||||
EXPECT_EQ(info, INFO);
|
||||
EXPECT_TRUE(INFO == INFO);
|
||||
EXPECT_FALSE(info == WARNING);
|
||||
EXPECT_TRUE(info != WARNING);
|
||||
EXPECT_FALSE(info != INFO);
|
||||
}
|
||||
|
||||
TEST(Basics, Shutdown) {
|
||||
std::string file_content;
|
||||
@ -280,12 +317,13 @@ TEST(LogTest, LOG_preFatalLogging_hook) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_FALSE(mockFatalWasCalled());
|
||||
g_fatal_counter.store(0);
|
||||
g3::setFatalPreLoggingHook(fatalCounter);
|
||||
g3::setFatalPreLoggingHook(fatalCounter);
|
||||
LOG(FATAL) << "This message is fatal";
|
||||
logger.reset();
|
||||
EXPECT_EQ(g_fatal_counter.load(), size_t{1});
|
||||
}
|
||||
{ // Now with no fatal pre-logging-hook
|
||||
{
|
||||
// Now with no fatal pre-logging-hook
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_FALSE(mockFatalWasCalled());
|
||||
g_fatal_counter.store(0);
|
||||
@ -299,14 +337,14 @@ TEST(LogTest, LOG_preFatalLogging_hook) {
|
||||
TEST(LogTest, LOG_FATAL) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_FALSE(mockFatalWasCalled());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LOG(FATAL) << "This message is fatal";
|
||||
EXPECT_TRUE(mockFatalWasCalled());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), "EXIT trigger caused by "));
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), "This message is fatal"))
|
||||
<< "\ncontent: [[" << mockFatalMessage() << "]]";
|
||||
<< "\ncontent: [[" << mockFatalMessage() << "]]";
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), "FATAL"));
|
||||
|
||||
logger.reset();
|
||||
@ -419,31 +457,31 @@ TEST(CHECK, CHECK_ThatWontThrow) {
|
||||
|
||||
|
||||
|
||||
TEST(CustomLogLevels, AddANonFatal){
|
||||
TEST(CustomLogLevels, AddANonFatal) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS MYINFO {WARNING.value +1, {"MY_INFO_LEVEL"}};
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
const LEVELS MYINFO {WARNING.value + 1, {"MY_INFO_LEVEL"}};
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
g3::only_change_at_initialization::setLogLevel(MYINFO, true);
|
||||
#endif
|
||||
#endif
|
||||
LOG(MYINFO) << "Testing my own custom level"; auto line = __LINE__;
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
std::string expected;
|
||||
expected += "MY_INFO_LEVEL [test_io.cpp L: " + std::to_string(line);
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
}
|
||||
|
||||
TEST(CustomLogLevels, AddFatal){
|
||||
TEST(CustomLogLevels, AddFatal) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS DEADLY {FATAL.value +1, {"DEADLY"}};
|
||||
const LEVELS DEADLY {FATAL.value + 1, {"DEADLY"}};
|
||||
EXPECT_TRUE(g3::internal::wasFatal(DEADLY));
|
||||
g_fatal_counter.store(0);
|
||||
ASSERT_FALSE(mockFatalWasCalled());
|
||||
g3::setFatalPreLoggingHook(fatalCounter);
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
g3::setFatalPreLoggingHook(fatalCounter);
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
g3::only_change_at_initialization::setLogLevel(DEADLY, true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
LOG(DEADLY) << "Testing my own custom level"; auto line = __LINE__;
|
||||
logger.reset();
|
||||
@ -453,13 +491,13 @@ TEST(CustomLogLevels, AddFatal){
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
std::string expected;
|
||||
expected += "DEADLY [test_io.cpp L: " + std::to_string(line);
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
g_fatal_counter.store(0); // restore
|
||||
}
|
||||
|
||||
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
namespace {
|
||||
// Restore dynamic levels if turned off
|
||||
|
||||
@ -477,9 +515,9 @@ namespace {
|
||||
} // anonymous
|
||||
|
||||
|
||||
TEST(CustomLogLevels, AddANonFatal__ThenReset){
|
||||
TEST(CustomLogLevels, AddANonFatal__ThenReset) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS MYINFO {WARNING.value +2, {"MY_INFO_LEVEL"}};
|
||||
const LEVELS MYINFO {WARNING.value + 2, {"MY_INFO_LEVEL"}};
|
||||
EXPECT_FALSE(g3::logLevel(MYINFO));
|
||||
g3::only_change_at_initialization::setLogLevel(MYINFO, true);
|
||||
EXPECT_TRUE(g3::logLevel(MYINFO));
|
||||
@ -488,22 +526,22 @@ TEST(CustomLogLevels, AddANonFatal__ThenReset){
|
||||
}
|
||||
|
||||
|
||||
TEST(CustomLogLevels, AddANonFatal__DidNotAddItToEnabledValue1){
|
||||
TEST(CustomLogLevels, AddANonFatal__DidNotAddItToEnabledValue1) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS MYINFO {WARNING.value +2, {"MY_INFO_LEVEL"}};
|
||||
const LEVELS MYINFO {WARNING.value + 2, {"MY_INFO_LEVEL"}};
|
||||
LOG(MYINFO) << "Testing my own custom level"; auto line = __LINE__;
|
||||
logger.reset();
|
||||
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
std::string expected;
|
||||
expected += "MY_INFO_LEVEL [test_io.cpp L: " + std::to_string(line);
|
||||
EXPECT_FALSE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected << "\nLevels:\n" << g3::only_change_at_initialization::printLevels();
|
||||
EXPECT_FALSE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected << "\nLevels:\n" << g3::only_change_at_initialization::printLevels();
|
||||
}
|
||||
|
||||
TEST(CustomLogLevels, AddANonFatal__DidNotAddItToEnabledValue2){
|
||||
TEST(CustomLogLevels, AddANonFatal__DidNotAddItToEnabledValue2) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS MYINFO {WARNING.value +2, {"MY_INFO_LEVEL"}};
|
||||
const LEVELS MYINFO {WARNING.value + 2, {"MY_INFO_LEVEL"}};
|
||||
EXPECT_FALSE(g3::logLevel(MYINFO));
|
||||
LOG(MYINFO) << "Testing my own custom level"; auto line = __LINE__;
|
||||
logger.reset();
|
||||
@ -511,21 +549,21 @@ TEST(CustomLogLevels, AddANonFatal__DidNotAddItToEnabledValue2){
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
std::string expected;
|
||||
expected += "MY_INFO_LEVEL [test_io.cpp L: " + std::to_string(line);
|
||||
EXPECT_FALSE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected << "\nLevels:\n" << g3::only_change_at_initialization::printLevels();
|
||||
EXPECT_FALSE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected << "\nLevels:\n" << g3::only_change_at_initialization::printLevels();
|
||||
}
|
||||
|
||||
TEST(CustomLogLevels, AddANonFatal__DidtAddItToEnabledValue){
|
||||
TEST(CustomLogLevels, AddANonFatal__DidtAddItToEnabledValue) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
const LEVELS MYINFO {WARNING.value +3, {"MY_INFO_LEVEL"}};
|
||||
const LEVELS MYINFO {WARNING.value + 3, {"MY_INFO_LEVEL"}};
|
||||
g3::only_change_at_initialization::setLogLevel(MYINFO, true);
|
||||
LOG(MYINFO) << "Testing my own custom level"; auto line = __LINE__;
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
std::string expected;
|
||||
expected += "MY_INFO_LEVEL [test_io.cpp L: " + std::to_string(line);
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
EXPECT_TRUE(verifyContent(file_content, expected)) << file_content
|
||||
<< "\n\nExpected: \n" << expected;
|
||||
}
|
||||
|
||||
|
||||
@ -562,7 +600,7 @@ TEST(DynamicLogging, DynamicLogging_IS_ENABLED) {
|
||||
}
|
||||
TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
@ -570,16 +608,16 @@ TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
}
|
||||
|
||||
RestoreDynamicLoggingLevels raiiLevelRestore;
|
||||
|
||||
|
||||
std::string msg_debugOn = "This %s SHOULD appear in the %s";
|
||||
std::string msg_debugOff = "This message should never appear in the log";
|
||||
std::string msg_info1 = "This info msg log";
|
||||
try {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOGF(DEBUG, msg_debugOn.c_str(), "msg", "log");
|
||||
auto content = logger.resetAndRetrieveContent();
|
||||
ASSERT_TRUE(verifyContent(content, "This msg SHOULD appear in the log")) << "Content: [" << content << "]";
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOGF(DEBUG, msg_debugOn.c_str(), "msg", "log");
|
||||
auto content = logger.resetAndRetrieveContent();
|
||||
ASSERT_TRUE(verifyContent(content, "This msg SHOULD appear in the log")) << "Content: [" << content << "]";
|
||||
}
|
||||
|
||||
{
|
||||
@ -590,8 +628,8 @@ TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
auto content = logger.resetAndRetrieveContent();
|
||||
ASSERT_FALSE(verifyContent(content, "This message should never appear in the log")) << "Content: [" << content << "]";
|
||||
}
|
||||
|
||||
} catch (std::exception const &e) {
|
||||
|
||||
} catch (std::exception const& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
ADD_FAILURE() << "Should never have thrown";
|
||||
}
|
||||
@ -610,11 +648,11 @@ TEST(DynamicLogging, DynamicLogging_No_Fatal_If_Disabled) {
|
||||
EXPECT_TRUE(mockFatalWasCalled());
|
||||
EXPECT_FALSE(mockFatalMessage().empty());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), msg1));
|
||||
|
||||
|
||||
clearMockFatal();
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
|
||||
|
||||
|
||||
|
||||
g3::only_change_at_initialization::setLogLevel(FATAL, false);
|
||||
std::string msg3 = "This is NOT fatal (not crash, since it is unit test. FATAL is disabled";
|
||||
LOG(FATAL) << msg3;
|
||||
@ -633,10 +671,10 @@ TEST(DynamicLogging, DynamicLogging_Check_WillAlsoBeTurnedOffWhen_Fatal_Is_Disab
|
||||
LOG(FATAL) << msg1;
|
||||
EXPECT_TRUE(mockFatalWasCalled());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), msg1));
|
||||
|
||||
|
||||
clearMockFatal();
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
|
||||
|
||||
// Disable also CHECK calls
|
||||
g3::only_change_at_initialization::setLogLevel(FATAL, false);
|
||||
ASSERT_FALSE(g3::logLevel(FATAL));
|
||||
@ -647,7 +685,7 @@ TEST(DynamicLogging, DynamicLogging_Check_WillAlsoBeTurnedOffWhen_Fatal_Is_Disab
|
||||
|
||||
|
||||
|
||||
#else
|
||||
#else
|
||||
TEST(DynamicLogging, DynamicLogging_IS_NOT_ENABLED) {
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
//g3::setLogLevel(DEBUG, false); this line will not compile since G3_DYNAMIC_LOGGING is not enabled. Kept for show.
|
||||
|
Loading…
Reference in New Issue
Block a user