mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-12 10:23:50 +01:00
Updated for better unit-testing. Unit testing does not abort but throws a std::runtime_error if FATAL
This commit is contained in:
parent
b3b5335b90
commit
925581d338
@ -54,7 +54,7 @@ IF(UNIX)
|
||||
MESSAGE("")
|
||||
set(PLATFORM_LINK_LIBRIES justthread rt)
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Wunused -std=c++0x ${CMAKE_CXX_FLAGS_DEBUG} -pthread -I/usr/include/justthread")
|
||||
set(G2_LOG_FILES ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
|
||||
set(G2_LOG_FILES ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
|
||||
include_directories("/usr/include/justthread")
|
||||
|
||||
# SETUP for GTEST
|
||||
@ -73,7 +73,7 @@ IF(WIN32)
|
||||
MESSAGE("then run 'Debug\\g2log-example.exe' or whatever performance test you feel like trying")
|
||||
MESSAGE("")
|
||||
set(PLATFORM_LINK_LIBRIES $ENV{PROGRAMFILES}/JustSoftwareSolutions/JustThread/lib/justthread_vc10_mdd.lib)
|
||||
set(G2_LOG_FILES ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_win.cpp)
|
||||
set(G2_LOG_FILES ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_win.cpp)
|
||||
include_directories("$ENV{PROGRAMFILES}/JustSoftwareSolutions/JustThread/include")
|
||||
ENDIF(WIN32)
|
||||
|
||||
@ -136,12 +136,10 @@ IF(UNIX)
|
||||
|
||||
# create the the TEST executable
|
||||
add_executable(g2log-unit_test ../test_main/test_main.cpp test/test_io.cpp)
|
||||
add_library(lib_test_logger ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
|
||||
add_library(lib_test_logger ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
|
||||
set_target_properties(lib_test_logger PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(lib_test_logger PROPERTIES COMPILE_DEFINITIONS "YALLA=1")
|
||||
target_link_libraries(lib_test_logger lib_activeobject)
|
||||
# For unit-test only, dont 'crash' by signals, instead just throw a std::runtime_error
|
||||
set_target_properties(g2log-unit_test PROPERTIES COMPILE_DEFINITIONS "YALLA=1")
|
||||
target_link_libraries(g2log-unit_test lib_activeobject lib_test_logger gtest_160_lib justthread rt)
|
||||
ENDIF(UNIX)
|
||||
|
||||
|
@ -15,7 +15,7 @@ std::string signalName(int signal_number);
|
||||
|
||||
/** 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, LogWorker after flushing messages to file */
|
||||
* from g2log, g2LogWorker after flushing messages to file */
|
||||
void exitWithDefaultSignalHandler(int signal_number);
|
||||
} // end g2::interal
|
||||
|
||||
|
@ -46,7 +46,7 @@ void crashHandler(int signal_number, siginfo_t *info, void *unused_context)
|
||||
FatalMessage fatal_message(fatal_stream.str(),FatalMessage::kReasonOS_FATAL_SIGNAL, signal_number);
|
||||
FatalTrigger trigger(fatal_message); std::ostringstream oss;
|
||||
std::cerr << fatal_message.message_ << std::endl << std::flush;
|
||||
} // message sent to LogWorker
|
||||
} // message sent to g2LogWorker
|
||||
// wait to die -- will be inside the FatalTrigger
|
||||
}
|
||||
} // end anonymous namespace
|
||||
@ -86,7 +86,7 @@ default:
|
||||
}
|
||||
}
|
||||
|
||||
// Triggered by g2log::LogWorker after receiving a FATAL trigger
|
||||
// Triggered by g2log->g2LogWorker 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(int signal_number)
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
#include "logworker.h"
|
||||
#include "g2logworker.h"
|
||||
#include "crashhandler.h"
|
||||
#include <signal.h>
|
||||
|
||||
@ -34,7 +34,7 @@ const std::string kTruncatedWarningText = "[...truncated...]";
|
||||
}
|
||||
namespace internal
|
||||
{
|
||||
static LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
|
||||
static g2LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
|
||||
static std::mutex g_logging_init_mutex;
|
||||
bool isLoggingInitialized(){return g_logger_instance != nullptr; }
|
||||
|
||||
@ -53,7 +53,7 @@ std::string splitFileName(const std::string& str)
|
||||
} // end namespace g2::internal
|
||||
|
||||
|
||||
void initializeLogging(LogWorker *bgworker)
|
||||
void initializeLogging(g2LogWorker *bgworker)
|
||||
{
|
||||
static bool once_only_signalhandler = false;
|
||||
std::lock_guard<std::mutex> lock(internal::g_logging_init_mutex);
|
||||
@ -68,20 +68,50 @@ void initializeLogging(LogWorker *bgworker)
|
||||
}
|
||||
}
|
||||
|
||||
LogWorker* shutDownLogging()
|
||||
g2LogWorker* shutDownLogging()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(internal::g_logging_init_mutex);
|
||||
CHECK(internal::isLoggingInitialized());
|
||||
LogWorker *backup = internal::g_logger_instance;
|
||||
g2LogWorker *backup = internal::g_logger_instance;
|
||||
internal::g_logger_instance = nullptr;
|
||||
return backup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
// The default, initial, handling to send a 'fatal' event to g2logworker
|
||||
// the caller will stay here, eternally, until the software is aborted
|
||||
void callFatalInitial(FatalMessage message)
|
||||
{
|
||||
internal::g_logger_instance->fatal(message);
|
||||
}
|
||||
// By default this function pointer goes to \ref callFatalInitial;
|
||||
void (*g_fatal_to_g2logworker_function_ptr)(FatalMessage) = callFatalInitial;
|
||||
|
||||
|
||||
|
||||
// Replaces the g2log.cpp/g_fatal_to_g2logworker_function_ptr through
|
||||
// g2log::changeFatalInitHandler
|
||||
void unitTestFatalInitHandler(g2::internal::FatalMessage fatal_message)
|
||||
{
|
||||
assert(internal::g_logger_instance != nullptr);
|
||||
internal::g_logger_instance->save(fatal_message.message_); // calling 'save' instead of 'fatal'
|
||||
throw std::runtime_error(fatal_message.message_);
|
||||
}
|
||||
|
||||
// In case of unit-testing - a replacement 'fatal function' can be called
|
||||
void changeFatalInitHandlerForUnitTesting()
|
||||
{
|
||||
g_fatal_to_g2logworker_function_ptr = unitTestFatalInitHandler;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LogContractMessage::LogContractMessage(const std::string &file, const int line,
|
||||
const std::string& function, const std::string &boolean_expression)
|
||||
: LogMessage(file, line, function, "FATAL")
|
||||
@ -130,9 +160,9 @@ LogMessage::~LogMessage()
|
||||
|
||||
if(!isLoggingInitialized() )
|
||||
{
|
||||
std::cerr << "Did you forget to call g2::InitializeLogging(LogWorker*) in your main.cpp?" << std::endl;
|
||||
std::cerr << "Did you forget to call g2::InitializeLogging(g2LogWorker*) in your main.cpp?" << std::endl;
|
||||
std::cerr << log_entry_ << std::endl << std::flush;
|
||||
throw std::runtime_error("Logger not initialized with g2::InitializeLogging(LogWorker*) for msg:\n" + log_entry_);
|
||||
throw std::runtime_error("Logger not initialized with g2::InitializeLogging(g2LogWorker*) for msg:\n" + log_entry_);
|
||||
}
|
||||
|
||||
|
||||
@ -155,18 +185,17 @@ FatalMessage::FatalMessage(std::string message, FatalType type, int signal_id)
|
||||
, type_(type)
|
||||
, signal_id_(signal_id){}
|
||||
|
||||
// used to RAII trigger fatal message sending to LogWorker
|
||||
// used to RAII trigger fatal message sending to g2LogWorker
|
||||
FatalTrigger::FatalTrigger(const FatalMessage &message)
|
||||
: message_(message){}
|
||||
|
||||
// at destruction, flushes fatal message to LogWorker
|
||||
// at destruction, flushes fatal message to g2LogWorker
|
||||
FatalTrigger::~FatalTrigger()
|
||||
{
|
||||
internal::g_logger_instance->fatal(message_);
|
||||
#if !defined(YALLA) // don't sleep if unit-testing
|
||||
// wait to die
|
||||
// either we will stay here eternally, or it's in unit-test mode
|
||||
// then we throw a std::runtime_error (and never hit sleep)
|
||||
g_fatal_to_g2logworker_function_ptr(message_);
|
||||
while(true){std::this_thread::sleep_for(std::chrono::seconds(1));}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <cstdarg>
|
||||
#include <chrono>
|
||||
|
||||
class LogWorker;
|
||||
class g2LogWorker;
|
||||
|
||||
#if !(defined(__PRETTY_FUNCTION__))
|
||||
#define __PRETTY_FUNCTION__ __FUNCTION__
|
||||
@ -141,15 +141,15 @@ And here is possible output
|
||||
* --- Thanks for a great 2011 and good luck with 'g2' --- KjellKod */
|
||||
namespace g2
|
||||
{
|
||||
/** Should be called at very first startup of the software with \ref LogWorker pointer. Ownership of the \ref LogWorker is
|
||||
/** 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 */
|
||||
void initializeLogging(LogWorker *logger);
|
||||
void initializeLogging(g2LogWorker *logger);
|
||||
|
||||
/** Shutdown the logging by making the pointer to the background logger to nullptr
|
||||
* The \ref pointer to the LogWorker is owned by the instantniater \ref initializeLogging
|
||||
* The \ref pointer to the g2LogWorker is owned by the instantniater \ref initializeLogging
|
||||
* and is not deleted. By restoring the ptr to nullptr we can re-initialize it later again. This is
|
||||
* kept for test reasons and should normally not be used */
|
||||
LogWorker* shutDownLogging();
|
||||
g2LogWorker* shutDownLogging();
|
||||
|
||||
|
||||
// defined here but should't not have to be used outside the g2log
|
||||
@ -160,6 +160,13 @@ typedef std::chrono::duration<long,std::ratio<1, 1000> > millisecond;
|
||||
typedef std::chrono::duration<long long,std::ratio<1, 1000000> > microsecond;
|
||||
typedef const std::string& LogEntry;
|
||||
|
||||
|
||||
/** By default the g2log will call g2LogWorker::fatal(...) which will abort() the system after flushing
|
||||
* the logs to file. This makes unit test of FATAL level cumbersome. A work around is to change the 'fatal call'
|
||||
* which can be done here */
|
||||
void changeFatalInitHandlerForUnitTesting();
|
||||
|
||||
|
||||
/** Trigger for flushing the message queue and exiting the applicaition
|
||||
A thread that causes a FatalMessage will sleep forever until the
|
||||
application has exited (after message flush) */
|
||||
|
@ -1,11 +1,11 @@
|
||||
/* *************************************************
|
||||
* Filename:logworker.cpp Framework for Logging and Design By Contract
|
||||
* Filename:g2LogWorker.cpp Framework for Logging and Design By Contract
|
||||
* Created: 2011 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
|
||||
* ********************************************* */
|
||||
|
||||
#include "logworker.h"
|
||||
#include "g2logworker.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
@ -17,10 +17,6 @@
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
|
||||
#if defined(YALLA)
|
||||
#include <stdexcept> // exceptions
|
||||
#endif
|
||||
|
||||
#include "active.h"
|
||||
#include "g2log.h"
|
||||
#include "crashhandler.h"
|
||||
@ -54,13 +50,13 @@ struct LogTime
|
||||
|
||||
|
||||
|
||||
/** The actual background worker, while LogWorker gives the
|
||||
* asynchronous API to put job in the background the LogWorkerImpl
|
||||
/** The actual background worker, while g2LogWorker gives the
|
||||
* asynchronous API to put job in the background the g2LogWorkerImpl
|
||||
* does the actual background thread work */
|
||||
struct LogWorkerImpl
|
||||
struct g2LogWorkerImpl
|
||||
{
|
||||
LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory);
|
||||
~LogWorkerImpl();
|
||||
g2LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory);
|
||||
~g2LogWorkerImpl();
|
||||
|
||||
void backgroundFileWrite(g2::internal::LogEntry message);
|
||||
void backgroundExitFatal(g2::internal::FatalMessage fatal_message);
|
||||
@ -71,15 +67,15 @@ struct LogWorkerImpl
|
||||
g2::internal::time_point start_time_;
|
||||
|
||||
private:
|
||||
LogWorkerImpl& operator=(const LogWorkerImpl&); // c++11 feature not yet in vs2010 = delete;
|
||||
LogWorkerImpl(const LogWorkerImpl& other); // c++11 feature not yet in vs2010 = delete;
|
||||
g2LogWorkerImpl& operator=(const g2LogWorkerImpl&); // c++11 feature not yet in vs2010 = delete;
|
||||
g2LogWorkerImpl(const g2LogWorkerImpl& other); // c++11 feature not yet in vs2010 = delete;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Private API implementation : LogWorkerImpl
|
||||
LogWorkerImpl::LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory)
|
||||
// Private API implementation : g2LogWorkerImpl
|
||||
g2LogWorkerImpl::g2LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory)
|
||||
: log_file_with_path_(log_directory)
|
||||
, bg_(kjellkod::Active::createActive())
|
||||
, start_time_(std::chrono::steady_clock::now())
|
||||
@ -115,7 +111,7 @@ LogWorkerImpl::LogWorkerImpl(const std::string& log_prefix, const std::string& l
|
||||
out.fill('0');
|
||||
}
|
||||
|
||||
LogWorkerImpl::~LogWorkerImpl()
|
||||
g2LogWorkerImpl::~g2LogWorkerImpl()
|
||||
{
|
||||
std::ostringstream ss_exit;
|
||||
time_t exit_time;
|
||||
@ -125,7 +121,7 @@ LogWorkerImpl::~LogWorkerImpl()
|
||||
out << ss_exit.str() << std::flush;
|
||||
}
|
||||
|
||||
void LogWorkerImpl::backgroundFileWrite(LogEntry message)
|
||||
void g2LogWorkerImpl::backgroundFileWrite(LogEntry message)
|
||||
{
|
||||
using namespace std;
|
||||
LogTime t;
|
||||
@ -136,17 +132,9 @@ void LogWorkerImpl::backgroundFileWrite(LogEntry message)
|
||||
out << "\t" << message << std::flush;
|
||||
}
|
||||
|
||||
void LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
|
||||
void g2LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
|
||||
{
|
||||
backgroundFileWrite(fatal_message.message_);
|
||||
|
||||
#if defined(YALLA)
|
||||
// If running unit test - we simplify matters by not sending the signal, but
|
||||
// by just throwing an exception
|
||||
throw std::runtime_error(fatal_message.message_);
|
||||
return;
|
||||
#endif
|
||||
|
||||
out.close();
|
||||
exitWithDefaultSignalHandler(fatal_message.signal_id_);
|
||||
perror("g2log exited after receiving FATAL trigger. Flush message status: "); // should never reach this point
|
||||
@ -154,31 +142,31 @@ void LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
|
||||
|
||||
|
||||
|
||||
// BELOW LogWorker
|
||||
// BELOW g2LogWorker
|
||||
// Public API implementation
|
||||
LogWorker::LogWorker(const std::string& log_prefix, const std::string& log_directory)
|
||||
: pimpl_(new LogWorkerImpl(log_prefix, log_directory))
|
||||
g2LogWorker::g2LogWorker(const std::string& log_prefix, const std::string& log_directory)
|
||||
: pimpl_(new g2LogWorkerImpl(log_prefix, log_directory))
|
||||
, log_file_with_path_(pimpl_->log_file_with_path_)
|
||||
{
|
||||
}
|
||||
|
||||
LogWorker::~LogWorker()
|
||||
g2LogWorker::~g2LogWorker()
|
||||
{
|
||||
pimpl_.reset();
|
||||
std::cout << "\nExiting, log location: " << log_file_with_path_ << std::endl << std::flush;
|
||||
}
|
||||
|
||||
void LogWorker::save(g2::internal::LogEntry msg)
|
||||
void g2LogWorker::save(g2::internal::LogEntry msg)
|
||||
{
|
||||
pimpl_->bg_->send(std::tr1::bind(&LogWorkerImpl::backgroundFileWrite, pimpl_.get(), msg));
|
||||
pimpl_->bg_->send(std::tr1::bind(&g2LogWorkerImpl::backgroundFileWrite, pimpl_.get(), msg));
|
||||
}
|
||||
|
||||
void LogWorker::fatal(g2::internal::FatalMessage fatal_message)
|
||||
void g2LogWorker::fatal(g2::internal::FatalMessage fatal_message)
|
||||
{
|
||||
pimpl_->bg_->send(std::tr1::bind(&LogWorkerImpl::backgroundExitFatal, pimpl_.get(), fatal_message));
|
||||
pimpl_->bg_->send(std::tr1::bind(&g2LogWorkerImpl::backgroundExitFatal, pimpl_.get(), fatal_message));
|
||||
}
|
||||
|
||||
std::string LogWorker::logFileName() const
|
||||
std::string g2LogWorker::logFileName() const
|
||||
{
|
||||
return log_file_with_path_;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
#ifndef LOG_WORKER_H_
|
||||
#define LOG_WORKER_H_
|
||||
#ifndef G2_LOG_WORKER_H_
|
||||
#define G2_LOG_WORKER_H_
|
||||
|
||||
/* *************************************************
|
||||
* Filename:logworker.h Framework for Logging and Design By Contract
|
||||
* Filename:g2logworker.h Framework for Logging and Design By Contract
|
||||
* Created: 2011 by Kjell Hedström
|
||||
*
|
||||
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
|
||||
@ -10,16 +10,16 @@
|
||||
#include <memory>
|
||||
#include "g2log.h"
|
||||
|
||||
class LogWorkerImpl;
|
||||
class g2LogWorkerImpl;
|
||||
|
||||
/**
|
||||
* \param log_prefix is the 'name' of the binary, this give the log name 'LOG-'name'-...
|
||||
* \param log_directory gives the directory to put the log files */
|
||||
class LogWorker
|
||||
class g2LogWorker
|
||||
{
|
||||
public:
|
||||
LogWorker(const std::string& log_prefix, const std::string& log_directory);
|
||||
virtual ~LogWorker();
|
||||
g2LogWorker(const std::string& log_prefix, const std::string& log_directory);
|
||||
virtual ~g2LogWorker();
|
||||
|
||||
/// pushes in background thread (asynchronously) input messages to log file
|
||||
void save(g2::internal::LogEntry entry);
|
||||
@ -33,11 +33,11 @@ public:
|
||||
std::string logFileName() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<LogWorkerImpl> pimpl_;
|
||||
std::unique_ptr<g2LogWorkerImpl> pimpl_;
|
||||
const std::string log_file_with_path_;
|
||||
|
||||
LogWorker(const LogWorker&); // c++11 feature not yet in vs2010 = delete;
|
||||
LogWorker& operator=(const LogWorker&); // c++11 feature not yet in vs2010 = delete;
|
||||
g2LogWorker(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
|
||||
g2LogWorker& operator=(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
|
||||
};
|
||||
|
||||
|
@ -5,9 +5,8 @@
|
||||
* PUBLIC DOMAIN and Not copy-writed
|
||||
* ********************************************* */
|
||||
|
||||
#include "logworker.h"
|
||||
#include "g2logworker.h"
|
||||
#include "g2log.h"
|
||||
#include "logworker.h"
|
||||
#include <iomanip>
|
||||
|
||||
namespace
|
||||
@ -25,14 +24,9 @@ int main(int argc, char** argv)
|
||||
float pi_f = 3.1415926535897932384626433832795f;
|
||||
|
||||
|
||||
LogWorker logger(argv[0], path_to_log_file);
|
||||
g2LogWorker logger(argv[0], path_to_log_file);
|
||||
g2::initializeLogging(&logger);
|
||||
|
||||
std::cout << "****** A NUMBER of 'runtime exceptions' will be printed on this screen" << std::endl;
|
||||
std::cout << "****** that's all good and part of the 'example'. " << std::endl;
|
||||
std::cout << "****** please see g2log/src/main.cpp and he finished log file to " << std::endl;
|
||||
std::cout << "****** follow what is done in this example\n\n" << std::endl;
|
||||
|
||||
LOGF(INFO, "Hi log %d", 123);
|
||||
LOG(INFO) << "Test SLOG INFO";
|
||||
LOG(DEBUG) << "Test SLOG DEBUG";
|
||||
@ -51,15 +45,6 @@ int main(int argc, char** argv)
|
||||
//LOG(UNKNOWN_LEVEL) << "This log attempt will cause a compiler error";
|
||||
LOG(INFO) << "Simple to use with streaming syntax, easy as abc or " << 123;
|
||||
LOGF(WARNING, "Printf-style syntax is also %s", "available");
|
||||
// ....
|
||||
try
|
||||
{
|
||||
LOGF(FATAL, "FATAL has a special meaning. This %s will throw an exception", "message");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "\n **** All good expected the 'FATAL has a special meaning' runtime exception\n\n\n" << std::endl;
|
||||
}
|
||||
LOG_IF(INFO, (1 < 2)) << "If true this text will be logged";
|
||||
LOGF_IF(INFO, (1<2), "if %d<%d : then this text will be logged", 1,2);
|
||||
LOG_IF(FATAL, (2>3)) << "This message should NOT throw";
|
||||
@ -68,42 +53,14 @@ int main(int argc, char** argv)
|
||||
{
|
||||
const std::string logging = "logging";
|
||||
// OK --- this WILL get a compiler warning
|
||||
LOGF(DEBUG, "Printf-type %s is the number 1 for many %s", logging.c_str());
|
||||
}
|
||||
CHECK(1 != 2); // true: won't throw
|
||||
try
|
||||
{
|
||||
CHECK(1 > 2) << "CHECK(false) will put this message to the throw exception message and our log";
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "\n **** All good expected the 'CHECK(false) will put ...' runtime exception\n\n\n" << std::endl;
|
||||
}
|
||||
//
|
||||
// END: LOG Entris that were in the article
|
||||
//
|
||||
try
|
||||
{
|
||||
const std::string arg = "CHECK_F";
|
||||
CHECK_F(1 > 2, "This is a test to see if %s works", arg.c_str());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "\n **** All good expected the 'CHECK(1>2) This is a test ...' runtime exception\n\n\n" << std::endl;
|
||||
LOGF(DEBUG, "ILLEGAL PRINTF_SYNTAX EXAMPLE. WILL GENERATE compiler warning.\n\nbadly formatted message:[Printf-type %s is the number 1 for many %s]", logging.c_str());
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
std::cout << "\n\n***** Be ready the example will show a 'runtime exception' " << std::endl;
|
||||
CHECK(1<2) << "SHOULD NOT SEE THIS MESSAGE";
|
||||
CHECK(1>2) << "Test to see if contract works: onetwothree: " << 123 << ". This should be inside an exception";
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "\n***** All good, the 'exception' was part of the example\n\n\n" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
std::cerr << "Unexpected ending, expected an exception" << std::endl << std::flush;
|
||||
return 1;
|
||||
std::cout << "\n\n***** Be ready this last example will 'abort' " << std::endl;
|
||||
std::cout << "***** please theck the logfile for all the LOGS and compare them to this example" << std::endl;
|
||||
std::cout << "***** this file is g2log/src/main.cpp. The log file is: " << logger.logFileName() << std::endl;
|
||||
std::cout << "************************************************************\n\n" << std::endl;
|
||||
CHECK(1<2) << "SHOULD NOT SEE THIS MESSAGE";
|
||||
CHECK(1>2) << "Test to see if contract works: onetwothree: " << 123 << ". This should be at the end of the log, and will exit this example";
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ int main(int argc, char** argv)
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
LogWorker* logger = new LogWorker(g_prefix_log_name, g_path);
|
||||
g2LogWorker* logger = new g2LogWorker(g_prefix_log_name, g_path);
|
||||
g2::initializeLogging(logger);
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
@ -85,7 +85,7 @@ int main(int argc, char** argv)
|
||||
auto total_time_us = std::chrono::duration_cast<microsecond>(worker_end_time - start_time).count();
|
||||
|
||||
oss << "\n" << g_iterations << " log entries took: [" << total_time_us / 1000000 << " s] to write to disk"<< std::endl;
|
||||
oss << "[Application(2threads):\t\t:" << application_time_us/1000 << " ms]" << std::endl;
|
||||
oss << "[Application(" << number_of_threads << "):\t\t:" << application_time_us/1000 << " ms]" << std::endl;
|
||||
oss << "[Background thread to finish\t:" << total_time_us/1000 << " ms]" << std::endl;
|
||||
oss << "\nAverage time per log entry:" << std::endl;
|
||||
oss << "[Application: " << application_time_us/(number_of_threads*g_iterations) << " us]" << std::endl;
|
||||
|
@ -26,6 +26,10 @@ const std::string g_path = "/tmp/";
|
||||
using namespace g2_test;
|
||||
|
||||
|
||||
//
|
||||
// OK: The code below isn't pretty but it works. Lots and lots of log entries
|
||||
// to keep track of!
|
||||
//
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
size_t number_of_threads =0;
|
||||
@ -57,7 +61,7 @@ int main(int argc, char** argv)
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
LogWorker* logger = new LogWorker(g_prefix_log_name, g_path);
|
||||
g2LogWorker* logger = new g2LogWorker(g_prefix_log_name, g_path);
|
||||
g2::initializeLogging(logger);
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#if defined(G2LOG_PERFORMANCE)
|
||||
#include "g2log.h"
|
||||
#include "logworker.h"
|
||||
#include "g2logworker.h"
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
#include <glog/logging.h>
|
||||
#else
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "g2log.h"
|
||||
#include "logworker.h"
|
||||
#include "g2logworker.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
@ -50,16 +50,17 @@ struct RestoreLogger
|
||||
void reset();
|
||||
std::string readFileToText();
|
||||
|
||||
std::unique_ptr<LogWorker> logger_;
|
||||
std::unique_ptr<g2LogWorker> logger_;
|
||||
const std::string log_file_;
|
||||
|
||||
};
|
||||
|
||||
RestoreLogger::RestoreLogger()
|
||||
: logger_(new LogWorker("UNIT_TEST_LOGGER", "./"))
|
||||
: logger_(new g2LogWorker("UNIT_TEST_LOGGER", "./"))
|
||||
, log_file_(logger_->logFileName())
|
||||
{
|
||||
g2::initializeLogging(logger_.get());
|
||||
g2::internal::changeFatalInitHandlerForUnitTesting();
|
||||
}
|
||||
|
||||
RestoreLogger::~RestoreLogger()
|
||||
@ -175,13 +176,13 @@ TEST(LogTest, LOGF__FATAL)
|
||||
try
|
||||
{
|
||||
LOGF(FATAL, "This message should throw %d",0);
|
||||
sleep(k_wait_time);
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
std::cerr << file_content << std::endl << std::flush;
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, "This message should throw"))
|
||||
{
|
||||
@ -203,13 +204,12 @@ TEST(LogTest, LOG_FATAL)
|
||||
try
|
||||
{
|
||||
LOG(FATAL) << "This message should throw";
|
||||
sleep(k_wait_time);
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, "This message should throw"))
|
||||
{
|
||||
@ -231,13 +231,12 @@ TEST(LogTest, LOGF_IF__FATAL)
|
||||
try
|
||||
{
|
||||
LOGF_IF(FATAL, (2<3), "This message%sshould throw"," ");
|
||||
sleep(k_wait_time);
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, "This message should throw"))
|
||||
{
|
||||
@ -260,13 +259,12 @@ TEST(LogTest, LOG_IF__FATAL)
|
||||
{
|
||||
LOG_IF(WARNING, (0 != t_info.compare(t_info))) << "This message should NOT be written";
|
||||
LOG_IF(FATAL, (0 != t_info.compare(t_info2))) << "This message should throw";
|
||||
sleep(k_wait_time);
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, "This message should throw") &&
|
||||
(false == verifyContent(file_content, "This message should NOT be written")))
|
||||
@ -311,7 +309,7 @@ TEST(CheckTest, CHECK_F__thisWILL_PrintErrorMsg)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL"))
|
||||
{
|
||||
SUCCEED();
|
||||
@ -332,13 +330,12 @@ TEST(CHECK_F_Test, CHECK_F__thisWILL_PrintErrorMsg)
|
||||
try
|
||||
{
|
||||
CHECK_F(1 >= 2, msg.c_str(), arg1.c_str(), arg2.c_str());
|
||||
sleep(k_wait_time);
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, msg2))
|
||||
{
|
||||
@ -364,7 +361,7 @@ TEST(CHECK_Test, CHECK__thisWILL_PrintErrorMsg)
|
||||
{
|
||||
logger.reset();
|
||||
std::string file_content = readFileToText(logger.log_file_);
|
||||
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
|
||||
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
|
||||
verifyContent(file_content, "FATAL") &&
|
||||
verifyContent(file_content, msg2))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user