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:
Kjell Hedstrom 2015-07-19 23:10:56 -06:00
parent 7cf42c535c
commit 7c7012325d
46 changed files with 465 additions and 449 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@
#include "g3log/logmessage.hpp"
namespace g2 {
namespace g3 {
namespace internal {
struct SinkWrapper {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,8 @@
* ============================================================================*/
#include <g2log.hpp>
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>
#include "tester_sharedlib.h"
struct RuntimeLoadedLib : public SomeLibrary {

View File

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

View File

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