mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-12 10:23:50 +01:00
Easier to install. continues
1) Breaking change: g3 namespace replaces g2 2) g2log.hpp remains in src/g2log.hpp... but now all it does is to include the g3log.hpp, etc 3) ALL HEADER FILES ARE IN src/g3log/ while all .cpp and .ipp files are in /src (exception for g2log.hpp) This should make it EASIER for clients to copy/install the header files to the new location. It greatly simplifies rpm and cpackage installationsw
This commit is contained in:
parent
7cf42c535c
commit
7c7012325d
@ -18,7 +18,7 @@ SET(ACTIVE_CPP0xx_DIR "Release")
|
||||
# WARNING: If Clang for Linux does not work with full C++11 support it might be your
|
||||
# installation that is faulty. When I tested Clang on Ubuntu I followed the following
|
||||
# description
|
||||
# 1) http://kjellkod.wordpress.com/2013/09/23/experimental-g2log-with-clang/
|
||||
# 1) http://kjellkod.wordpress.com/2013/09/23/experimental-g3log-with-clang/
|
||||
# 2) https://github.com/maidsafe/MaidSafe/wiki/Hacking-with-Clang-llvm-abi-and-llvm-libc
|
||||
IF ("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang")
|
||||
MESSAGE("")
|
||||
@ -64,14 +64,14 @@ IF (MSVC OR MINGW)
|
||||
ENDIF()
|
||||
|
||||
# GENERIC STEPS
|
||||
file(GLOB SRC_FILES ${LOG_SRC}/g3log/*.h ${LOG_SRC}/g3log/*.hpp ${LOG_SRC}/g3log/*.cpp ${LOG_SRC}/g3log/*.ipp)
|
||||
file(GLOB SRC_FILES ${LOG_SRC}/g3log/*.h ${LOG_SRC}/g3log/*.hpp ${LOG_SRC}/*.cpp ${LOG_SRC}/*.ipp)
|
||||
file(GLOB HEADER_FILES ${LOG_SRC}/g3log/*.hpp ${LOG_SRC}/*.hpp)
|
||||
#MESSAGE(" HEADER FILES ARE: ${HEADER_FILES}")
|
||||
|
||||
IF (MSVC OR MINGW)
|
||||
list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/g3log/crashhandler_unix.cpp)
|
||||
ELSE()
|
||||
list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/g3log/crashhandler_windows.cpp ${LOG_SRC}/g3log/stacktrace_windows.hpp ${LOG_SRC}/g3log/stacktrace_windows.cpp)
|
||||
list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/crashhandler_windows.cpp ${LOG_SRC}/g3log/stacktrace_windows.hpp ${LOG_SRC}/stacktrace_windows.cpp)
|
||||
ENDIF (MSVC OR MINGW)
|
||||
|
||||
set(SRC_FILES ${SRC_FILES} ${SRC_PLATFORM_SPECIFIC})
|
||||
|
@ -103,7 +103,7 @@ endif()
|
||||
# ==========================================================================
|
||||
# UNIT TEST OPTIONS:
|
||||
# ============================================================================
|
||||
# ENABLE WITH: -DADD_G2LOG_UNIT_TEST=ON
|
||||
# ENABLE WITH: -DADD_G3LOG_UNIT_TEST=ON
|
||||
INCLUDE (${g3log_SOURCE_DIR}/test_unit/Test.cmake)
|
||||
|
||||
|
||||
|
@ -22,11 +22,11 @@ SET(G3_DEFINITIONS "")
|
||||
option (USE_DYNAMIC_LOGGING_LEVELS
|
||||
"Turn ON/OFF log levels. An disabled level will not push logs of that level to the sink. By default dynamic logging is disabled" OFF)
|
||||
IF(USE_DYNAMIC_LOGGING_LEVELS)
|
||||
LIST(APPEND G3_DEFINITIONS G2_DYNAMIC_LOGGING)
|
||||
add_definitions(-DG2_DYNAMIC_LOGGING)
|
||||
LIST(APPEND G3_DEFINITIONS G3_DYNAMIC_LOGGING)
|
||||
add_definitions(-DG3_DYNAMIC_LOGGING)
|
||||
MESSAGE("-DUSE_DYNAMIC_LOGGING_LEVELS=ON")
|
||||
MESSAGE("\tDynamic logging levels can be turned on. Make sure to have [#define G2_DYNAMIC_LOGGING 1] in your source code")
|
||||
MESSAGE("\tUse [g2::setLogLevel(LEVEL boolean)] to enable/disable logging on specified levels\n\n")
|
||||
MESSAGE("\tDynamic logging levels can be turned on. Make sure to have [#define G3_DYNAMIC_LOGGING 1] in your source code")
|
||||
MESSAGE("\tUse [g3::setLogLevel(LEVEL boolean)] to enable/disable logging on specified levels\n\n")
|
||||
ELSE()
|
||||
MESSAGE("-DUSE_DYNAMIC_LOGGING_LEVELS=OFF")
|
||||
ENDIF(USE_DYNAMIC_LOGGING_LEVELS)
|
||||
|
@ -31,7 +31,7 @@ CHECK(less > more) << "CHECK(false) triggers a FATAL message";
|
||||
|
||||
|
||||
## What G3Log is:
|
||||
* ***G3log*** is the acting name for the third version of g2log and it stands for **g2log with dynamic sinks**
|
||||
* ***G3log*** is the acting name for the third version of g2log and it stands for **g3log with dynamic sinks**
|
||||
* G3log is an asynchronous, "crash-safe" logger. You can read more about it here [[g2log version]](
|
||||
http://www.codeproject.com/Articles/288827/g2log-An-efficient-asynchronous-logger-using-Cplus)
|
||||
* You can choose to use the default log receiver which saves all LOG calls to file, **or** you can choose to use your own custom made log receiver(s), **or** both, **or** as many sinks as you need.
|
||||
@ -59,17 +59,17 @@ The logger will catch certain fatal events *(Linux/OSX: signals, Windows: fatal
|
||||
|
||||
8. The code is given for free as public domain. This gives the option to change, use, and do whatever with it, no strings attached.
|
||||
|
||||
9. Two versions of g2log exist that are under active development.
|
||||
* This version: *[g3log](https://bitbucket.org/KjellKod/g3log)* : which is made to facilitate easy adding of custom log receivers. Its tested on at least the following platforms with Linux(Clang/gcc), Windows (mingw, visual studio 2013). My recommendation is to go with g3log if you have full C++11 support.
|
||||
* *[g2log](https://bitbucket.org/KjellKod/g2log)*: The original. Simple, easy to modify and with the most OS support. Clients use g2log on environments such as OSX/Clang, Ubuntu, CentOS, Windows/mingw, Windows/Visual Studio. The focus on g2log is stability and compiler support. Only well, time tested, features from g3log will make it into g2log.
|
||||
9. Two versions of g3log exist that are under active development.
|
||||
* This version: *[g3log](https://github.com/KjellKod/g3log)* : which is made to facilitate easy adding of custom log receivers. Its tested on at least the following platforms with Linux(Clang/gcc), Windows (mingw, visual studio 2013). My recommendation is to go with g3log if you have full C++11 support.
|
||||
* *[g2log](https://bitbucket.org/KjellKod/g2log)*: The original. Simple, easy to modify and with the most OS support. Clients use g2log on environments such as OSX/Clang, Ubuntu, CentOS, Windows/mingw, Windows/Visual Studio. The focus on g2log is "slow to change" and compiler support. Only well, time tested, features from g3log will make it into g2log.
|
||||
|
||||
|
||||
|
||||
|
||||
# G3log with sinks
|
||||
[Sinks](http://en.wikipedia.org/wiki/Sink_(computing)) are receivers of LOG calls. G3log comes with a default sink (*the same as G2log uses*) that can be used to save log to file. A sink can be of *any* class type without restrictions as long as it can either receive a LOG message as a *std::string* **or** as a *g2::LogMessageMover*.
|
||||
[Sinks](http://en.wikipedia.org/wiki/Sink_(computing)) are receivers of LOG calls. G3log comes with a default sink (*the same as G3log uses*) that can be used to save log to file. A sink can be of *any* class type without restrictions as long as it can either receive a LOG message as a *std::string* **or** as a *g3::LogMessageMover*.
|
||||
|
||||
The *std::string* comes pre-formatted. The *g2::LogMessageMover* is a wrapped struct that contains the raw data for custom handling in your own sink.
|
||||
The *std::string* comes pre-formatted. The *g3::LogMessageMover* is a wrapped struct that contains the raw data for custom handling in your own sink.
|
||||
|
||||
A sink is *owned* by the G3log and is added to the logger inside a ```std::unique_ptr```. The sink can be called though its public API through a *handler* which will asynchronously forward the call to the receiving sink.
|
||||
```
|
||||
@ -81,14 +81,14 @@ auto sinkHandle = logworker->addSink(std2::make_unique<CustomSink>(),
|
||||
Example usage where a custom sink is added. A function is called though the sink handler to the actual sink object.
|
||||
```
|
||||
// main.cpp
|
||||
#include<g2log.hpp>
|
||||
#include<g2logworker.hpp>
|
||||
#include <std2_make_unique.hpp>
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/g3logworker.hpp>
|
||||
#include <g3log/std2_make_unique.hpp>
|
||||
|
||||
#include "CustomSink.h"
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
std::unique_ptr<LogWorker> logworker{ LogWorker::createWithNoSink() };
|
||||
auto sinkHandle = logworker->addSink(std2::make_unique<CustomSink>(),
|
||||
&CustomSink::ReceiveLogMessage);
|
||||
@ -104,19 +104,19 @@ int main(int argc, char**argv) {
|
||||
std::future<void> received = sinkHandle->call(&CustomSink::Foo,
|
||||
param1, param2);
|
||||
|
||||
// If the LogWorker is initialized then at scope exit the g2::shutDownLogging() will be called.
|
||||
// If the LogWorker is initialized then at scope exit the g3::shutDownLogging() will be called.
|
||||
// This is important since it protects from LOG calls from static or other entities that will go out of
|
||||
// scope at a later time.
|
||||
//
|
||||
// It can also be called manually:
|
||||
g2::shutDownLogging();
|
||||
g3::shutDownLogging();
|
||||
}
|
||||
|
||||
|
||||
// some_file.cpp : To show how easy it is to get the logger to work
|
||||
// in other parts of your software
|
||||
|
||||
#include <g2log.hpp>
|
||||
#include <g3log/g3log.hpp>
|
||||
|
||||
void SomeFunction() {
|
||||
...
|
||||
@ -127,19 +127,19 @@ void SomeFunction() {
|
||||
Example usage where a the default file logger is used **and** a custom sink is added
|
||||
```
|
||||
// main.cpp
|
||||
#include<g2log.hpp>
|
||||
#include<g2logworker.hpp>
|
||||
#include <std2_make_unique.hpp>
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include <g3log/std2_make_unique.hpp>
|
||||
|
||||
#include "CustomSink.h"
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
auto defaultHandler = LogWorker::createWithDefaultLogger(argv[0],
|
||||
path_to_log_file);
|
||||
|
||||
// logger is initialized
|
||||
g2::initializeLogging(defaultHandler.worker.get());
|
||||
g3::initializeLogging(defaultHandler.worker.get());
|
||||
|
||||
LOG(DEBUG) << "Make log call, then add another sink";
|
||||
|
||||
|
@ -6,7 +6,8 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
#include "g2log.hpp"
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
@ -34,12 +35,12 @@ int main(int argc, char **argv)
|
||||
double pi_d = 3.1415926535897932384626433832795;
|
||||
float pi_f = 3.1415926535897932384626433832795f;
|
||||
|
||||
auto logger_n_handle = g2::LogWorker::createWithDefaultLogger(argv[0], path_to_log_file);
|
||||
g2::initializeLogging(logger_n_handle.worker.get());
|
||||
std::future<std::string> log_file_name = logger_n_handle.sink->call(&g2::FileSink::fileName);
|
||||
std::cout << "* This is an example of g2log. It WILL exit by a failed CHECK(...)" << std::endl;
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(argv[0], path_to_log_file);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
std::future<std::string> log_file_name = logger_n_handle.sink->call(&g3::FileSink::fileName);
|
||||
std::cout << "* This is an example of g3log. It WILL exit by a failed CHECK(...)" << std::endl;
|
||||
std::cout << "* that acts as a FATAL trigger. Please see the generated log and " << std::endl;
|
||||
std::cout << "* compare to the code at:\n* \t g2log/test_example/main_contract.cpp" << std::endl;
|
||||
std::cout << "* compare to the code at:\n* \t g3log/test_example/main_contract.cpp" << std::endl;
|
||||
std::cout << "*\n* Log file: [" << log_file_name.get() << "]\n\n" << std::endl;
|
||||
|
||||
LOGF(INFO, "Hi log %d", 123);
|
||||
|
@ -6,9 +6,8 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
#include <g2log.hpp>
|
||||
//#/g3log.hpp>
|
||||
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cctype>
|
||||
@ -243,11 +242,11 @@ void breakHere() {
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
auto logger_n_handle = g2::LogWorker::createWithDefaultLogger(argv[0], path_to_log_file);
|
||||
g2::initializeLogging(logger_n_handle.worker.get());
|
||||
g2::setFatalPreLoggingHook(&breakHere);
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(argv[0], path_to_log_file);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
g3::setFatalPreLoggingHook(&breakHere);
|
||||
|
||||
std::future<std::string> log_file_name = logger_n_handle.sink->call(&g2::FileSink::fileName);
|
||||
std::future<std::string> log_file_name = logger_n_handle.sink->call(&g3::FileSink::fileName);
|
||||
std::cout << "**** G3LOG FATAL EXAMPLE ***\n\n"
|
||||
<< "Choose your type of fatal exit, then "
|
||||
<< " read the generated log and backtrace.\n"
|
||||
|
@ -6,7 +6,8 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
#include "g2log.hpp"
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
@ -52,7 +53,7 @@ int main(int argc, char **argv)
|
||||
double pi_d = 3.1415926535897932384626433832795;
|
||||
float pi_f = 3.1415926535897932384626433832795f;
|
||||
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
|
||||
std::unique_ptr<LogWorker> logworker {LogWorker::createWithNoSink()};
|
||||
auto sinkHandle = logworker->addSink(std2::make_unique<FileSink>(argv[0], path_to_log_file),
|
||||
@ -60,9 +61,9 @@ int main(int argc, char **argv)
|
||||
|
||||
initializeLogging(logworker.get());
|
||||
std::future<std::string> log_file_name = sinkHandle->call(&FileSink::fileName);
|
||||
std::cout << "* This is an example of g2log. It WILL exit by a FATAL trigger" << std::endl;
|
||||
std::cout << "* This is an example of g3log. It WILL exit by a FATAL trigger" << std::endl;
|
||||
std::cout << "* Please see the generated log and compare to the code at" << std::endl;
|
||||
std::cout << "* g2log/test_example/main.cpp" << std::endl;
|
||||
std::cout << "* g3log/test_example/main.cpp" << std::endl;
|
||||
std::cout << "*\n* Log file: [" << log_file_name.get() << "]\n\n" << std::endl;
|
||||
|
||||
|
||||
|
@ -34,21 +34,21 @@
|
||||
|
||||
|
||||
namespace {
|
||||
// Dump of stack,. then exit through g2log background worker
|
||||
// Dump of stack,. then exit through g3log background worker
|
||||
// ALL thanks to this thread at StackOverflow. Pretty much borrowed from:
|
||||
// Ref: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
|
||||
void signalHandler(int signal_number, siginfo_t *info, void *unused_context) {
|
||||
using namespace g2::internal;
|
||||
using namespace g3::internal;
|
||||
{
|
||||
const auto dump = stackdump();
|
||||
std::ostringstream fatal_stream;
|
||||
const auto fatal_reason = exitReasonName(g2::internal::FATAL_SIGNAL, signal_number);
|
||||
const auto fatal_reason = exitReasonName(g3::internal::FATAL_SIGNAL, signal_number);
|
||||
fatal_stream << "Received fatal signal: " << fatal_reason;
|
||||
fatal_stream << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
|
||||
fatal_stream << "\n***** SIGNAL " << fatal_reason << "(" << signal_number << ")" << std::endl;
|
||||
LogCapture trigger(FATAL_SIGNAL, static_cast<g2::SignalType>(signal_number), dump.c_str());
|
||||
LogCapture trigger(FATAL_SIGNAL, static_cast<g3::SignalType>(signal_number), dump.c_str());
|
||||
trigger.stream() << fatal_stream.str();
|
||||
} // message sent to g2LogWorker
|
||||
} // message sent to g3LogWorker
|
||||
// wait to die
|
||||
}
|
||||
} // end anonymous namespace
|
||||
@ -58,9 +58,9 @@ namespace {
|
||||
|
||||
|
||||
|
||||
// Redirecting and using signals. In case of fatal signals g2log should log the fatal signal
|
||||
// Redirecting and using signals. In case of fatal signals g3log should log the fatal signal
|
||||
// and flush the log queue and then "rethrow" the signal to exit
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
// References:
|
||||
// sigaction : change the default action if a specific signal is received
|
||||
// http://linux.die.net/man/2/sigaction
|
||||
@ -137,7 +137,7 @@ namespace g2 {
|
||||
|
||||
|
||||
/// string representation of signal ID
|
||||
std::string exitReasonName(const LEVELS &level, g2::SignalType fatal_id) {
|
||||
std::string exitReasonName(const LEVELS &level, g3::SignalType fatal_id) {
|
||||
|
||||
int signal_number = static_cast<int>(fatal_id);
|
||||
switch (signal_number) {
|
||||
@ -162,7 +162,7 @@ namespace g2 {
|
||||
|
||||
// KJELL : TODO. The Fatal Message can contain a callback function that depending on OS and test scenario does
|
||||
// different things.
|
||||
// exitWithDefaultSignalHandler is called from g2logworke::bgFatal AFTER all the logging sinks have been cleared
|
||||
// exitWithDefaultSignalHandler is called from g3logworke::bgFatal AFTER all the logging sinks have been cleared
|
||||
// I.e. saving a function that has the value already encapsulated within.
|
||||
// FatalMessagePtr msgPtr
|
||||
// Linux/OSX --> msgPtr.get()->ContinueWithFatalExit(); --> exitWithDefaultSignalHandler(int signal_number);
|
||||
@ -172,15 +172,15 @@ namespace g2 {
|
||||
// i.e. an atomic flag should be set
|
||||
// the next step should then be to re-throw the same exception
|
||||
// i.e. just call the next exception handler
|
||||
// we should make sure that 1) g2log exception handler is called BEFORE widows
|
||||
// we should make sure that 1) g3log exception handler is called BEFORE widows
|
||||
// it should continue and then be caught in Visual Studios exception handler
|
||||
//
|
||||
//
|
||||
|
||||
// Triggered by g2log->g2LogWorker after receiving a FATAL trigger
|
||||
// Triggered by g3log->g3LogWorker after receiving a FATAL trigger
|
||||
// which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
|
||||
// --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g2::SignalType fatal_signal_id) {
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g3::SignalType fatal_signal_id) {
|
||||
const int signal_number = static_cast<int>(fatal_signal_id);
|
||||
std::cerr << "Exiting due to " << level.text << ", " << signal_number << " " << std::flush;
|
||||
|
||||
@ -195,7 +195,7 @@ namespace g2 {
|
||||
kill(getpid(), signal_number);
|
||||
abort(); // should never reach this
|
||||
}
|
||||
} // end g2::internal
|
||||
} // end g3::internal
|
||||
|
||||
|
||||
//
|
||||
@ -228,8 +228,8 @@ namespace g2 {
|
||||
|
||||
void installCrashHandler() {
|
||||
installSignalHandler();
|
||||
} // namespace g2::internal
|
||||
} // namespace g3::internal
|
||||
|
||||
|
||||
} // end namespace g2
|
||||
} // end namespace g3
|
||||
|
@ -69,15 +69,15 @@ namespace {
|
||||
|
||||
// called for fatal signals SIGABRT, SIGFPE, SIGSEGV, SIGILL, SIGTERM
|
||||
void signalHandler(int signal_number) {
|
||||
using namespace g2::internal;
|
||||
using namespace g3::internal;
|
||||
std::string dump = stacktrace::stackdump();
|
||||
|
||||
std::ostringstream fatal_stream;
|
||||
fatal_stream << "\n***** Received fatal signal " << g2::internal::exitReasonName(g2::internal::FATAL_SIGNAL, signal_number);
|
||||
fatal_stream << "\n***** Received fatal signal " << g3::internal::exitReasonName(g3::internal::FATAL_SIGNAL, signal_number);
|
||||
fatal_stream << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
|
||||
|
||||
|
||||
LogCapture trigger(FATAL_SIGNAL, static_cast<g2::SignalType>(signal_number), dump.c_str());
|
||||
LogCapture trigger(FATAL_SIGNAL, static_cast<g3::SignalType>(signal_number), dump.c_str());
|
||||
trigger.stream() << fatal_stream.str();
|
||||
|
||||
// Trigger debug break point, if we're in debug. This breakpoint CAN cause a slowdown when it happens.
|
||||
@ -99,12 +99,12 @@ namespace {
|
||||
std::string dump = stacktrace::stackdump(info);
|
||||
|
||||
std::ostringstream fatal_stream;
|
||||
const g2::SignalType exception_code = info->ExceptionRecord->ExceptionCode;
|
||||
fatal_stream << "\n***** " << handler << ": Received fatal exception " << g2::internal::exitReasonName(g2::internal::FATAL_EXCEPTION, exception_code);
|
||||
const g3::SignalType exception_code = info->ExceptionRecord->ExceptionCode;
|
||||
fatal_stream << "\n***** " << handler << ": Received fatal exception " << g3::internal::exitReasonName(g3::internal::FATAL_EXCEPTION, exception_code);
|
||||
fatal_stream << "\tPID: " << getpid() << std::endl;
|
||||
|
||||
const auto fatal_id = static_cast<g2::SignalType>(exception_code);
|
||||
LogCapture trigger(g2::internal::FATAL_EXCEPTION, fatal_id, dump.c_str());
|
||||
const auto fatal_id = static_cast<g3::SignalType>(exception_code);
|
||||
LogCapture trigger(g3::internal::FATAL_EXCEPTION, fatal_id, dump.c_str());
|
||||
trigger.stream() << fatal_stream.str();
|
||||
// FATAL Exception: It doesn't necessarily stop here we pass on continue search
|
||||
// if no one else will catch that then it's goodbye anyhow.
|
||||
@ -127,7 +127,7 @@ namespace {
|
||||
/// Ref: http://blogs.msdn.com/b/zhanli/archive/2010/06/25/c-tips-addvectoredexceptionhandler-addvectoredcontinuehandler-and-setunhandledexceptionfilter.aspx
|
||||
#if !(defined(DISABLE_VECTORED_EXCEPTIONHANDLING))
|
||||
LONG WINAPI vectorExceptionHandling(PEXCEPTION_POINTERS p) {
|
||||
const g2::SignalType exception_code = p->ExceptionRecord->ExceptionCode;
|
||||
const g3::SignalType exception_code = p->ExceptionRecord->ExceptionCode;
|
||||
if (false == stacktrace::isKnownException(exception_code)) {
|
||||
// The unknown exception is ignored. Since it is not a Windows
|
||||
// fatal exception generated by the OS we leave the
|
||||
@ -146,7 +146,7 @@ namespace {
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
@ -171,8 +171,8 @@ namespace g2 {
|
||||
|
||||
|
||||
/// string representation of signal ID or Windows exception id
|
||||
std::string exitReasonName(const LEVELS &level, g2::SignalType fatal_id) {
|
||||
if (level == g2::internal::FATAL_EXCEPTION) {
|
||||
std::string exitReasonName(const LEVELS &level, g3::SignalType fatal_id) {
|
||||
if (level == g3::internal::FATAL_EXCEPTION) {
|
||||
return stacktrace::exceptionIdToText(fatal_id);
|
||||
}
|
||||
|
||||
@ -190,10 +190,10 @@ namespace g2 {
|
||||
}
|
||||
|
||||
|
||||
// Triggered by g2log::LogWorker after receiving a FATAL trigger
|
||||
// Triggered by g3log::LogWorker after receiving a FATAL trigger
|
||||
// which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
|
||||
// --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g2::SignalType fatal_signal_id) {
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g3::SignalType fatal_signal_id) {
|
||||
|
||||
ReverseToOriginalFatalHandling();
|
||||
// For windows exceptions we want to continue the possibility of
|
||||
@ -201,7 +201,7 @@ namespace g2 {
|
||||
// to sinks. We therefore avoid to kill the preocess here. Instead
|
||||
// it will be the exceptionHandling functions above that
|
||||
// will let exception handling continue with: EXCEPTION_CONTINUE_SEARCH
|
||||
if (g2::internal::FATAL_EXCEPTION == level) {
|
||||
if (g3::internal::FATAL_EXCEPTION == level) {
|
||||
gBlockForFatal = false;
|
||||
return;
|
||||
}
|
||||
@ -214,11 +214,11 @@ namespace g2 {
|
||||
|
||||
|
||||
void installSignalHandler() {
|
||||
g2::installSignalHandlerForThread();
|
||||
g3::installSignalHandlerForThread();
|
||||
}
|
||||
|
||||
|
||||
} // end g2::internal
|
||||
} // end g3::internal
|
||||
|
||||
|
||||
/// SIGFPE, SIGILL, and SIGSEGV handling must be installed per thread
|
||||
@ -256,4 +256,4 @@ namespace g2 {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace g2
|
||||
} // end namespace g3
|
@ -7,10 +7,10 @@
|
||||
* ============================================================================*/
|
||||
|
||||
#include "g3log/filesink.hpp"
|
||||
#include "g3log/filesinkhelper.ipp"
|
||||
#include "filesinkhelper.ipp"
|
||||
#include <cassert>
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
using namespace internal;
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ namespace g2 {
|
||||
{
|
||||
_log_prefix_backup = prefixSanityFix(log_prefix);
|
||||
if (!isValidFilename(_log_prefix_backup)) {
|
||||
std::cerr << "g2log: forced abort due to illegal log prefix [" << log_prefix << "]" << std::endl;
|
||||
std::cerr << "g3log: forced abort due to illegal log prefix [" << log_prefix << "]" << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ namespace g2 {
|
||||
|
||||
|
||||
FileSink::~FileSink() {
|
||||
std::string exit_msg {"\ng2log g2FileSink shutdown at: "};
|
||||
std::string exit_msg {"\ng3log g3FileSink shutdown at: "};
|
||||
exit_msg.append(localtime_formatted(systemtime_now(), internal::time_formatted));
|
||||
filestream() << exit_msg << std::flush;
|
||||
|
||||
@ -56,8 +56,8 @@ namespace g2 {
|
||||
|
||||
std::string FileSink::changeLogFile(const std::string &directory) {
|
||||
|
||||
auto now = g2::systemtime_now();
|
||||
auto now_formatted = g2::localtime_formatted(now, {internal::date_formatted + " " + internal::time_formatted});
|
||||
auto now = g3::systemtime_now();
|
||||
auto now_formatted = g3::localtime_formatted(now, {internal::date_formatted + " " + internal::time_formatted});
|
||||
|
||||
std::string file_name = createLogFileName(_log_prefix_backup);
|
||||
std::string prospect_log = directory + file_name;
|
||||
@ -89,4 +89,4 @@ namespace g2 {
|
||||
filestream() << header();
|
||||
}
|
||||
|
||||
} // g2
|
||||
} // g3
|
@ -18,7 +18,7 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
static const std::string file_name_time_formatted = "%Y%m%d-%H%M%S";
|
||||
|
||||
@ -79,7 +79,7 @@ namespace g2 {
|
||||
std::string header() {
|
||||
std::ostringstream ss_entry;
|
||||
// Day Month Date Time Year: is written as "%a %b %d %H:%M:%S %Y" and formatted output as : Wed Sep 19 08:28:16 2012
|
||||
ss_entry << "\t\tg2log created log at: " << g2::localtime_formatted(g2::systemtime_now(), "%a %b %d %H:%M:%S %Y") << "\n";
|
||||
ss_entry << "\t\tg3log created log at: " << g3::localtime_formatted(g3::systemtime_now(), "%a %b %d %H:%M:%S %Y") << "\n";
|
||||
ss_entry << "\t\tLOG format: [YYYY/MM/DD hh:mm:ss uuu* LEVEL FILE:LINE] message";
|
||||
ss_entry << "\t\t(uuu*: microsecond counter since initialization of log worker)\n\n";
|
||||
return ss_entry.str();
|
||||
@ -87,8 +87,8 @@ namespace g2 {
|
||||
|
||||
std::string createLogFileName(const std::string &verified_prefix) {
|
||||
std::stringstream oss_name;
|
||||
oss_name << verified_prefix << ".g2log.";
|
||||
oss_name << g2::localtime_formatted(g2::systemtime_now(), file_name_time_formatted);
|
||||
oss_name << verified_prefix << ".g3log.";
|
||||
oss_name << g3::localtime_formatted(g3::systemtime_now(), file_name_time_formatted);
|
||||
oss_name << ".log";
|
||||
return oss_name.str();
|
||||
}
|
@ -7,8 +7,17 @@
|
||||
* ============================================================================*/
|
||||
|
||||
#pragma once
|
||||
#include "g3log/g3log.hpp"
|
||||
#include "g3log/logworker.hpp"
|
||||
#include "g3log/loglevels.hpp"
|
||||
#include "g3log/filesink.hpp"
|
||||
|
||||
// For convenience: If you don't want to do a recursive search and replace in your source code
|
||||
// for replacing g2log.hpp for g3log/g3log.hpp then you can choose to add this header file to your
|
||||
// code. It will get the necessary includes
|
||||
//
|
||||
//
|
||||
// Btw: replacing g2log for g3log include is easy on Linux
|
||||
// find . -name "*.cpp*" -print | xargs sed -i -e 's/\g2log\.hpp/\g3log\/g3log\.hpp/g'
|
||||
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include <g3log/loglevels.hpp>
|
||||
#include <g3log/filesink.hpp>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================
|
||||
*
|
||||
* Filename:g2log.cpp Framework for Logging and Design By Contract
|
||||
* Filename:g3log.cpp Framework for Logging and Design By Contract
|
||||
* Created: 2011 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not copywrited since it was built on public-domain software and at least in "spirit" influenced
|
||||
@ -35,10 +35,10 @@
|
||||
|
||||
namespace {
|
||||
std::once_flag g_initialize_flag;
|
||||
g2::LogWorker *g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
|
||||
g3::LogWorker *g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
|
||||
std::mutex g_logging_init_mutex;
|
||||
|
||||
std::unique_ptr<g2::LogMessage> g_first_unintialized_msg = {nullptr};
|
||||
std::unique_ptr<g3::LogMessage> g_first_unintialized_msg = {nullptr};
|
||||
std::once_flag g_set_first_uninitialized_flag;
|
||||
std::once_flag g_save_first_unintialized_flag;
|
||||
const std::function<void(void)> g_pre_fatal_hook_that_does_nothing = [] { /*does nothing */};
|
||||
@ -52,7 +52,7 @@ namespace {
|
||||
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
// signalhandler and internal clock is only needed to install once
|
||||
// for unit testing purposes the initializeLogging might be called
|
||||
// several times...
|
||||
@ -98,14 +98,14 @@ namespace g2 {
|
||||
|
||||
|
||||
// By default this function pointer goes to \ref pushFatalMessageToLogger;
|
||||
std::function<void(FatalMessagePtr) > g_fatal_to_g2logworker_function_ptr = internal::pushFatalMessageToLogger;
|
||||
std::function<void(FatalMessagePtr) > g_fatal_to_g3logworker_function_ptr = internal::pushFatalMessageToLogger;
|
||||
|
||||
/** REPLACE fatalCallToLogger for fatalCallForUnitTest
|
||||
* This function switches the function pointer so that only
|
||||
* 'unitTest' mock-fatal calls are made.
|
||||
* */
|
||||
void setFatalExitHandler(std::function<void(FatalMessagePtr) > fatal_call) {
|
||||
g_fatal_to_g2logworker_function_ptr = fatal_call;
|
||||
g_fatal_to_g3logworker_function_ptr = fatal_call;
|
||||
}
|
||||
|
||||
|
||||
@ -136,9 +136,9 @@ namespace g2 {
|
||||
bool shutDownLoggingForActiveOnly(LogWorker *active) {
|
||||
if (isLoggingInitialized() && nullptr != active && (active != g_logger_instance)) {
|
||||
LOG(WARNING) << "\n\t\tAttempted to shut down logging, but the ID of the Logger is not the one that is active."
|
||||
<< "\n\t\tHaving multiple instances of the g2::LogWorker is likely a BUG"
|
||||
<< "\n\t\tHaving multiple instances of the g3::LogWorker is likely a BUG"
|
||||
<< "\n\t\tEither way, this call to shutDownLogging was ignored"
|
||||
<< "\n\t\tTry g2::internal::shutDownLogging() instead";
|
||||
<< "\n\t\tTry g3::internal::shutDownLogging() instead";
|
||||
return false;
|
||||
}
|
||||
shutDownLogging();
|
||||
@ -178,7 +178,7 @@ namespace g2 {
|
||||
.append("---First crash stacktrace: ").append(first_stack_trace).append("\n---End of first stacktrace\n");
|
||||
}
|
||||
FatalMessagePtr fatal_message { std2::make_unique<FatalMessage>(*(message._move_only.get()), fatal_signal) };
|
||||
// At destruction, flushes fatal message to g2LogWorker
|
||||
// At destruction, flushes fatal message to g3LogWorker
|
||||
// either we will stay here until the background worker has received the fatal
|
||||
// message, flushed the crash message to the sinks and exits with the same fatal signal
|
||||
//..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep)
|
||||
@ -235,18 +235,18 @@ namespace g2 {
|
||||
}
|
||||
}
|
||||
|
||||
/** The default, initial, handling to send a 'fatal' event to g2logworker
|
||||
/** The default, initial, handling to send a 'fatal' event to g3logworker
|
||||
* the caller will stay here, eternally, until the software is aborted
|
||||
* ... in the case of unit testing it is the given "Mock" fatalCall that will
|
||||
* define the behaviour.
|
||||
*/
|
||||
void fatalCall(FatalMessagePtr message) {
|
||||
g_fatal_to_g2logworker_function_ptr(FatalMessagePtr {std::move(message)});
|
||||
g_fatal_to_g3logworker_function_ptr(FatalMessagePtr {std::move(message)});
|
||||
}
|
||||
|
||||
|
||||
} // internal
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
// kjell. Separera på crashhandler.hpp och crashhanlder_internal.hpp
|
||||
// implementationsfilen kan vara den samma
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
@ -30,7 +30,7 @@ namespace g2 {
|
||||
|
||||
namespace internal {
|
||||
/** return whether or any fatal handling is still ongoing
|
||||
* this is used by g2log::fatalCallToLogger
|
||||
* this is used by g3log::fatalCallToLogger
|
||||
* only in the case of Windows exceptions (not fatal signals)
|
||||
* are we interested in changing this from false to true to
|
||||
* help any other exceptions handler work with 'EXCEPTION_CONTINUE_SEARCH'*/
|
||||
@ -38,16 +38,16 @@ namespace g2 {
|
||||
|
||||
/** \return signal_name Ref: signum.hpp and \ref installSignalHandler
|
||||
* or for Windows exception name */
|
||||
std::string exitReasonName(const LEVELS &level, g2::SignalType signal_number);
|
||||
std::string exitReasonName(const LEVELS &level, g3::SignalType signal_number);
|
||||
|
||||
/** return calling thread's stackdump*/
|
||||
std::string stackdump(const char *dump = nullptr);
|
||||
|
||||
/** Re-"throw" a fatal signal, previously caught. This will exit the application
|
||||
* This is an internal only function. Do not use it elsewhere. It is triggered
|
||||
* from g2log, g2LogWorker after flushing messages to file */
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g2::SignalType signal_number);
|
||||
} // end g2::internal
|
||||
* from g3log, g3LogWorker after flushing messages to file */
|
||||
void exitWithDefaultSignalHandler(const LEVELS &level, g3::SignalType signal_number);
|
||||
} // end g3::internal
|
||||
|
||||
|
||||
// PUBLIC API:
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "g3log/logmessage.hpp"
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
class FileSink {
|
||||
public:
|
||||
@ -38,5 +38,5 @@ namespace g2 {
|
||||
FileSink(const FileSink &other) = delete;
|
||||
|
||||
};
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================
|
||||
* Filename:g2future.hpp
|
||||
* Filename:g3future.hpp
|
||||
* Helper functionality to put packaged_tasks in standard container. This
|
||||
* is especially helpful for background thread processing a la async but through
|
||||
* an actor pattern (active object), thread pool or similar.
|
||||
@ -30,7 +30,7 @@
|
||||
#include "g3log/moveoncopy.hpp"
|
||||
#include "g3log/stlpatch_future.hpp"
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
// Generic helper function to avoid repeating the steps for managing
|
||||
// asynchronous task job (by active object) that returns a future results
|
||||
// could of course be made even more generic if done more in the way of
|
||||
@ -40,7 +40,7 @@ namespace g2 {
|
||||
// std::unique_ptr<Active> bgWorker{Active::createActive()};
|
||||
// ...
|
||||
// auto msg_call=[=](){return ("Hello from the Background");};
|
||||
// auto future_msg = g2::spawn_task(msg_lambda, bgWorker.get());
|
||||
// auto future_msg = g3::spawn_task(msg_lambda, bgWorker.get());
|
||||
template <typename Func, class BgWorker>
|
||||
std::future<typename std::result_of<Func()>::type> spawn_task(Func func, BgWorker *worker)
|
||||
{
|
||||
@ -60,4 +60,4 @@ namespace g2 {
|
||||
worker->send(MoveOnCopy<task_type>(std::move(task)));
|
||||
return std::move(result);
|
||||
}
|
||||
} // end namespace g2
|
||||
} // end namespace g3
|
||||
|
@ -6,7 +6,7 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================
|
||||
*
|
||||
* Filename:g2log.hpp Framework for Logging and Design By Contract
|
||||
* Filename:g3log.hpp Framework for Logging and Design By Contract
|
||||
* Created: 2011 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not copywrited since it was built on public-domain software and influenced
|
||||
@ -42,23 +42,23 @@
|
||||
|
||||
|
||||
/** namespace for LOG() and CHECK() frameworks
|
||||
* History lesson: Why the names 'g2' and 'g2log'?:
|
||||
* History lesson: Why the names 'g3' and 'g3log'?:
|
||||
* The framework was made in my own free time as PUBLIC DOMAIN but the
|
||||
* first commercial project to use it used 'g2' as an internal denominator for
|
||||
* the current project. g2 as in 'generation 2'. I decided to keep the g2 and g2log names
|
||||
* first commercial project to use it used 'g3' as an internal denominator for
|
||||
* the current project. g3 as in 'generation 2'. I decided to keep the g3 and g3log names
|
||||
* to give credit to the people in that project (you know who you are :) and I guess also
|
||||
* for 'sentimental' reasons. That a big influence was google's glog is just a happy
|
||||
* concidence or subconscious choice. Either way g2log became the name for this logger.
|
||||
* concidence or subconscious choice. Either way g3log became the name for this logger.
|
||||
*
|
||||
* --- Thanks for a great 2011 and good luck with 'g2' --- KjellKod
|
||||
* --- Thanks for a great 2011 and good luck with 'g3' --- KjellKod
|
||||
*/
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
class LogWorker;
|
||||
struct LogMessage;
|
||||
struct FatalMessage;
|
||||
|
||||
/** Should be called at very first startup of the software with \ref g2LogWorker
|
||||
* pointer. Ownership of the \ref g2LogWorker is the responsibilkity of the caller */
|
||||
/** Should be called at very first startup of the software with \ref g3LogWorker
|
||||
* pointer. Ownership of the \ref g3LogWorker is the responsibilkity of the caller */
|
||||
void initializeLogging(LogWorker *logger);
|
||||
|
||||
|
||||
@ -70,17 +70,17 @@ namespace g2 {
|
||||
* This will be reset to default (does nothing) at initializeLogging(...);
|
||||
*
|
||||
* Example usage:
|
||||
* Windows: g2::setFatalPreLoggingHook([]{__debugbreak();}); // remember #include <intrin.h>
|
||||
* Windows: g3::setFatalPreLoggingHook([]{__debugbreak();}); // remember #include <intrin.h>
|
||||
* WARNING: '__debugbreak()' when not running in Debug in your Visual Studio IDE will likely
|
||||
* trigger a recursive crash if used here. It should only be used when debugging
|
||||
* in your Visual Studio IDE. Recursive crashes are handled but are unnecessary.
|
||||
*
|
||||
* Linux: g2::setFatalPreLoggingHook([]{ raise(SIGTRAP); });
|
||||
* Linux: g3::setFatalPreLoggingHook([]{ raise(SIGTRAP); });
|
||||
*/
|
||||
void setFatalPreLoggingHook(std::function<void(void)> pre_fatal_hook);
|
||||
|
||||
/** If the @ref setFatalPreLoggingHook is not enough and full fatal exit handling is needed then
|
||||
* use "setFatalExithandler". Please see g2log.cpp and crashhandler_windows.cpp or crashhandler_unix for
|
||||
* use "setFatalExithandler". Please see g3log.cpp and crashhandler_windows.cpp or crashhandler_unix for
|
||||
* example of restoring signal and exception handlers, flushing the log and shutting down.
|
||||
*/
|
||||
void setFatalExitHandler(std::function<void(FatalMessagePtr)> fatal_call);
|
||||
@ -88,7 +88,7 @@ namespace g2 {
|
||||
|
||||
|
||||
|
||||
// internal namespace is for completely internal or semi-hidden from the g2 namespace due to that it is unlikely
|
||||
// internal namespace is for completely internal or semi-hidden from the g3 namespace due to that it is unlikely
|
||||
// that you will use these
|
||||
namespace internal {
|
||||
/// @returns true if logger is initialized
|
||||
@ -102,8 +102,8 @@ namespace g2 {
|
||||
void pushMessageToLogger(LogMessagePtr log_entry);
|
||||
|
||||
|
||||
// forwards a FATAL message to all sinks,. after which the g2logworker
|
||||
// will trigger crashhandler / g2::internal::exitWithDefaultSignalHandler
|
||||
// forwards a FATAL message to all sinks,. after which the g3logworker
|
||||
// will trigger crashhandler / g3::internal::exitWithDefaultSignalHandler
|
||||
//
|
||||
// By default the "fatalCall" will forward a Fatalessageptr to this function
|
||||
// this behaviour can be changed if you set a different fatal handler through
|
||||
@ -127,22 +127,22 @@ namespace g2 {
|
||||
bool shutDownLoggingForActiveOnly(LogWorker *active);
|
||||
|
||||
} // internal
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
#define INTERNAL_LOG_MESSAGE(level) LogCapture(__FILE__, __LINE__, __PRETTY_FUNCTION__, level)
|
||||
|
||||
#define INTERNAL_CONTRACT_MESSAGE(boolean_expression) \
|
||||
LogCapture(__FILE__, __LINE__, __PRETTY_FUNCTION__, g2::internal::CONTRACT, boolean_expression)
|
||||
LogCapture(__FILE__, __LINE__, __PRETTY_FUNCTION__, g3::internal::CONTRACT, boolean_expression)
|
||||
|
||||
|
||||
// LOG(level) is the API for the stream log
|
||||
#define LOG(level) if(g2::logLevel(level)) INTERNAL_LOG_MESSAGE(level).stream()
|
||||
#define LOG(level) if(g3::logLevel(level)) INTERNAL_LOG_MESSAGE(level).stream()
|
||||
|
||||
|
||||
// 'Conditional' stream log
|
||||
#define LOG_IF(level, boolean_expression) \
|
||||
if(true == boolean_expression) \
|
||||
if(g2::logLevel(level)) INTERNAL_LOG_MESSAGE(level).stream()
|
||||
if(g3::logLevel(level)) INTERNAL_LOG_MESSAGE(level).stream()
|
||||
|
||||
// 'Design By Contract' stream API. For Broken Contracts:
|
||||
// unit testing: it will throw std::runtime_error when a contract breaks
|
||||
@ -200,12 +200,12 @@ And here is possible output
|
||||
: Width trick: 10
|
||||
: A string \endverbatim */
|
||||
#define LOGF(level, printf_like_message, ...) \
|
||||
if(g2::logLevel(level)) INTERNAL_LOG_MESSAGE(level).capturef(printf_like_message, ##__VA_ARGS__)
|
||||
if(g3::logLevel(level)) INTERNAL_LOG_MESSAGE(level).capturef(printf_like_message, ##__VA_ARGS__)
|
||||
|
||||
// Conditional log printf syntax
|
||||
#define LOGF_IF(level,boolean_expression, printf_like_message, ...) \
|
||||
if(true == boolean_expression) \
|
||||
if(g2::logLevel(level)) INTERNAL_LOG_MESSAGE(level).capturef(printf_like_message, ##__VA_ARGS__)
|
||||
if(g3::logLevel(level)) INTERNAL_LOG_MESSAGE(level).capturef(printf_like_message, ##__VA_ARGS__)
|
||||
|
||||
// Design By Contract, printf-like API syntax with variadic input parameters.
|
||||
// Throws std::runtime_eror if contract breaks
|
||||
|
@ -25,19 +25,19 @@
|
||||
*/
|
||||
struct LogCapture {
|
||||
/// Called from crash handler when a fatal signal has occurred (SIGSEGV etc)
|
||||
LogCapture(const LEVELS &level, g2::SignalType fatal_signal, const char *dump = nullptr);
|
||||
LogCapture(const LEVELS &level, g3::SignalType fatal_signal, const char *dump = nullptr);
|
||||
|
||||
|
||||
/**
|
||||
* @file, line, function are given in g2log.hpp from macros
|
||||
* @file, line, function are given in g3log.hpp from macros
|
||||
* @level INFO/DEBUG/WARNING/FATAL
|
||||
* @expression for CHECK calls
|
||||
* @fatal_signal for failed CHECK:SIGABRT or fatal signal caught in the signal handler
|
||||
*/
|
||||
LogCapture(const char *file, const int line, const char *function, const LEVELS &level, const char *expression = "", g2::SignalType fatal_signal = SIGABRT, const char *dump = nullptr);
|
||||
LogCapture(const char *file, const int line, const char *function, const LEVELS &level, const char *expression = "", g3::SignalType fatal_signal = SIGABRT, const char *dump = nullptr);
|
||||
|
||||
|
||||
// At destruction the message will be forwarded to the g2log worker.
|
||||
// At destruction the message will be forwarded to the g3log worker.
|
||||
// in case of dynamically (at runtime) loaded libraries the important thing to know is that
|
||||
// all strings are copied so the original are not destroyed at the receiving end, only the copy
|
||||
virtual ~LogCapture();
|
||||
@ -67,7 +67,7 @@ struct LogCapture {
|
||||
const char *_function;
|
||||
const LEVELS &_level;
|
||||
const char *_expression;
|
||||
const g2::SignalType _fatal_signal;
|
||||
const g3::SignalType _fatal_signal;
|
||||
|
||||
};
|
||||
//} // g2
|
||||
//} // g3
|
||||
|
@ -45,28 +45,28 @@ struct LEVELS {
|
||||
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
static const int kDebugVaulue = 0;
|
||||
}
|
||||
|
||||
#if (defined(CHANGE_G3LOG_DEBUG_TO_DBUG))
|
||||
const LEVELS DBUG {
|
||||
g2::kDebugVaulue, {"DEBUG"}
|
||||
g3::kDebugVaulue, {"DEBUG"}
|
||||
},
|
||||
#else
|
||||
const LEVELS DEBUG {
|
||||
g2::kDebugVaulue, {"DEBUG"}
|
||||
g3::kDebugVaulue, {"DEBUG"}
|
||||
},
|
||||
#endif
|
||||
INFO {g2::kDebugVaulue + 1, {"INFO"}},
|
||||
INFO {g3::kDebugVaulue + 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"
|
||||
// 2) Remember to update the initialization of "g3loglevels.cpp/g_log_level_status"
|
||||
FATAL {WARNING.value + 1, {"FATAL"}};
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
const LEVELS CONTRACT {
|
||||
100, {"CONTRACT"}
|
||||
@ -75,10 +75,10 @@ namespace g2 {
|
||||
bool wasFatal(const LEVELS &level);
|
||||
}
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
// Enable/Disable a log level {DEBUG,INFO,WARNING,FATAL}
|
||||
void setLogLevel(LEVELS level, bool enabled_status);
|
||||
#endif
|
||||
bool logLevel(LEVELS level);
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
/** LogMessage contains all the data collected from the LOG(...) call.
|
||||
* If the sink receives a std::string it will be the std::string toString()... function
|
||||
@ -103,7 +103,7 @@ namespace g2 {
|
||||
* 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, g2::SignalType signal_id);
|
||||
FatalMessage(const LogMessage &details, g3::SignalType signal_id);
|
||||
FatalMessage(const FatalMessage &);
|
||||
virtual ~FatalMessage() {}
|
||||
|
||||
@ -117,4 +117,4 @@ namespace g2 {
|
||||
typedef MoveOnCopy<std::unique_ptr<FatalMessage>> FatalMessagePtr;
|
||||
typedef MoveOnCopy<std::unique_ptr<LogMessage>> LogMessagePtr;
|
||||
typedef MoveOnCopy<LogMessage> LogMessageMover;
|
||||
} // g2
|
||||
} // g3
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================
|
||||
* Filename:g2logworker.h Framework for Logging and Design By Contract
|
||||
* Filename:g3logworker.h Framework for Logging and Design By Contract
|
||||
* Created: 2011 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
|
||||
@ -24,26 +24,26 @@
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
class LogWorker;
|
||||
struct LogWorkerImpl;
|
||||
|
||||
struct DefaultFileLogger {
|
||||
DefaultFileLogger(const std::string &log_prefix, const std::string &log_directory);
|
||||
std::unique_ptr<LogWorker> worker;
|
||||
std::unique_ptr<g2::SinkHandle<g2::FileSink>> sink;
|
||||
std::unique_ptr<g3::SinkHandle<g3::FileSink>> sink;
|
||||
|
||||
};
|
||||
|
||||
struct LogWorkerImpl final {
|
||||
typedef std::shared_ptr<g2::internal::SinkWrapper> SinkWrapperPtr;
|
||||
typedef std::shared_ptr<g3::internal::SinkWrapper> SinkWrapperPtr;
|
||||
std::vector<SinkWrapperPtr> _sinks;
|
||||
std::unique_ptr<kjellkod::Active> _bg; // do not change declaration order. _bg must be destroyed before sinks
|
||||
|
||||
LogWorkerImpl();
|
||||
~LogWorkerImpl() = default;
|
||||
|
||||
void bgSave(g2::LogMessagePtr msgPtr);
|
||||
void bgSave(g3::LogMessagePtr msgPtr);
|
||||
void bgFatal(FatalMessagePtr msgPtr);
|
||||
|
||||
LogWorkerImpl(const LogWorkerImpl &) = delete;
|
||||
@ -52,7 +52,7 @@ namespace g2 {
|
||||
|
||||
class LogWorker final {
|
||||
LogWorker() = default;
|
||||
void addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> wrapper);
|
||||
void addWrappedSink(std::shared_ptr<g3::internal::SinkWrapper> wrapper);
|
||||
|
||||
LogWorkerImpl _impl;
|
||||
LogWorker(const LogWorker &) = delete;
|
||||
@ -61,7 +61,7 @@ namespace g2 {
|
||||
|
||||
public:
|
||||
~LogWorker();
|
||||
static g2::DefaultFileLogger createWithDefaultLogger(const std::string &log_prefix, const std::string &log_directory);
|
||||
static g3::DefaultFileLogger createWithDefaultLogger(const std::string &log_prefix, const std::string &log_directory);
|
||||
static std::unique_ptr<LogWorker> createWithNoSink();
|
||||
|
||||
|
||||
@ -74,12 +74,12 @@ namespace g2 {
|
||||
void fatal(FatalMessagePtr fatal_message);
|
||||
|
||||
template<typename T, typename DefaultLogCall>
|
||||
std::unique_ptr<g2::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) {
|
||||
using namespace g2;
|
||||
using namespace g2::internal;
|
||||
std::unique_ptr<g3::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) {
|
||||
using namespace g3;
|
||||
using namespace g3::internal;
|
||||
auto sink = std::make_shared<Sink<T>> (std::move(real_sink), call);
|
||||
addWrappedSink(sink);
|
||||
return std2::make_unique<SinkHandle<T>> (sink);
|
||||
}
|
||||
};
|
||||
} // g2
|
||||
} // g3
|
||||
|
@ -7,7 +7,7 @@
|
||||
* ============================================================================*/
|
||||
|
||||
#pragma once
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
// A straightforward technique to move around packaged_tasks.
|
||||
// Instances of std::packaged_task are MoveConstructible and MoveAssignable, but
|
||||
@ -45,4 +45,4 @@ namespace g2 {
|
||||
}
|
||||
};
|
||||
|
||||
} // g2
|
||||
} // g3
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
typedef std::function<void(LogMessageMover) > AsyncMessageCall;
|
||||
|
||||
@ -71,9 +71,9 @@ namespace g2 {
|
||||
|
||||
template<typename Call, typename... Args>
|
||||
auto async(Call call, Args &&... args)-> std::future< typename std::result_of<decltype(call)(T, Args...)>::type> {
|
||||
return g2::spawn_task(std::bind(call, _real_sink.get(), std::forward<Args>(args)...), _bg.get());
|
||||
return g3::spawn_task(std::bind(call, _real_sink.get(), std::forward<Args>(args)...), _bg.get());
|
||||
}
|
||||
};
|
||||
} // internal
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
@ -14,13 +14,13 @@
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
// The Sinkhandle is the client's access point to the specific sink instance.
|
||||
// Only through the Sinkhandle can, and should, the real sink's specific API
|
||||
// be called.
|
||||
//
|
||||
// The real sink will be owned by the g2logger. If the real sink is deleted
|
||||
// The real sink will be owned by the g3logger. If the real sink is deleted
|
||||
// calls to sink's API through the SinkHandle will return an exception embedded
|
||||
// in the resulting future. Ref: SinkHandle::call
|
||||
template<class T>
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "g3log/logmessage.hpp"
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
|
||||
struct SinkWrapper {
|
||||
|
@ -24,11 +24,11 @@
|
||||
|
||||
namespace stacktrace {
|
||||
/// return the text description of a Windows exception code
|
||||
std::string exceptionIdToText(g2::SignalType id);
|
||||
std::string exceptionIdToText(g3::SignalType id);
|
||||
|
||||
/// return whether or not the exception is a known exception, i.e.
|
||||
/// an exception that we should treat as a fatal event
|
||||
bool isKnownException(g2::SignalType id);
|
||||
bool isKnownException(g3::SignalType id);
|
||||
|
||||
/// helper function: retrieve stackdump from no excisting exception pointer
|
||||
std::string stackdump();
|
||||
|
@ -6,11 +6,11 @@
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================
|
||||
* Filename:g2time.h cross-platform, thread-safe replacement for C++11 non-thread-safe
|
||||
* Filename:g3time.h cross-platform, thread-safe replacement for C++11 non-thread-safe
|
||||
* localtime (and similar)
|
||||
* Created: 2012 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not under copywrite protection. First published for g2log at KjellKod.cc
|
||||
* PUBLIC DOMAIN and Not under copywrite protection. First published for g3log at KjellKod.cc
|
||||
* ********************************************* */
|
||||
|
||||
#include <ctime>
|
||||
@ -18,10 +18,10 @@
|
||||
#include <chrono>
|
||||
|
||||
// FYI:
|
||||
// namespace g2::internal ONLY in g2time.cpp
|
||||
// namespace g3::internal ONLY in g3time.cpp
|
||||
// std::string put_time(const struct tm* tmb, const char* c_time_format)
|
||||
|
||||
namespace g2
|
||||
namespace g3
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
@ -37,8 +37,8 @@ namespace g2
|
||||
std::time_t systemtime_now();
|
||||
|
||||
/** return time representing POD struct (ref ctime + wchar) that is normally
|
||||
* retrieved with std::localtime. g2::localtime is threadsafe which std::localtime is not.
|
||||
* g2::localtime is probably used together with @ref g2::systemtime_now */
|
||||
* retrieved with std::localtime. g3::localtime is threadsafe which std::localtime is not.
|
||||
* g3::localtime is probably used together with @ref g3::systemtime_now */
|
||||
tm localtime(const std::time_t &time);
|
||||
|
||||
/** format string must conform to std::put_time's demands.
|
||||
|
@ -13,7 +13,7 @@
|
||||
// signals that must have a signal handler instealled per thread-basis
|
||||
// It is really a royal pain. Seriously Microsoft? Seriously?
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
#define SIGNAL_HANDLER_VERIFY() g2::installSignalHandlerForThread()
|
||||
#define SIGNAL_HANDLER_VERIFY() g3::installSignalHandlerForThread()
|
||||
#else
|
||||
// Does nothing --- enforces that semicolon must be written
|
||||
#define SIGNAL_HANDLER_VERIFY() do {} while(0)
|
||||
@ -25,31 +25,31 @@
|
||||
* captured message is forwarded to background worker.
|
||||
* As a safety precaution: No memory allocated here will be moved into the background
|
||||
* worker in case of dynamic loaded library reasons instead the arguments are copied
|
||||
* inside of g2log.cpp::saveMessage*/
|
||||
* inside of g3log.cpp::saveMessage*/
|
||||
LogCapture::~LogCapture() {
|
||||
using namespace g2::internal;
|
||||
using namespace g3::internal;
|
||||
SIGNAL_HANDLER_VERIFY();
|
||||
saveMessage(_stream.str().c_str(), _file, _line, _function, _level, _expression, _fatal_signal, _stack_trace.c_str());
|
||||
}
|
||||
|
||||
|
||||
/// Called from crash handler when a fatal signal has occurred (SIGSEGV etc)
|
||||
LogCapture::LogCapture(const LEVELS &level, g2::SignalType fatal_signal, const char *dump) : LogCapture("", 0, "", level, "", fatal_signal, dump) {
|
||||
LogCapture::LogCapture(const LEVELS &level, g3::SignalType fatal_signal, const char *dump) : LogCapture("", 0, "", level, "", fatal_signal, dump) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @file, line, function are given in g2log.hpp from macros
|
||||
* @file, line, function are given in g3log.hpp from macros
|
||||
* @level INFO/DEBUG/WARNING/FATAL
|
||||
* @expression for CHECK calls
|
||||
* @fatal_signal for failed CHECK:SIGABRT or fatal signal caught in the signal handler
|
||||
*/
|
||||
LogCapture::LogCapture(const char *file, const int line, const char *function, const LEVELS &level,
|
||||
const char *expression, g2::SignalType fatal_signal, const char *dump)
|
||||
const char *expression, g3::SignalType fatal_signal, const char *dump)
|
||||
: _file(file), _line(line), _function(function), _level(level), _expression(expression), _fatal_signal(fatal_signal) {
|
||||
|
||||
if (g2::internal::wasFatal(level)) {
|
||||
if (g3::internal::wasFatal(level)) {
|
||||
_stack_trace = {"\n*******\tSTACKDUMP *******\n"};
|
||||
_stack_trace.append(g2::internal::stackdump(dump));
|
||||
_stack_trace.append(g3::internal::stackdump(dump));
|
||||
}
|
||||
}
|
||||
|
@ -11,13 +11,13 @@
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
bool wasFatal(const LEVELS &level) {
|
||||
return level.value >= FATAL.value;
|
||||
}
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
// All levels are by default ON: i.e. for DEBUG, INFO, WARNING, FATAL
|
||||
const int g_level_size {
|
||||
FATAL.value + 1
|
||||
@ -26,22 +26,22 @@ namespace g2 {
|
||||
#endif
|
||||
} // internal
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
void setLogLevel(LEVELS log_level, bool enabled) {
|
||||
assert(internal::g_level_size == 4 && "Mismatch between number of logging levels and their use");
|
||||
int level = log_level.value;
|
||||
CHECK((level >= g2::kDebugVaulue) && (level <= FATAL.value));
|
||||
CHECK((level >= g3::kDebugVaulue) && (level <= FATAL.value));
|
||||
internal::g_log_level_status[level].store(enabled, std::memory_order_release);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool logLevel(LEVELS log_level) {
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
int level = log_level.value;
|
||||
CHECK((level >= g2::kDebugVaulue) && (level <= FATAL.value));
|
||||
CHECK((level >= g3::kDebugVaulue) && (level <= FATAL.value));
|
||||
bool status = (internal::g_log_level_status[level].load(std::memory_order_acquire));
|
||||
return status;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
} // g2
|
||||
} // g3
|
@ -34,7 +34,7 @@ namespace {
|
||||
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
|
||||
// helper for setting the normal log details in an entry
|
||||
@ -132,7 +132,7 @@ namespace g2 {
|
||||
|
||||
LogMessage::LogMessage(const std::string &file, const int line,
|
||||
const std::string &function, const LEVELS &level)
|
||||
: _timestamp(g2::systemtime_now())
|
||||
: _timestamp(g3::systemtime_now())
|
||||
, _call_thread_id(std::this_thread::get_id())
|
||||
, _microseconds(microsecondsCounter())
|
||||
, _file(splitFileName(file))
|
||||
@ -180,7 +180,7 @@ namespace g2 {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
FatalMessage::FatalMessage(const LogMessage &details, g2::SignalType signal_id)
|
||||
FatalMessage::FatalMessage(const LogMessage &details, g3::SignalType signal_id)
|
||||
: LogMessage(details), _signal_id(signal_id) { }
|
||||
|
||||
|
||||
@ -198,4 +198,4 @@ namespace g2 {
|
||||
}
|
||||
|
||||
|
||||
} // g2
|
||||
} // g3
|
@ -19,11 +19,11 @@
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
LogWorkerImpl::LogWorkerImpl() : _bg(kjellkod::Active::createActive()) { }
|
||||
|
||||
void LogWorkerImpl::bgSave(g2::LogMessagePtr msgPtr) {
|
||||
void LogWorkerImpl::bgSave(g3::LogMessagePtr msgPtr) {
|
||||
std::unique_ptr<LogMessage> uniqueMsg(std::move(msgPtr.get()));
|
||||
|
||||
for (auto &sink : _sinks) {
|
||||
@ -32,7 +32,7 @@ namespace g2 {
|
||||
}
|
||||
|
||||
if (_sinks.empty()) {
|
||||
std::string err_msg {"g2logworker has no sinks. Message: ["};
|
||||
std::string err_msg {"g3logworker has no sinks. Message: ["};
|
||||
err_msg.append(uniqueMsg.get()->toString()).append({"]\n"});
|
||||
std::cerr << err_msg;
|
||||
}
|
||||
@ -41,7 +41,7 @@ namespace g2 {
|
||||
void LogWorkerImpl::bgFatal(FatalMessagePtr msgPtr) {
|
||||
// this will be the last message. Only the active logworker can receive a FATAL call so it's
|
||||
// safe to shutdown logging now
|
||||
g2::internal::shutDownLogging();
|
||||
g3::internal::shutDownLogging();
|
||||
|
||||
std::string reason = msgPtr.get()->reason();
|
||||
const auto level = msgPtr.get()->_level;
|
||||
@ -71,11 +71,11 @@ namespace g2 {
|
||||
internal::exitWithDefaultSignalHandler(level, fatal_id);
|
||||
|
||||
// should never reach this point
|
||||
perror("g2log exited after receiving FATAL trigger. Flush message status: ");
|
||||
perror("g3log exited after receiving FATAL trigger. Flush message status: ");
|
||||
}
|
||||
|
||||
LogWorker::~LogWorker() {
|
||||
g2::internal::shutDownLoggingForActiveOnly(this);
|
||||
g3::internal::shutDownLoggingForActiveOnly(this);
|
||||
|
||||
// The sinks WILL automatically be cleared at exit of this destructor
|
||||
// However, the waiting below ensures that all messages until this point are taken care of
|
||||
@ -87,7 +87,7 @@ namespace g2 {
|
||||
// *) If it is before the wait below then they will be executed
|
||||
// *) If it is AFTER the wait below then they will be ignored and NEVER executed
|
||||
auto bg_clear_sink_call = [this] { _impl._sinks.clear(); };
|
||||
auto token_cleared = g2::spawn_task(bg_clear_sink_call, _impl._bg.get());
|
||||
auto token_cleared = g3::spawn_task(bg_clear_sink_call, _impl._bg.get());
|
||||
token_cleared.wait();
|
||||
|
||||
// The background worker WILL be automatically cleared at the exit of the destructor
|
||||
@ -101,7 +101,7 @@ namespace g2 {
|
||||
//
|
||||
// If sinks would already have been added after the sink clear above then this reset will deal with it
|
||||
// without risking lambda execution with a partially deconstructed LogWorkerImpl
|
||||
// Calling g2::spawn_task on a nullptr Active object will not crash but return
|
||||
// Calling g3::spawn_task on a nullptr Active object will not crash but return
|
||||
// a future containing an appropriate exception.
|
||||
_impl._bg.reset(nullptr);
|
||||
}
|
||||
@ -114,15 +114,15 @@ namespace g2 {
|
||||
_impl._bg->send([this, fatal_message] {_impl.bgFatal(fatal_message); });
|
||||
}
|
||||
|
||||
void LogWorker::addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> sink) {
|
||||
void LogWorker::addWrappedSink(std::shared_ptr<g3::internal::SinkWrapper> sink) {
|
||||
auto bg_addsink_call = [this, sink] {_impl._sinks.push_back(sink);};
|
||||
auto token_done = g2::spawn_task(bg_addsink_call, _impl._bg.get());
|
||||
auto token_done = g3::spawn_task(bg_addsink_call, _impl._bg.get());
|
||||
token_done.wait();
|
||||
}
|
||||
|
||||
|
||||
g2::DefaultFileLogger LogWorker::createWithDefaultLogger(const std::string &log_prefix, const std::string &log_directory) {
|
||||
return g2::DefaultFileLogger(log_prefix, log_directory);
|
||||
g3::DefaultFileLogger LogWorker::createWithDefaultLogger(const std::string &log_prefix, const std::string &log_directory) {
|
||||
return g3::DefaultFileLogger(log_prefix, log_directory);
|
||||
}
|
||||
|
||||
std::unique_ptr<LogWorker> LogWorker::createWithNoSink() {
|
||||
@ -131,6 +131,6 @@ namespace g2 {
|
||||
|
||||
DefaultFileLogger::DefaultFileLogger(const std::string &log_prefix, const std::string &log_directory)
|
||||
: worker(LogWorker::createWithNoSink())
|
||||
, sink(worker->addSink(std2::make_unique<g2::FileSink>(log_prefix, log_directory), &FileSink::fileWrite)) { }
|
||||
, sink(worker->addSink(std2::make_unique<g3::FileSink>(log_prefix, log_directory), &FileSink::fileWrite)) { }
|
||||
|
||||
} // g2
|
||||
} // g3
|
@ -32,33 +32,33 @@
|
||||
|
||||
|
||||
|
||||
#define g2_MAP_PAIR_STRINGIFY(x) {x, #x}
|
||||
#define g3_MAP_PAIR_STRINGIFY(x) {x, #x}
|
||||
|
||||
namespace {
|
||||
thread_local size_t g_thread_local_recursive_crash_check = 0;
|
||||
|
||||
const std::map<g2::SignalType, std::string> kExceptionsAsText = {
|
||||
g2_MAP_PAIR_STRINGIFY(EXCEPTION_ACCESS_VIOLATION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_ARRAY_BOUNDS_EXCEEDED)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_DATATYPE_MISALIGNMENT)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_DENORMAL_OPERAND)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_DIVIDE_BY_ZERO)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INEXACT_RESULT)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INEXACT_RESULT)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INVALID_OPERATION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_OVERFLOW)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_STACK_CHECK)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_UNDERFLOW)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_IN_PAGE_ERROR)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_INT_DIVIDE_BY_ZERO)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_INT_OVERFLOW)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_INVALID_DISPOSITION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_NONCONTINUABLE_EXCEPTION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_PRIV_INSTRUCTION)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_STACK_OVERFLOW)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_BREAKPOINT)
|
||||
, g2_MAP_PAIR_STRINGIFY(EXCEPTION_SINGLE_STEP)
|
||||
const std::map<g3::SignalType, std::string> kExceptionsAsText = {
|
||||
g3_MAP_PAIR_STRINGIFY(EXCEPTION_ACCESS_VIOLATION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_ARRAY_BOUNDS_EXCEEDED)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_DATATYPE_MISALIGNMENT)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_DENORMAL_OPERAND)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_DIVIDE_BY_ZERO)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INEXACT_RESULT)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INEXACT_RESULT)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_INVALID_OPERATION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_OVERFLOW)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_STACK_CHECK)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_FLT_UNDERFLOW)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_IN_PAGE_ERROR)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_INT_DIVIDE_BY_ZERO)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_INT_OVERFLOW)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_INVALID_DISPOSITION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_NONCONTINUABLE_EXCEPTION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_PRIV_INSTRUCTION)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_STACK_OVERFLOW)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_BREAKPOINT)
|
||||
, g3_MAP_PAIR_STRINGIFY(EXCEPTION_SINGLE_STEP)
|
||||
|
||||
};
|
||||
|
||||
@ -150,7 +150,7 @@ namespace stacktrace {
|
||||
const std::string kUnknown = {"UNKNOWN EXCEPTION"};
|
||||
/// return the text description of a Windows exception code
|
||||
/// From MSDN GetExceptionCode http://msdn.microsoft.com/en-us/library/windows/desktop/ms679356(v=vs.85).aspx
|
||||
std::string exceptionIdToText(g2::SignalType id) {
|
||||
std::string exceptionIdToText(g3::SignalType id) {
|
||||
const auto iter = kExceptionsAsText.find(id);
|
||||
if ( iter == kExceptionsAsText.end()) {
|
||||
std::string unknown = {kUnknown + ":" + std::to_string(id)};
|
||||
@ -162,7 +162,7 @@ namespace stacktrace {
|
||||
/// Yes a double lookup: first for isKnownException and then exceptionIdToText
|
||||
/// for vectored exceptions we only deal with known exceptions so this tiny
|
||||
/// overhead we can live with
|
||||
bool isKnownException(g2::SignalType id) {
|
||||
bool isKnownException(g3::SignalType id) {
|
||||
return (kExceptionsAsText.end() != kExceptionsAsText.find(id));
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
namespace internal {
|
||||
// This mimics the original "std::put_time(const std::tm* tmb, const charT* fmt)"
|
||||
// This is needed since latest version (at time of writing) of gcc4.7 does not implement this library function yet.
|
||||
@ -45,11 +45,11 @@ namespace g2 {
|
||||
#endif
|
||||
}
|
||||
} // internal
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
std::time_t systemtime_now() {
|
||||
system_time_point system_now = std::chrono::system_clock::now();
|
||||
@ -72,6 +72,6 @@ namespace g2 {
|
||||
|
||||
std::string localtime_formatted(const std::time_t &time_snapshot, const std::string &time_format) {
|
||||
std::tm t = localtime(time_snapshot); // could be const, but cannot due to VS2012 is non conformant for C++11's std::put_time (see above)
|
||||
return g2::internal::put_time(&t, time_format.c_str()); // format example: //"%Y/%m/%d %H:%M:%S");
|
||||
return g3::internal::put_time(&t, time_format.c_str()); // format example: //"%Y/%m/%d %H:%M:%S");
|
||||
}
|
||||
} // g2
|
||||
} // g3
|
@ -32,7 +32,7 @@
|
||||
${DIR_PERFORMANCE}/performance.h)
|
||||
# Turn on G3LOG performance flag
|
||||
set_target_properties(g3log-performance-threaded_mean PROPERTIES
|
||||
COMPILE_DEFINITIONS "G2LOG_PERFORMANCE=1")
|
||||
COMPILE_DEFINITIONS "G3LOG_PERFORMANCE=1")
|
||||
target_link_libraries(g3log-performance-threaded_mean
|
||||
${G3LOG_LIBRARY} ${PLATFORM_LINK_LIBRIES})
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
${DIR_PERFORMANCE}/main_threaded_worst.cpp ${DIR_PERFORMANCE}/performance.h)
|
||||
# Turn on G3LOG performance flag
|
||||
set_target_properties(g3log-performance-threaded_worst PROPERTIES
|
||||
COMPILE_DEFINITIONS "G2LOG_PERFORMANCE=1")
|
||||
COMPILE_DEFINITIONS "G3LOG_PERFORMANCE=1")
|
||||
target_link_libraries(g3log-performance-threaded_worst
|
||||
${G3LOG_LIBRARY} ${PLATFORM_LINK_LIBRIES})
|
||||
|
||||
|
@ -6,17 +6,17 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
// through CMakeLists.txt #define of GOOGLE_GLOG_PERFORMANCE and G2LOG_PERFORMANCE
|
||||
// through CMakeLists.txt #define of GOOGLE_GLOG_PERFORMANCE and G3LOG_PERFORMANCE
|
||||
#include "performance.h"
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
const std::string title = "G2LOG";
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
const std::string title = "G3LOG";
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
const std::string title = "GOOGLE__GLOG";
|
||||
#else
|
||||
#error G2LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#error G3LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
@ -24,14 +24,14 @@ const std::string g_path = "./";
|
||||
#else
|
||||
const std::string g_path = "/tmp/";
|
||||
#endif
|
||||
using namespace g2_test;
|
||||
using namespace g3_test;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
std::cerr << "G2_DYNAMIC_LOGGING is enabled" << std::endl;
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
std::cerr << "G3_DYNAMIC_LOGGING is enabled" << std::endl;
|
||||
#else
|
||||
std::cerr << "G2_DYNAMIC_LOGGING is DISABLED" << std::endl;
|
||||
std::cerr << "G3_DYNAMIC_LOGGING is DISABLED" << std::endl;
|
||||
#endif
|
||||
|
||||
size_t number_of_threads = 0;
|
||||
@ -59,9 +59,9 @@ int main(int argc, char **argv)
|
||||
writeTextToFile(g_measurement_dump, oss.str(), kAppend);
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g2::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g2::initializeLogging(logger_n_handle.worker.get());
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
@ -86,7 +86,7 @@ int main(int argc, char **argv)
|
||||
auto application_end_time = std::chrono::high_resolution_clock::now();
|
||||
delete [] threads;
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
logger_n_handle.worker.reset(); // will flush anything in the queue to file
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::ShutdownGoogleLogging();
|
||||
|
@ -6,7 +6,7 @@
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
// through CMakeLists.txt #define of GOOGLE_GLOG_PERFORMANCE and G2LOG_PERFORMANCE
|
||||
// through CMakeLists.txt #define of GOOGLE_GLOG_PERFORMANCE and G3LOG_PERFORMANCE
|
||||
#include "performance.h"
|
||||
|
||||
#include <thread>
|
||||
@ -15,16 +15,16 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
const std::string title {
|
||||
"G2LOG"
|
||||
"G3LOG"
|
||||
};
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
const std::string title {
|
||||
"GOOGLE__GLOG"
|
||||
};
|
||||
#else
|
||||
#error G2LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#error G3LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#endif
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ const std::string g_path {
|
||||
|
||||
|
||||
|
||||
using namespace g2_test;
|
||||
using namespace g3_test;
|
||||
|
||||
|
||||
//
|
||||
@ -83,9 +83,9 @@ int main(int argc, char** argv)
|
||||
writeTextToFile(g_measurement_dump, oss.str(), kAppend);
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g2::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g2::initializeLogging(logger_n_handle.worker.get());
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
@ -119,7 +119,7 @@ int main(int argc, char** argv)
|
||||
delete [] threads;
|
||||
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
logger_n_handle.worker.reset(); // will flush anything in the queue to file
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::ShutdownGoogleLogging();
|
||||
|
@ -19,21 +19,22 @@
|
||||
#include <chrono>
|
||||
#include <cassert>
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
#include "g2log.hpp"
|
||||
using namespace g2::internal;
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
using namespace g3::internal;
|
||||
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
#include <glog/logging.h>
|
||||
#else
|
||||
#error G2LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#error G3LOG_PERFORMANCE or GOOGLE_GLOG_PERFORMANCE was not defined
|
||||
#endif
|
||||
|
||||
typedef std::chrono::high_resolution_clock::time_point time_point;
|
||||
typedef std::chrono::duration<uint64_t,std::ratio<1, 1000> > millisecond;
|
||||
typedef std::chrono::duration<uint64_t,std::ratio<1, 1000000> > microsecond;
|
||||
|
||||
namespace g2_test
|
||||
namespace g3_test
|
||||
{
|
||||
enum WriteMode
|
||||
{
|
||||
@ -86,8 +87,8 @@ inline void measurePeakDuringLogWrites(const std::string& title, std::vector<uin
|
||||
{
|
||||
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
std::cout << "G2LOG (" << title << ") WORST_PEAK PERFORMANCE TEST" << std::endl;
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
std::cout << "G3LOG (" << title << ") WORST_PEAK PERFORMANCE TEST" << std::endl;
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
std::cout << "GOOGLE_GLOG (" << title << ") WORST_PEAK PERFORMANCE TEST" << std::endl;
|
||||
#else
|
||||
@ -108,8 +109,8 @@ inline void measurePeakDuringLogWrites(const std::string& title, std::vector<uin
|
||||
void doLogWrites(const std::string& title);
|
||||
inline void doLogWrites(const std::string& title)
|
||||
{
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
std::cout << "G2LOG (" << title << ") PERFORMANCE TEST" << std::endl;
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
std::cout << "G3LOG (" << title << ") PERFORMANCE TEST" << std::endl;
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
std::cout << "GOOGLE_GLOG (" << title << ") PERFORMANCE TEST" << std::endl;
|
||||
#else
|
||||
|
@ -35,14 +35,14 @@ class CoutSink {
|
||||
public:
|
||||
void clear() { buffer.str(""); }
|
||||
std::string string() { return buffer.str(); }
|
||||
void save(g2::LogMessageMover msg) { std::cout << msg.get().message(); }
|
||||
void save(g3::LogMessageMover msg) { std::cout << msg.get().message(); }
|
||||
virtual ~CoutSink() final {}
|
||||
static std::unique_ptr<CoutSink> createSink() { return std::unique_ptr<CoutSink>(new CoutSink);}
|
||||
};
|
||||
|
||||
struct StringSink {
|
||||
std::string raw;
|
||||
void append(g2::LogMessageMover entry) { raw.append(entry.get().message());}
|
||||
void append(g3::LogMessageMover entry) { raw.append(entry.get().message());}
|
||||
std::string string() {
|
||||
return raw;
|
||||
}
|
||||
@ -50,10 +50,10 @@ struct StringSink {
|
||||
|
||||
|
||||
namespace {
|
||||
typedef std::shared_ptr<g2::internal::SinkWrapper> SinkWrapperPtr;
|
||||
typedef std::shared_ptr<g3::internal::SinkWrapper> SinkWrapperPtr;
|
||||
}
|
||||
|
||||
namespace g2 {
|
||||
namespace g3 {
|
||||
|
||||
class Worker {
|
||||
std::vector<SinkWrapperPtr> _container; // should be hidden in a pimple with a bg active object
|
||||
@ -61,7 +61,7 @@ namespace g2 {
|
||||
|
||||
void bgSave(std::string msg) {
|
||||
for (auto& sink : _container) {
|
||||
g2::LogMessage message("test", 0, "test", DEBUG);
|
||||
g3::LogMessage message("test", 0, "test", DEBUG);
|
||||
message.write().append(msg);
|
||||
sink->send(LogMessageMover(std::move(message)));
|
||||
}
|
||||
@ -89,7 +89,7 @@ namespace g2 {
|
||||
std::unique_ptr< SinkHandle<T> > addSink(std::unique_ptr<T> unique, DefaultLogCall call) {
|
||||
auto sink = std::make_shared < internal::Sink<T> > (std::move(unique), call);
|
||||
auto add_sink_call = [this, sink] { _container.push_back(sink); };
|
||||
auto wait_result = g2::spawn_task(add_sink_call, _bg.get());
|
||||
auto wait_result = g3::spawn_task(add_sink_call, _bg.get());
|
||||
wait_result.wait();
|
||||
|
||||
auto handle = std2::make_unique< SinkHandle<T> >(sink);
|
||||
@ -97,13 +97,13 @@ namespace g2 {
|
||||
}
|
||||
};
|
||||
|
||||
} // g2
|
||||
} // g3
|
||||
|
||||
|
||||
|
||||
|
||||
using namespace g2;
|
||||
using namespace g2::internal;
|
||||
using namespace g3;
|
||||
using namespace g3::internal;
|
||||
|
||||
TEST(ConceptSink, CreateHandle) {
|
||||
Worker worker;
|
||||
@ -196,7 +196,7 @@ TEST(Sink, OneSink) {
|
||||
AtomicBoolPtr flag = make_shared<atomic<bool>>(false);
|
||||
AtomicIntPtr count = make_shared<atomic<int>>(0);
|
||||
{
|
||||
auto worker = std::make_shared<g2LogWorker>();
|
||||
auto worker = std::make_shared<g3LogWorker>();
|
||||
worker->addSink(std2::make_unique<ScopedSetTrue>(flag, count), &ScopedSetTrue::ReceiveMsg);
|
||||
worker->save("this message should trigger an atomic increment at the sink");
|
||||
|
||||
@ -211,7 +211,7 @@ TEST(Sink, OneSinkWithHandleOutOfScope) {
|
||||
AtomicBoolPtr flag = make_shared<atomic<bool>>(false);
|
||||
AtomicIntPtr count = make_shared<atomic<int>>(0);
|
||||
{
|
||||
auto worker = std::make_shared<g2LogWorker>();
|
||||
auto worker = std::make_shared<g3LogWorker>();
|
||||
{
|
||||
auto handle = worker->addSink(std2::make_unique<ScopedSetTrue>(flag, count), &ScopedSetTrue::ReceiveMsg);
|
||||
}
|
||||
@ -238,7 +238,7 @@ TEST(Sink, OneHundredSinks) {
|
||||
}
|
||||
|
||||
{
|
||||
auto worker = std::make_shared<g2LogWorker>();
|
||||
auto worker = std::make_shared<g3LogWorker>();
|
||||
size_t index = 0;
|
||||
for (auto& flag : flags) {
|
||||
auto& count = counts[index++];
|
||||
|
@ -27,14 +27,14 @@ TEST(Configuration, LOG)
|
||||
// --- the last example is such an example.
|
||||
try
|
||||
{
|
||||
std::cout << g2::localtime_formatted(g2::systemtime_now(), "%a %b %d %H:%M:%S %Y") << std::endl;
|
||||
std::cout << g3::localtime_formatted(g3::systemtime_now(), "%a %b %d %H:%M:%S %Y") << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
std::cout << g2::localtime_formatted(g2::systemtime_now(), "%%Y/%%m/%%d %%H:%%M:%%S = %Y/%m/%d %H:%M:%S") << std::endl;
|
||||
std::cout << g3::localtime_formatted(g3::systemtime_now(), "%%Y/%%m/%%d %%H:%%M:%%S = %Y/%m/%d %H:%M:%S") << std::endl;
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
std::cerr << "Formatting options skipped due to VS2012, C++11 non-conformance for" << std::endl;
|
||||
std::cerr << " some formatting options. The skipped code was:\n\t\t %EX %Ec, \n(see http://en.cppreference.com/w/cpp/io/manip/put_time for details)" << std::endl;
|
||||
#else
|
||||
std::cout << "C++11 new formatting options:\n" << g2::localtime_formatted(g2::systemtime_now(), "%%EX: %EX\n%%z: %z\n%%Ec: %Ec") << std::endl;
|
||||
std::cout << "C++11 new formatting options:\n" << g3::localtime_formatted(g3::systemtime_now(), "%%EX: %EX\n%%z: %z\n%%Ec: %Ec") << std::endl;
|
||||
#endif
|
||||
}
|
||||
// This does not work. Other kinds of fatal exits (on Windows) seems to be used instead of exceptions
|
||||
@ -77,7 +77,7 @@ TEST(TestOf_CopyableCall, Expecting_SmoothSailing)
|
||||
MsgType type(str);
|
||||
std::unique_ptr<Active> bgWorker(Active::createActive());
|
||||
std::future<std::string> fstring =
|
||||
g2::spawn_task(std::bind(&MsgType::msg, type), bgWorker.get());
|
||||
g3::spawn_task(std::bind(&MsgType::msg, type), bgWorker.get());
|
||||
ASSERT_STREQ(str.c_str(), fstring.get().c_str());
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ TEST(TestOf_CopyableLambdaCall, Expecting_AllFine)
|
||||
auto msg_lambda=[=](){return (str_standalone+str_standalone);};
|
||||
std::string expected(str_standalone+str_standalone);
|
||||
|
||||
auto fstring_standalone = g2::spawn_task(msg_lambda, bgWorker.get());
|
||||
auto fstring_standalone = g3::spawn_task(msg_lambda, bgWorker.get());
|
||||
ASSERT_STREQ(expected.c_str(), fstring_standalone.get().c_str());
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ std::future<typename std::result_of<F()>::type> ObsoleteSpawnTask(F f)
|
||||
std::future<result_type> result = task.get_future();
|
||||
|
||||
std::vector<std::function<void()>> vec;
|
||||
vec.push_back(g2::MoveOnCopy<task_type>(std::move(task)));
|
||||
vec.push_back(g3::MoveOnCopy<task_type>(std::move(task)));
|
||||
std::thread(std::move(vec.back())).detach();
|
||||
result.wait();
|
||||
return std::move(result);
|
||||
@ -133,7 +133,7 @@ TEST(TestOf_ObsoleteSpawnTaskWithStringReturn, Expecting_FutureString)
|
||||
// --------------------------------------------------------------
|
||||
namespace WORKING
|
||||
{
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
@ -175,7 +175,7 @@ namespace WORKING
|
||||
return 42.2;
|
||||
}
|
||||
|
||||
std::string msg2(){return "msg2";}
|
||||
std::string msg3(){return "msg3";}
|
||||
} // WORKING
|
||||
|
||||
TEST(Yalla, Testar)
|
||||
@ -184,7 +184,7 @@ TEST(Yalla, Testar)
|
||||
auto f = spawn_task(get_res);
|
||||
std::cout << "Res = " << f.get() << std::endl;
|
||||
|
||||
auto f2 = spawn_task(msg2);
|
||||
auto f2 = spawn_task(msg3);
|
||||
std::cout << "Res2 = " << f2.get() << std::endl;
|
||||
|
||||
|
||||
|
@ -26,8 +26,8 @@ using namespace testing_helpers;
|
||||
|
||||
namespace { // anonymous
|
||||
const char* name_path_1 = "./some_fake_DirectoryOrName_1_";
|
||||
g2::LogWorker* g_logger_ptr = nullptr;
|
||||
g2::SinkHandle<g2::FileSink>* g_filesink_handler = nullptr;
|
||||
g3::LogWorker* g_logger_ptr = nullptr;
|
||||
g3::SinkHandle<g3::FileSink>* g_filesink_handler = nullptr;
|
||||
LogFileCleaner* g_cleaner_ptr = nullptr;
|
||||
|
||||
std::string setLogNameAndAddCount(std::string new_file_to_create) {
|
||||
@ -37,7 +37,7 @@ namespace { // anonymous
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
{
|
||||
add_count = std::to_string(++count) + "_";
|
||||
auto future_new_log = g_filesink_handler->call(&g2::FileSink::changeLogFile, new_file_to_create + add_count);
|
||||
auto future_new_log = g_filesink_handler->call(&g3::FileSink::changeLogFile, new_file_to_create + add_count);
|
||||
auto new_log = future_new_log.get();
|
||||
if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log);
|
||||
return new_log;
|
||||
@ -46,14 +46,14 @@ namespace { // anonymous
|
||||
}
|
||||
|
||||
std::string setLogName(std::string new_file_to_create) {
|
||||
auto future_new_log = g_filesink_handler->call(&g2::FileSink::changeLogFile, new_file_to_create);
|
||||
auto future_new_log = g_filesink_handler->call(&g3::FileSink::changeLogFile, new_file_to_create);
|
||||
auto new_log = future_new_log.get();
|
||||
if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log);
|
||||
return new_log;
|
||||
}
|
||||
|
||||
std::string getLogName() {
|
||||
return g_filesink_handler->call(&g2::FileSink::fileName).get();
|
||||
return g_filesink_handler->call(&g3::FileSink::fileName).get();
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
@ -73,7 +73,7 @@ TEST(TestOf_ChangingLogFile, Expecting_NewLogFileUsed) {
|
||||
}
|
||||
|
||||
TEST(TestOf_ManyThreadsChangingLogFileName, Expecting_EqualNumberLogsCreated) {
|
||||
auto old_log = g_filesink_handler->call(&g2::FileSink::fileName).get();
|
||||
auto old_log = g_filesink_handler->call(&g3::FileSink::fileName).get();
|
||||
if (!old_log.empty()) g_cleaner_ptr->addLogToClean(old_log);
|
||||
|
||||
LOG(INFO) << "SoManyThreadsAllDoingChangeFileName";
|
||||
@ -111,22 +111,22 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
testing_helpers::ScopedOut scopedCerr(std::cerr, &cerrDump);
|
||||
|
||||
auto logger = g2::LogWorker::createWithDefaultLogger("ReplaceLogFile", name_path_1);
|
||||
auto logger = g3::LogWorker::createWithDefaultLogger("ReplaceLogFile", name_path_1);
|
||||
g_logger_ptr = logger.worker.get();
|
||||
g_filesink_handler = logger.sink.get();
|
||||
last_log_file = g_filesink_handler->call(&g2::FileSink::fileName).get();
|
||||
last_log_file = g_filesink_handler->call(&g3::FileSink::fileName).get();
|
||||
cleaner.addLogToClean(last_log_file);
|
||||
|
||||
|
||||
g2::initializeLogging(g_logger_ptr);
|
||||
g3::initializeLogging(g_logger_ptr);
|
||||
LOG(INFO) << "test_filechange demo*" << std::endl;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return_value = RUN_ALL_TESTS();
|
||||
|
||||
last_log_file = g_filesink_handler->call(&g2::FileSink::fileName).get();
|
||||
last_log_file = g_filesink_handler->call(&g3::FileSink::fileName).get();
|
||||
std::cout << "log file at: " << last_log_file << std::endl;
|
||||
//g2::shutDownLogging();
|
||||
//g3::shutDownLogging();
|
||||
}
|
||||
std::cout << "FINISHED WITH THE TESTING" << std::endl;
|
||||
// cleaning up
|
||||
|
@ -23,9 +23,9 @@ 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_debug2 = "test DEBUG 1.123456";
|
||||
const std::string t_debug3 = "test DEBUG 1.123456";
|
||||
const std::string t_warning = "test WARNING ";
|
||||
const std::string t_warning2 = "test WARNING yello";
|
||||
const std::string t_warning3 = "test WARNING yello";
|
||||
|
||||
std::atomic<size_t> g_fatal_counter = {0};
|
||||
void fatalCounter() {
|
||||
@ -44,13 +44,13 @@ using namespace testing_helpers;
|
||||
///
|
||||
/// TODO : (gtest issue)
|
||||
///Move out to separate unit test binary to ensure reordering of tests does not happen
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_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_FALSE(g3::internal::isLoggingInitialized());
|
||||
EXPECT_TRUE(g3::logLevel(DEBUG));
|
||||
EXPECT_TRUE(g3::logLevel(INFO));
|
||||
EXPECT_TRUE(g3::logLevel(WARNING));
|
||||
EXPECT_TRUE(g3::logLevel(FATAL));
|
||||
EXPECT_EQ(DEBUG.value, 0);
|
||||
EXPECT_EQ(INFO.value, 1);
|
||||
EXPECT_EQ(WARNING.value, 2);
|
||||
@ -58,16 +58,16 @@ TEST(Initialization, No_Logger_Initialized___LevelsAreONByDefault) {
|
||||
}
|
||||
|
||||
TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKish) {
|
||||
EXPECT_FALSE(g2::internal::isLoggingInitialized());
|
||||
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";
|
||||
EXPECT_FALSE(g3::internal::isLoggingInitialized());
|
||||
EXPECT_TRUE(g3::logLevel(INFO));
|
||||
EXPECT_TRUE(g3::logLevel(FATAL));
|
||||
EXPECT_TRUE(g3::logLevel(DEBUG));
|
||||
EXPECT_TRUE(g3::logLevel(WARNING));
|
||||
std::string err_msg1 = "Hey. I am not instantiated but I still should not crash. (I am g3logger)";
|
||||
std::string err_msg3_ignored = "This uninitialized message should be ignored";
|
||||
try {
|
||||
LOG(INFO) << err_msg1; // nothing happened. level not ON
|
||||
LOG(INFO) << err_msg2_ignored; // nothing happened. level not ON
|
||||
LOG(INFO) << err_msg3_ignored; // nothing happened. level not ON
|
||||
|
||||
} catch (std::exception& e) {
|
||||
ADD_FAILURE() << "Should never have thrown even if it is not instantiated. Ignored exception: " << e.what();
|
||||
@ -79,22 +79,22 @@ TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKi
|
||||
LOG(INFO) << good_msg1;
|
||||
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_msg2_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg3_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
}
|
||||
#else
|
||||
TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKish) {
|
||||
EXPECT_FALSE(g2::internal::isLoggingInitialized());
|
||||
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";
|
||||
EXPECT_FALSE(g3::internal::isLoggingInitialized());
|
||||
EXPECT_TRUE(g3::logLevel(INFO));
|
||||
EXPECT_TRUE(g3::logLevel(FATAL));
|
||||
EXPECT_TRUE(g3::logLevel(DEBUG));
|
||||
EXPECT_TRUE(g3::logLevel(WARNING));
|
||||
std::string err_msg1 = "Hey. I am not instantiated but I still should not crash. (I am g3logger)";
|
||||
std::string err_msg3_ignored = "This uninitialized message should be ignored";
|
||||
|
||||
try {
|
||||
LOG(INFO) << err_msg1;
|
||||
LOG(INFO) << err_msg2_ignored;
|
||||
LOG(INFO) << err_msg3_ignored;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
ADD_FAILURE() << "Should never have thrown even if it is not instantiated: " << e.what();
|
||||
@ -106,10 +106,10 @@ TEST(Initialization, No_Logger_Initialized___Expecting_LOG_calls_to_be_Still_OKi
|
||||
LOG(INFO) << good_msg1;
|
||||
auto content = logger.resetAndRetrieveContent(); // this synchronizes with the LOG(INFO) call.
|
||||
ASSERT_TRUE(verifyContent(content, err_msg1)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg2_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_FALSE(verifyContent(content, err_msg3_ignored)) << "Content: [" << content << "]";
|
||||
ASSERT_TRUE(verifyContent(content, good_msg1)) << "Content: [" << content << "]";
|
||||
}
|
||||
#endif // #ifdef G2_DYNAMIC_LOGGING
|
||||
#endif // #ifdef G3_DYNAMIC_LOGGING
|
||||
|
||||
|
||||
TEST(Basics, Shutdown) {
|
||||
@ -132,7 +132,7 @@ TEST(Basics, Shutdownx2) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOG(INFO) << "Not yet shutdown. This message should make it";
|
||||
logger.reset(); // force flush of logger (which will trigger a shutdown)
|
||||
g2::internal::shutDownLogging(); // already called in reset, but safe to call again
|
||||
g3::internal::shutDownLogging(); // already called in reset, but safe to call again
|
||||
LOG(INFO) << "Logger is shutdown,. this message will not make it (but it's safe to try)";
|
||||
file_content = readFileToText(logger.logFile()); // already reset
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
@ -146,7 +146,7 @@ TEST(Basics, ShutdownActiveLogger) {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOG(INFO) << "Not yet shutdown. This message should make it";
|
||||
EXPECT_TRUE(g2::internal::shutDownLoggingForActiveOnly(logger._scope->get()));
|
||||
EXPECT_TRUE(g3::internal::shutDownLoggingForActiveOnly(logger._scope->get()));
|
||||
LOG(INFO) << "Logger is shutdown,. this message will not make it (but it's safe to try)";
|
||||
file_content = logger.resetAndRetrieveContent();
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
@ -160,8 +160,8 @@ TEST(Basics, DoNotShutdownActiveLogger) {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOG(INFO) << "Not yet shutdown. This message should make it";
|
||||
std::unique_ptr<g2::LogWorker> duplicateLogWorker{g2::LogWorker::createWithNoSink()};
|
||||
EXPECT_FALSE(g2::internal::shutDownLoggingForActiveOnly(duplicateLogWorker.get()));
|
||||
std::unique_ptr<g3::LogWorker> duplicateLogWorker{g3::LogWorker::createWithNoSink()};
|
||||
EXPECT_FALSE(g3::internal::shutDownLoggingForActiveOnly(duplicateLogWorker.get()));
|
||||
LOG(INFO) << "Logger is (NOT) shutdown,. this message WILL make it";
|
||||
file_content = logger.resetAndRetrieveContent();
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
@ -175,16 +175,16 @@ TEST(LOGTest, LOG) {
|
||||
std::string file_content;
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
EXPECT_TRUE(g2::logLevel(INFO));
|
||||
EXPECT_TRUE(g2::logLevel(FATAL));
|
||||
EXPECT_TRUE(g3::logLevel(INFO));
|
||||
EXPECT_TRUE(g3::logLevel(FATAL));
|
||||
LOG(INFO) << "test LOG(INFO)";
|
||||
logger.reset(); // force flush of logger
|
||||
file_content = readFileToText(logger.logFile());
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
}
|
||||
EXPECT_TRUE(verifyContent(file_content, "test LOG(INFO)"));
|
||||
EXPECT_TRUE(g2::logLevel(INFO));
|
||||
EXPECT_TRUE(g2::logLevel(FATAL));
|
||||
EXPECT_TRUE(g3::logLevel(INFO));
|
||||
EXPECT_TRUE(g3::logLevel(FATAL));
|
||||
}
|
||||
|
||||
|
||||
@ -206,8 +206,8 @@ TEST(LogTest, LOG_F) {
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
}
|
||||
ASSERT_TRUE(verifyContent(file_content, t_info2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_debug2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_warning2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_debug3));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_warning3));
|
||||
}
|
||||
|
||||
|
||||
@ -226,8 +226,8 @@ TEST(LogTest, LOG) {
|
||||
SCOPED_TRACE("LOG_INFO"); // Scope exit be prepared for destructor failure
|
||||
}
|
||||
ASSERT_TRUE(verifyContent(file_content, t_info2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_debug2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_warning2));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_debug3));
|
||||
ASSERT_TRUE(verifyContent(file_content, t_warning3));
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@ TEST(LogTest, LOG_F_IF) {
|
||||
SCOPED_TRACE("LOG_IF"); // Scope exit be prepared for destructor failure
|
||||
}
|
||||
ASSERT_TRUE(verifyContent(file_content, t_info2));
|
||||
ASSERT_FALSE(verifyContent(file_content, t_debug2));
|
||||
ASSERT_FALSE(verifyContent(file_content, t_debug3));
|
||||
}
|
||||
|
||||
|
||||
@ -257,7 +257,7 @@ TEST(LogTest, LOG_IF) {
|
||||
SCOPED_TRACE("LOG_IF"); // Scope exit be prepared for destructor failure
|
||||
}
|
||||
EXPECT_TRUE(verifyContent(file_content, t_info2));
|
||||
EXPECT_FALSE(verifyContent(file_content, t_debug2));
|
||||
EXPECT_FALSE(verifyContent(file_content, t_debug3));
|
||||
}
|
||||
TEST(LogTest, LOGF__FATAL) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
@ -279,7 +279,7 @@ TEST(LogTest, LOG_preFatalLogging_hook) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_FALSE(mockFatalWasCalled());
|
||||
g_fatal_counter.store(0);
|
||||
g2::setFatalPreLoggingHook(fatalCounter);
|
||||
g3::setFatalPreLoggingHook(fatalCounter);
|
||||
LOG(FATAL) << "This message is fatal";
|
||||
logger.reset();
|
||||
EXPECT_EQ(g_fatal_counter.load(), size_t{1});
|
||||
@ -373,11 +373,11 @@ TEST(CheckTest, CHECK_F__thisWILL_PrintErrorMsg) {
|
||||
TEST(CHECK_F_Test, CHECK_F__thisWILL_PrintErrorMsg) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
std::string msg = "This message is added to throw %s and %s";
|
||||
std::string msg2 = "This message is added to throw message and log";
|
||||
std::string msg3 = "This message is added to throw message and log";
|
||||
std::string arg1 = "message";
|
||||
std::string arg2 = "log";
|
||||
std::string arg3 = "log";
|
||||
|
||||
CHECK_F(1 >= 2, msg.c_str(), arg1.c_str(), arg2.c_str());
|
||||
CHECK_F(1 >= 2, msg.c_str(), arg1.c_str(), arg3.c_str());
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), "EXIT trigger caused by "));
|
||||
@ -388,23 +388,23 @@ TEST(CHECK_F_Test, CHECK_F__thisWILL_PrintErrorMsg) {
|
||||
TEST(CHECK_Test, CHECK__thisWILL_PrintErrorMsg) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
std::string msg = "This message is added to throw %s and %s";
|
||||
std::string msg2 = "This message is added to throw message and log";
|
||||
std::string msg3 = "This message is added to throw message and log";
|
||||
std::string arg1 = "message";
|
||||
std::string arg2 = "log";
|
||||
CHECK(1 >= 2) << msg2;
|
||||
std::string arg3 = "log";
|
||||
CHECK(1 >= 2) << msg3;
|
||||
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), "EXIT trigger caused by "));
|
||||
EXPECT_TRUE(verifyContent(file_content, "CONTRACT"));
|
||||
EXPECT_TRUE(verifyContent(file_content, msg2));
|
||||
EXPECT_TRUE(verifyContent(file_content, msg3));
|
||||
}
|
||||
TEST(CHECK, CHECK_ThatWontThrow) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
std::string msg = "This %s should never appear in the %s";
|
||||
std::string msg2 = "This message should never appear in the log";
|
||||
std::string msg3 = "This message should never appear in the log";
|
||||
std::string arg1 = "message";
|
||||
std::string arg2 = "log";
|
||||
std::string arg3 = "log";
|
||||
|
||||
CHECK(1 == 1);
|
||||
CHECK_F(1 == 1, msg.c_str(), "message", "log");
|
||||
@ -412,15 +412,15 @@ TEST(CHECK, CHECK_ThatWontThrow) {
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
|
||||
std::string file_content = readFileToText(logger.logFile());
|
||||
EXPECT_FALSE(verifyContent(file_content, msg2));
|
||||
EXPECT_FALSE(verifyContent(mockFatalMessage(), msg2));
|
||||
EXPECT_FALSE(verifyContent(file_content, msg3));
|
||||
EXPECT_FALSE(verifyContent(mockFatalMessage(), msg3));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef G2_DYNAMIC_LOGGING
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
namespace {
|
||||
// Restore dynamic levels if turned off
|
||||
|
||||
@ -428,51 +428,51 @@ namespace {
|
||||
RestoreDynamicLoggingLevels() {
|
||||
};
|
||||
~RestoreDynamicLoggingLevels() {
|
||||
g2::setLogLevel(DEBUG, false);
|
||||
g2::setLogLevel(INFO, false);
|
||||
g2::setLogLevel(WARNING, false);
|
||||
g2::setLogLevel(FATAL, false);
|
||||
g3::setLogLevel(DEBUG, false);
|
||||
g3::setLogLevel(INFO, false);
|
||||
g3::setLogLevel(WARNING, false);
|
||||
g3::setLogLevel(FATAL, false);
|
||||
}
|
||||
};
|
||||
} // anonymous
|
||||
TEST(DynamicLogging, DynamicLogging_IS_ENABLED) {
|
||||
RestoreDynamicLoggingLevels raiiLevelRestore;
|
||||
|
||||
ASSERT_TRUE(g2::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g2::logLevel(INFO));
|
||||
ASSERT_TRUE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
g2::setLogLevel(DEBUG, false);
|
||||
ASSERT_FALSE(g2::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g2::logLevel(INFO));
|
||||
ASSERT_TRUE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
g3::setLogLevel(DEBUG, false);
|
||||
ASSERT_FALSE(g3::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
|
||||
g2::setLogLevel(INFO, false);
|
||||
ASSERT_FALSE(g2::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g2::logLevel(INFO));
|
||||
ASSERT_TRUE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
g3::setLogLevel(INFO, false);
|
||||
ASSERT_FALSE(g3::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
|
||||
g2::setLogLevel(WARNING, false);
|
||||
ASSERT_FALSE(g2::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g2::logLevel(INFO));
|
||||
ASSERT_FALSE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
g3::setLogLevel(WARNING, false);
|
||||
ASSERT_FALSE(g3::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g3::logLevel(INFO));
|
||||
ASSERT_FALSE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
|
||||
g2::setLogLevel(FATAL, false);
|
||||
ASSERT_FALSE(g2::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g2::logLevel(INFO));
|
||||
ASSERT_FALSE(g2::logLevel(WARNING));
|
||||
ASSERT_FALSE(g2::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
g3::setLogLevel(FATAL, false);
|
||||
ASSERT_FALSE(g3::logLevel(DEBUG));
|
||||
ASSERT_FALSE(g3::logLevel(INFO));
|
||||
ASSERT_FALSE(g3::logLevel(WARNING));
|
||||
ASSERT_FALSE(g3::logLevel(FATAL)); // Yes FATAL can be turned off. Thereby rendering it ineffective.
|
||||
}
|
||||
TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
ASSERT_TRUE(g2::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g2::logLevel(INFO));
|
||||
ASSERT_TRUE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL));
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL));
|
||||
}
|
||||
|
||||
RestoreDynamicLoggingLevels raiiLevelRestore;
|
||||
@ -490,8 +490,8 @@ TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
g2::setLogLevel(DEBUG, false);
|
||||
EXPECT_FALSE(g2::logLevel(DEBUG));
|
||||
g3::setLogLevel(DEBUG, false);
|
||||
EXPECT_FALSE(g3::logLevel(DEBUG));
|
||||
LOG(DEBUG) << msg_debugOff;
|
||||
auto content = logger.resetAndRetrieveContent();
|
||||
ASSERT_FALSE(verifyContent(content, "This message should never appear in the log")) << "Content: [" << content << "]";
|
||||
@ -505,10 +505,10 @@ TEST(DynamicLogging, DynamicLogging_No_Logs_If_Disabled) {
|
||||
TEST(DynamicLogging, DynamicLogging_No_Fatal_If_Disabled) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
RestoreDynamicLoggingLevels raiiLevelRestore;
|
||||
ASSERT_TRUE(g2::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g2::logLevel(INFO));
|
||||
ASSERT_TRUE(g2::logLevel(WARNING));
|
||||
ASSERT_TRUE(g2::logLevel(FATAL));
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(INFO));
|
||||
ASSERT_TRUE(g3::logLevel(WARNING));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL));
|
||||
|
||||
std::string msg1 = "This IS fatal (not crash, since it is unit test";
|
||||
|
||||
@ -521,9 +521,9 @@ TEST(DynamicLogging, DynamicLogging_No_Fatal_If_Disabled) {
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
|
||||
|
||||
g2::setLogLevel(FATAL, false);
|
||||
std::string msg2 = "This is NOT fatal (not crash, since it is unit test. FATAL is disabled";
|
||||
LOG(FATAL) << msg2;
|
||||
g3::setLogLevel(FATAL, false);
|
||||
std::string msg3 = "This is NOT fatal (not crash, since it is unit test. FATAL is disabled";
|
||||
LOG(FATAL) << msg3;
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
EXPECT_TRUE(mockFatalMessage().empty());
|
||||
}
|
||||
@ -532,10 +532,10 @@ TEST(DynamicLogging, DynamicLogging_No_Fatal_If_Disabled) {
|
||||
TEST(DynamicLogging, DynamicLogging_Check_WillAlsoBeTurnedOffWhen_Fatal_Is_Disabled) {
|
||||
RestoreFileLogger logger(log_directory);
|
||||
RestoreDynamicLoggingLevels raiiLevelRestore;
|
||||
ASSERT_TRUE(g2::logLevel(FATAL));
|
||||
ASSERT_TRUE(g3::logLevel(FATAL));
|
||||
|
||||
std::string msg1 = "dummy message to check if CHECK worked when fatal is enabled";
|
||||
std::string msg2 = "dummy message to check if CHECK worked when fatal is disabled";
|
||||
std::string msg3 = "dummy message to check if CHECK worked when fatal is disabled";
|
||||
LOG(FATAL) << msg1;
|
||||
EXPECT_TRUE(mockFatalWasCalled());
|
||||
EXPECT_TRUE(verifyContent(mockFatalMessage(), msg1));
|
||||
@ -544,9 +544,9 @@ TEST(DynamicLogging, DynamicLogging_Check_WillAlsoBeTurnedOffWhen_Fatal_Is_Disab
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
|
||||
// Disable also CHECK calls
|
||||
g2::setLogLevel(FATAL, false);
|
||||
ASSERT_FALSE(g2::logLevel(FATAL));
|
||||
LOG(FATAL) << msg2;
|
||||
g3::setLogLevel(FATAL, false);
|
||||
ASSERT_FALSE(g3::logLevel(FATAL));
|
||||
LOG(FATAL) << msg3;
|
||||
EXPECT_FALSE(mockFatalWasCalled());
|
||||
}
|
||||
|
||||
@ -554,9 +554,9 @@ TEST(DynamicLogging, DynamicLogging_Check_WillAlsoBeTurnedOffWhen_Fatal_Is_Disab
|
||||
|
||||
#else
|
||||
TEST(DynamicLogging, DynamicLogging_IS_NOT_ENABLED) {
|
||||
ASSERT_TRUE(g2::logLevel(DEBUG));
|
||||
//g2::setLogLevel(DEBUG, false); this line will not compile since G2_DYNAMIC_LOGGING is not enabled. Kept for show.
|
||||
//ASSERT_FALSE(g2::logLevel(DEBUG));
|
||||
ASSERT_TRUE(g3::logLevel(DEBUG));
|
||||
//g3::setLogLevel(DEBUG, false); this line will not compile since G3_DYNAMIC_LOGGING is not enabled. Kept for show.
|
||||
//ASSERT_FALSE(g3::logLevel(DEBUG));
|
||||
}
|
||||
#endif // Dynamic logging
|
||||
|
||||
|
@ -33,12 +33,12 @@ TEST(DynamicLoadOfLibrary, JustLoadAndExit) {
|
||||
std::vector<std::string> receiver;
|
||||
|
||||
{ // scope to flush logs at logworker exit
|
||||
auto worker = g2::LogWorker::createWithNoSink();
|
||||
auto worker = g3::LogWorker::createWithNoSink();
|
||||
auto handle = worker->addSink(std2::make_unique<LogMessageCounter>(std::ref(receiver)), &LogMessageCounter::countMessages);
|
||||
|
||||
// add another sink just for more throughput of data
|
||||
auto fileHandle = worker->addSink(std2::make_unique<g2::FileSink>("runtimeLoadOfDynamiclibs", "/tmp"), &g2::FileSink::fileWrite);
|
||||
g2::initializeLogging(worker.get());
|
||||
auto fileHandle = worker->addSink(std2::make_unique<g3::FileSink>("runtimeLoadOfDynamiclibs", "/tmp"), &g3::FileSink::fileWrite);
|
||||
g3::initializeLogging(worker.get());
|
||||
|
||||
void* libHandle = dlopen("libtester_sharedlib.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
EXPECT_FALSE(nullptr == libHandle);
|
||||
|
@ -24,11 +24,11 @@
|
||||
using namespace testing_helpers;
|
||||
using namespace std;
|
||||
TEST(Sink, OneSink) {
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
AtomicBoolPtr flag = make_shared < atomic<bool >> (false);
|
||||
AtomicIntPtr count = make_shared < atomic<int >> (0);
|
||||
{
|
||||
auto worker = g2::LogWorker::createWithNoSink();
|
||||
auto worker = g3::LogWorker::createWithNoSink();
|
||||
auto handle = worker->addSink(std2::make_unique<ScopedSetTrue>(flag, count), &ScopedSetTrue::ReceiveMsg);
|
||||
EXPECT_FALSE(flag->load());
|
||||
EXPECT_TRUE(0 == count->load());
|
||||
@ -49,7 +49,7 @@ namespace {
|
||||
}
|
||||
|
||||
TEST(ConceptSink, OneHundredSinks) {
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
BoolList flags;
|
||||
IntVector counts;
|
||||
|
||||
@ -61,7 +61,7 @@ TEST(ConceptSink, OneHundredSinks) {
|
||||
|
||||
{
|
||||
RestoreFileLogger logger{"./"};
|
||||
g2::LogWorker* worker = logger._scope->get(); //g2LogWorker::createWithNoSink();
|
||||
g3::LogWorker* worker = logger._scope->get(); //g3LogWorker::createWithNoSink();
|
||||
size_t index = 0;
|
||||
for (auto& flag : flags) {
|
||||
auto& count = counts[index++];
|
||||
@ -107,7 +107,7 @@ struct VoidReceiver {
|
||||
TEST(ConceptSink, VoidCall__NoCall_ExpectingNoAdd) {
|
||||
std::atomic<int> counter{0};
|
||||
{
|
||||
std::unique_ptr<g2::LogWorker> worker{g2::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
auto handle = worker->addSink(std2::make_unique<VoidReceiver>(&counter), &VoidReceiver::receiveMsg);
|
||||
}
|
||||
EXPECT_EQ(counter, 0);
|
||||
@ -116,7 +116,7 @@ TEST(ConceptSink, VoidCall__NoCall_ExpectingNoAdd) {
|
||||
TEST(ConceptSink, VoidCall__OneCall_ExpectingOneAdd) {
|
||||
std::atomic<int> counter{0};
|
||||
{
|
||||
std::unique_ptr<g2::LogWorker> worker{g2::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
auto handle = worker->addSink(std2::make_unique<VoidReceiver>(&counter), &VoidReceiver::receiveMsg);
|
||||
std::future<void> ignored = handle->call(&VoidReceiver::incrementAtomic);
|
||||
}
|
||||
@ -126,7 +126,7 @@ TEST(ConceptSink, VoidCall__OneCall_ExpectingOneAdd) {
|
||||
TEST(ConceptSink, VoidCall__TwoCalls_ExpectingTwoAdd) {
|
||||
std::atomic<int> counter{0};
|
||||
{
|
||||
std::unique_ptr<g2::LogWorker> worker{g2::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
auto handle = worker->addSink(std2::make_unique<VoidReceiver>(&counter), &VoidReceiver::receiveMsg);
|
||||
auto voidFuture1 = handle->call(&VoidReceiver::incrementAtomic);
|
||||
auto voidFuture2 = handle->call(&VoidReceiver::incrementAtomic);
|
||||
@ -153,7 +153,7 @@ struct IntReceiver {
|
||||
TEST(ConceptSink, IntCall__TwoCalls_ExpectingTwoAdd) {
|
||||
std::atomic<int> counter{0};
|
||||
{
|
||||
std::unique_ptr<g2::LogWorker> worker{g2::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
auto handle = worker->addSink(std2::make_unique<IntReceiver>(&counter), &IntReceiver::receiveMsgDoNothing);
|
||||
std::future<int> intFuture1 = handle->call(&IntReceiver::incrementAtomic);
|
||||
EXPECT_EQ(intFuture1.get(), 1);
|
||||
@ -179,7 +179,7 @@ void DoLogCalls(std::atomic<bool>* doWhileTrue, size_t counter) {
|
||||
TEST(ConceptSink, CannotCallSpawnTaskOnNullptrWorker) {
|
||||
auto FailedHelloWorld = []{ std::cout << "Hello World" << std::endl; };
|
||||
kjellkod::Active* active = nullptr;
|
||||
auto failed = g2::spawn_task(FailedHelloWorld, active);
|
||||
auto failed = g3::spawn_task(FailedHelloWorld, active);
|
||||
EXPECT_ANY_THROW(failed.get());
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ TEST(ConceptSink, AggressiveThreadCallsDuringShutdown) {
|
||||
const size_t numberOfThreads = 100;
|
||||
threads.reserve(numberOfThreads);
|
||||
|
||||
g2::internal::shutDownLogging();
|
||||
g3::internal::shutDownLogging();
|
||||
|
||||
// Avoid annoying printouts at log shutdown
|
||||
stringstream cerr_buffer;
|
||||
@ -210,16 +210,16 @@ TEST(ConceptSink, AggressiveThreadCallsDuringShutdown) {
|
||||
for (size_t create = 0; create < numberOfCycles; ++create) {
|
||||
std::cout << create << " ";
|
||||
|
||||
std::unique_ptr<g2::LogWorker> worker{g2::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
auto handle = worker->addSink(std2::make_unique<IntReceiver>(&atomicCounter), &IntReceiver::receiveMsgIncrementAtomic);
|
||||
g2::initializeLogging(worker.get());
|
||||
g3::initializeLogging(worker.get());
|
||||
|
||||
// wait till some LOGS streaming in
|
||||
atomicCounter = 0;
|
||||
while(atomicCounter.load() < 10) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
} // g2log worker exists: 1) shutdownlogging 2) flush of queues and shutdown of sinks
|
||||
} // g3log worker exists: 1) shutdownlogging 2) flush of queues and shutdown of sinks
|
||||
|
||||
|
||||
// exit the threads
|
||||
|
@ -7,7 +7,8 @@
|
||||
* ============================================================================*/
|
||||
|
||||
|
||||
#include <g2log.hpp>
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include "tester_sharedlib.h"
|
||||
|
||||
struct RuntimeLoadedLib : public SomeLibrary {
|
||||
|
@ -7,16 +7,20 @@
|
||||
* ============================================================================*/
|
||||
|
||||
|
||||
#include <g3log/g3log.hpp>
|
||||
#include <g3log/logworker.hpp>
|
||||
#include <g3log/std2_make_unique.hpp>
|
||||
#include <g3log/logmessage.hpp>
|
||||
|
||||
#include "testing_helpers.h"
|
||||
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "testing_helpers.h"
|
||||
#include "g2log.hpp"
|
||||
#include "g3log/std2_make_unique.hpp"
|
||||
#include "g3log/logmessage.hpp"
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace g2;
|
||||
using namespace g3;
|
||||
|
||||
namespace testing_helpers {
|
||||
|
||||
@ -41,7 +45,7 @@ namespace testing_helpers {
|
||||
g_mockFatal_signal = fatal_message.get()->_signal_id;
|
||||
g_mockFatalWasCalled = true;
|
||||
LogMessagePtr message{fatal_message.release()};
|
||||
g2::internal::pushMessageToLogger(message); //fatal_message.copyToLogMessage());
|
||||
g3::internal::pushMessageToLogger(message); //fatal_message.copyToLogMessage());
|
||||
}
|
||||
|
||||
void clearMockFatal() {
|
||||
@ -98,17 +102,17 @@ namespace testing_helpers {
|
||||
}
|
||||
}
|
||||
|
||||
ScopedLogger::ScopedLogger() : _currentWorker(g2::LogWorker::createWithNoSink()) {}
|
||||
ScopedLogger::ScopedLogger() : _currentWorker(g3::LogWorker::createWithNoSink()) {}
|
||||
ScopedLogger::~ScopedLogger() {}
|
||||
|
||||
g2::LogWorker* ScopedLogger::get() {
|
||||
g3::LogWorker* ScopedLogger::get() {
|
||||
return _currentWorker.get();
|
||||
}
|
||||
|
||||
RestoreFileLogger::RestoreFileLogger(std::string directory)
|
||||
: _scope(new ScopedLogger), _handle(_scope->get()->addSink(std2::make_unique<g2::FileSink>("UNIT_TEST_LOGGER", directory), &g2::FileSink::fileWrite)) {
|
||||
using namespace g2;
|
||||
g2::initializeLogging(_scope->_currentWorker.get());
|
||||
: _scope(new ScopedLogger), _handle(_scope->get()->addSink(std2::make_unique<g3::FileSink>("UNIT_TEST_LOGGER", directory), &g3::FileSink::fileWrite)) {
|
||||
using namespace g3;
|
||||
g3::initializeLogging(_scope->_currentWorker.get());
|
||||
clearMockFatal();
|
||||
setFatalExitHandler(&mockFatalCall);
|
||||
|
||||
@ -116,16 +120,16 @@ namespace testing_helpers {
|
||||
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);
|
||||
#ifdef G3_DYNAMIC_LOGGING
|
||||
g3::setLogLevel(INFO, true);
|
||||
g3::setLogLevel(DEBUG, true);
|
||||
g3::setLogLevel(WARNING, true);
|
||||
g3::setLogLevel(FATAL, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
RestoreFileLogger::~RestoreFileLogger() {
|
||||
g2::internal::shutDownLogging(); // is done at reset. Added for test clarity
|
||||
g3::internal::shutDownLogging(); // is done at reset. Added for test clarity
|
||||
reset();
|
||||
|
||||
if (!removeFile(_log_file))
|
||||
@ -140,7 +144,7 @@ namespace testing_helpers {
|
||||
// auto file = logger.logFile()
|
||||
// auto content = ReadContentFromFile(file)
|
||||
// ... it is not guaranteed that the content will contain (yet) the LOG(INFO)
|
||||
std::future<std::string> filename = _handle->call(&g2::FileSink::fileName);
|
||||
std::future<std::string> filename = _handle->call(&g3::FileSink::fileName);
|
||||
_log_file = filename.get();
|
||||
}
|
||||
return _log_file;
|
||||
@ -150,7 +154,7 @@ namespace testing_helpers {
|
||||
// since LOG(...) passes two queues but the handle::call only passes one queue
|
||||
// the handle::call can happen faster
|
||||
std::string RestoreFileLogger::resetAndRetrieveContent() {
|
||||
std::future<std::string> filename = _handle->call(&g2::FileSink::fileName);
|
||||
std::future<std::string> filename = _handle->call(&g3::FileSink::fileName);
|
||||
reset(); // flush all queues to sinks
|
||||
EXPECT_TRUE(filename.valid());
|
||||
auto file = filename.get();
|
||||
|
@ -23,7 +23,7 @@ namespace testing_helpers {
|
||||
std::string mockFatalMessage();
|
||||
int mockFatalSignal();
|
||||
bool mockFatalWasCalled();
|
||||
void mockFatalCall(g2::FatalMessagePtr fatal_message);
|
||||
void mockFatalCall(g3::FatalMessagePtr fatal_message);
|
||||
void clearMockFatal();
|
||||
|
||||
bool removeFile(std::string path_to_file);
|
||||
@ -77,8 +77,8 @@ struct ScopedLogger {
|
||||
ScopedLogger();
|
||||
virtual ~ScopedLogger();
|
||||
|
||||
g2::LogWorker* get();
|
||||
std::unique_ptr<g2::LogWorker> _currentWorker;
|
||||
g3::LogWorker* get();
|
||||
std::unique_ptr<g3::LogWorker> _currentWorker;
|
||||
};
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ struct RestoreFileLogger {
|
||||
|
||||
|
||||
private:
|
||||
std::unique_ptr<g2::SinkHandle<g2::FileSink>> _handle;
|
||||
std::unique_ptr<g3::SinkHandle<g3::FileSink>> _handle;
|
||||
std::string _log_file;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user