mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-13 10:42:56 +01:00
Breaking change but a good change: Cleared up the API for Creating log worker and Adding sinks
This commit is contained in:
parent
bc4459d779
commit
1803498e89
@ -89,7 +89,7 @@ Example usage where a custom sink is added. A function is called though the sink
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
using namespace g3;
|
||||
std::unique_ptr<LogWorker> logworker{ LogWorker::createWithNoSink() };
|
||||
std::unique_ptr<LogWorker> logworker{ LogWorker::createLogWorker() };
|
||||
auto sinkHandle = logworker->addSink(std2::make_unique<CustomSink>(),
|
||||
&CustomSink::ReceiveLogMessage);
|
||||
|
||||
@ -135,7 +135,8 @@ Example usage where a the default file logger is used **and** a custom sink is a
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
using namespace g3;
|
||||
auto defaultHandler = LogWorker::createWithDefaultLogger(argv[0],
|
||||
auto worker = LogWorker::createLogWorker();
|
||||
auto defaultHandler = worker->addDefaultLogger(argv[0],
|
||||
path_to_log_file);
|
||||
|
||||
// logger is initialized
|
||||
@ -143,7 +144,7 @@ int main(int argc, char**argv) {
|
||||
|
||||
LOG(DEBUG) << "Make log call, then add another sink";
|
||||
|
||||
defaultHandler.worker->addSink(std2::make_unique<CustomSink>(),
|
||||
worker->addSink(std2::make_unique<CustomSink>(),
|
||||
&CustomSink::ReceiveLogMessage);
|
||||
|
||||
...
|
||||
|
@ -35,9 +35,10 @@ int main(int argc, char **argv)
|
||||
double pi_d = 3.1415926535897932384626433832795;
|
||||
float pi_f = 3.1415926535897932384626433832795f;
|
||||
|
||||
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);
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle= worker->addDefaultLogger(argv[0], path_to_log_file);
|
||||
g3::initializeLogging(worker.get());
|
||||
std::future<std::string> log_file_name = handle->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 g3log/test_example/main_contract.cpp" << std::endl;
|
||||
|
@ -235,6 +235,10 @@ namespace
|
||||
} // namespace
|
||||
|
||||
void breakHere() {
|
||||
std::ostringstream oss;
|
||||
oss << __FUNCTION__ << " was reached" << std::endl;
|
||||
std::cout << oss.str() << std::endl;
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
__debugbreak();
|
||||
#endif
|
||||
@ -242,11 +246,11 @@ void breakHere() {
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
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(&g3::FileSink::fileName);
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle= worker->addDefaultLogger(argv[0], path_to_log_file);
|
||||
g3::initializeLogging(worker.get());
|
||||
std::future<std::string> log_file_name = handle->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"
|
||||
|
@ -55,7 +55,8 @@ int main(int argc, char **argv)
|
||||
|
||||
using namespace g3;
|
||||
|
||||
std::unique_ptr<LogWorker> logworker {LogWorker::createWithNoSink()};
|
||||
|
||||
std::unique_ptr<LogWorker> logworker {LogWorker::createLogWorker()};
|
||||
auto sinkHandle = logworker->addSink(std2::make_unique<FileSink>(argv[0], path_to_log_file),
|
||||
&FileSink::fileWrite);
|
||||
|
||||
|
@ -27,14 +27,9 @@
|
||||
namespace g3 {
|
||||
class LogWorker;
|
||||
struct LogWorkerImpl;
|
||||
using FileSinkHandle = g3::SinkHandle<g3::FileSink>;
|
||||
|
||||
struct DefaultFileLogger {
|
||||
DefaultFileLogger(const std::string &log_prefix, const std::string &log_directory);
|
||||
std::unique_ptr<LogWorker> worker;
|
||||
std::unique_ptr<g3::SinkHandle<g3::FileSink>> sink;
|
||||
|
||||
};
|
||||
|
||||
/// Background side of the LogWorker. Internal use only
|
||||
struct LogWorkerImpl final {
|
||||
typedef std::shared_ptr<g3::internal::SinkWrapper> SinkWrapperPtr;
|
||||
std::vector<SinkWrapperPtr> _sinks;
|
||||
@ -46,33 +41,60 @@ namespace g3 {
|
||||
void bgSave(g3::LogMessagePtr msgPtr);
|
||||
void bgFatal(FatalMessagePtr msgPtr);
|
||||
|
||||
LogWorkerImpl(const LogWorkerImpl &) = delete;
|
||||
LogWorkerImpl &operator=(const LogWorkerImpl &) = delete;
|
||||
LogWorkerImpl(const LogWorkerImpl&) = delete;
|
||||
LogWorkerImpl& operator=(const LogWorkerImpl&) = delete;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Front end of the LogWorker. API that is usefule is
|
||||
/// addSink( sink, default_call ) which returns a handle to the sink. See below and REAME for usage example
|
||||
/// save( msg ) : internal use
|
||||
/// fatal ( fatal_msg ) : internal use
|
||||
class LogWorker final {
|
||||
LogWorker() = default;
|
||||
void addWrappedSink(std::shared_ptr<g3::internal::SinkWrapper> wrapper);
|
||||
|
||||
LogWorkerImpl _impl;
|
||||
LogWorker(const LogWorker &) = delete;
|
||||
LogWorker &operator=(const LogWorker &) = delete;
|
||||
LogWorker(const LogWorker&) = delete;
|
||||
LogWorker& operator=(const LogWorker&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
public:
|
||||
~LogWorker();
|
||||
static g3::DefaultFileLogger createWithDefaultLogger(const std::string &log_prefix, const std::string &log_directory);
|
||||
static std::unique_ptr<LogWorker> createWithNoSink();
|
||||
|
||||
/// Creates the LogWorker with no sinks. See exampel below on @ref addSink for how to use it
|
||||
/// if you want to use the default file logger then see below for @ref addDefaultLogger
|
||||
static std::unique_ptr<LogWorker> createLogWorker();
|
||||
|
||||
|
||||
/**
|
||||
A convenience function to add the default g3::FileSink to the log worker
|
||||
|
||||
@param the worker (no, don't put in nullptr here!)
|
||||
@param log_prefix that you want
|
||||
@param log_directory where the log is to be stored.
|
||||
@return a handle for API access to the sink. See the README for example usage
|
||||
|
||||
@verbatim
|
||||
Example:
|
||||
using namespace g3;
|
||||
std::unique_ptr<LogWorker> logworker {LogWorker::createLogWorker()};
|
||||
auto handle = addDefaultLogger("my_test_log", "/tmp");
|
||||
initializeLogging(logworker.get()); // ref. g3log.hpp
|
||||
|
||||
std::future<std::string> log_file_name = sinkHandle->call(&FileSink::fileName);
|
||||
std::cout << "The filename is: " << log_file_name.get() << std::endl;
|
||||
// something like: /tmp/
|
||||
*/
|
||||
std::unique_ptr<FileSinkHandle> addDefaultLogger(const std::string& log_prefix, const std::string& log_directory);
|
||||
|
||||
|
||||
/// pushes in background thread (asynchronously) input messages to log file
|
||||
void save(LogMessagePtr entry);
|
||||
|
||||
/// Will push a fatal message on the queue, this is the last message to be processed
|
||||
/// this way it's ensured that all existing entries were flushed before 'fatal'
|
||||
/// Will abort the application!
|
||||
void fatal(FatalMessagePtr fatal_message);
|
||||
|
||||
/// Adds a sink and returns the handle for access to the sink
|
||||
/// @param real_sink unique_ptr ownership is passed to the log worker
|
||||
/// @param call the default call that should receive either a std::string or a LogMessageMover message
|
||||
/// @return handle to the sink for API access. See usage example below at @ref addDefaultLogger
|
||||
template<typename T, typename DefaultLogCall>
|
||||
std::unique_ptr<g3::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) {
|
||||
using namespace g3;
|
||||
@ -81,5 +103,19 @@ namespace g3 {
|
||||
addWrappedSink(sink);
|
||||
return std2::make_unique<SinkHandle<T>> (sink);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// internal:
|
||||
/// pushes in background thread (asynchronously) input messages to log file
|
||||
void save(LogMessagePtr entry);
|
||||
|
||||
/// internal:
|
||||
// pushes a fatal message on the queue, this is the last message to be processed
|
||||
/// this way it's ensured that all existing entries were flushed before 'fatal'
|
||||
/// Will abort the application!
|
||||
void fatal(FatalMessagePtr fatal_message);
|
||||
|
||||
|
||||
};
|
||||
} // g3
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
|
||||
* with no warranties. This code is yours to share, use and modify with no
|
||||
* strings attached and no restrictions or obligations.
|
||||
*
|
||||
*
|
||||
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
|
||||
* ============================================================================*/
|
||||
|
||||
@ -26,7 +26,7 @@ namespace g3 {
|
||||
void LogWorkerImpl::bgSave(g3::LogMessagePtr msgPtr) {
|
||||
std::unique_ptr<LogMessage> uniqueMsg(std::move(msgPtr.get()));
|
||||
|
||||
for (auto &sink : _sinks) {
|
||||
for (auto& sink : _sinks) {
|
||||
LogMessage msg(*(uniqueMsg));
|
||||
sink->send(LogMessageMover(std::move(msg)));
|
||||
}
|
||||
@ -59,7 +59,7 @@ namespace g3 {
|
||||
.append("\nLog content flushed flushed sucessfully to sink\n\n");
|
||||
|
||||
std::cerr << uniqueMsg->message() << std::flush;
|
||||
for (auto &sink : _sinks) {
|
||||
for (auto& sink : _sinks) {
|
||||
LogMessage msg(*(uniqueMsg));
|
||||
sink->send(LogMessageMover(std::move(msg)));
|
||||
}
|
||||
@ -120,17 +120,15 @@ namespace g3 {
|
||||
token_done.wait();
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
std::unique_ptr<LogWorker> LogWorker::createLogWorker() {
|
||||
return std::unique_ptr<LogWorker>(new LogWorker);
|
||||
}
|
||||
|
||||
DefaultFileLogger::DefaultFileLogger(const std::string &log_prefix, const std::string &log_directory)
|
||||
: worker(LogWorker::createWithNoSink())
|
||||
, sink(worker->addSink(std2::make_unique<g3::FileSink>(log_prefix, log_directory), &FileSink::fileWrite)) { }
|
||||
std::unique_ptr<FileSinkHandle>LogWorker::addDefaultLogger(const std::string& log_prefix, const std::string& log_directory) {
|
||||
return addSink(std2::make_unique<g3::FileSink>(log_prefix, log_directory), &FileSink::fileWrite);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // g3
|
||||
|
@ -60,8 +60,10 @@ int main(int argc, char **argv)
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle= worker->addDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(worker.get());
|
||||
|
||||
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
@ -87,7 +89,7 @@ int main(int argc, char **argv)
|
||||
delete [] threads;
|
||||
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
logger_n_handle.worker.reset(); // will flush anything in the queue to file
|
||||
worker.reset(); // will flush anything in the queue to file
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::ShutdownGoogleLogging();
|
||||
#endif
|
||||
|
@ -84,8 +84,9 @@ int main(int argc, char** argv)
|
||||
oss.str(""); // clear the stream
|
||||
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
auto logger_n_handle = g3::LogWorker::createWithDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(logger_n_handle.worker.get());
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle= worker->addDefaultLogger(g_prefix_log_name, g_path);
|
||||
g3::initializeLogging(worker.get());
|
||||
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
@ -120,7 +121,7 @@ int main(int argc, char** argv)
|
||||
|
||||
|
||||
#if defined(G3LOG_PERFORMANCE)
|
||||
logger_n_handle.worker.reset(); // will flush anything in the queue to file
|
||||
worker.reset(); // will flush anything in the queue to file
|
||||
#elif defined(GOOGLE_GLOG_PERFORMANCE)
|
||||
google::ShutdownGoogleLogging();
|
||||
#endif
|
||||
|
@ -111,9 +111,10 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
testing_helpers::ScopedOut scopedCerr(std::cerr, &cerrDump);
|
||||
|
||||
auto logger = g3::LogWorker::createWithDefaultLogger("ReplaceLogFile", name_path_1);
|
||||
g_logger_ptr = logger.worker.get();
|
||||
g_filesink_handler = logger.sink.get();
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle= worker->addDefaultLogger("ReplaceLogFile", name_path_1);
|
||||
g_logger_ptr = worker.get();
|
||||
g_filesink_handler = handle.get();
|
||||
last_log_file = g_filesink_handler->call(&g3::FileSink::fileName).get();
|
||||
cleaner.addLogToClean(last_log_file);
|
||||
|
||||
|
@ -198,7 +198,7 @@ TEST(Basics, DoNotShutdownActiveLogger) {
|
||||
{
|
||||
RestoreFileLogger logger(log_directory);
|
||||
LOG(INFO) << "Not yet shutdown. This message should make it";
|
||||
std::unique_ptr<g3::LogWorker> duplicateLogWorker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> duplicateLogWorker{g3::LogWorker::createLogWorker()};
|
||||
EXPECT_FALSE(g3::internal::shutDownLoggingForActiveOnly(duplicateLogWorker.get()));
|
||||
LOG(INFO) << "Logger is (NOT) shutdown,. this message WILL make it";
|
||||
file_content = logger.resetAndRetrieveContent();
|
||||
|
@ -33,7 +33,7 @@ TEST(DynamicLoadOfLibrary, JustLoadAndExit) {
|
||||
std::vector<std::string> receiver;
|
||||
|
||||
{ // scope to flush logs at logworker exit
|
||||
auto worker = g3::LogWorker::createWithNoSink();
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle = worker->addSink(std2::make_unique<LogMessageCounter>(std::ref(receiver)), &LogMessageCounter::countMessages);
|
||||
|
||||
// add another sink just for more throughput of data
|
||||
|
@ -28,7 +28,7 @@ using namespace g3;
|
||||
AtomicBoolPtr flag = make_shared < atomic<bool >> (false);
|
||||
AtomicIntPtr count = make_shared < atomic<int >> (0);
|
||||
{
|
||||
auto worker = g3::LogWorker::createWithNoSink();
|
||||
auto worker = g3::LogWorker::createLogWorker();
|
||||
auto handle = worker->addSink(std2::make_unique<ScopedSetTrue>(flag, count), &ScopedSetTrue::ReceiveMsg);
|
||||
EXPECT_FALSE(flag->load());
|
||||
EXPECT_TRUE(0 == count->load());
|
||||
@ -61,7 +61,7 @@ TEST(ConceptSink, OneHundredSinks) {
|
||||
|
||||
{
|
||||
RestoreFileLogger logger{"./"};
|
||||
g3::LogWorker* worker = logger._scope->get(); //g3LogWorker::createWithNoSink();
|
||||
g3::LogWorker* worker = logger._scope->get(); //g3LogWorker::createLogWorker();
|
||||
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<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createLogWorker()};
|
||||
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<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createLogWorker()};
|
||||
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<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createLogWorker()};
|
||||
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<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createLogWorker()};
|
||||
auto handle = worker->addSink(std2::make_unique<IntReceiver>(&counter), &IntReceiver::receiveMsgDoNothing);
|
||||
std::future<int> intFuture1 = handle->call(&IntReceiver::incrementAtomic);
|
||||
EXPECT_EQ(intFuture1.get(), 1);
|
||||
@ -210,7 +210,7 @@ TEST(ConceptSink, AggressiveThreadCallsDuringShutdown) {
|
||||
for (size_t create = 0; create < numberOfCycles; ++create) {
|
||||
std::cout << create << " ";
|
||||
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createWithNoSink()};
|
||||
std::unique_ptr<g3::LogWorker> worker{g3::LogWorker::createLogWorker()};
|
||||
auto handle = worker->addSink(std2::make_unique<IntReceiver>(&atomicCounter), &IntReceiver::receiveMsgIncrementAtomic);
|
||||
g3::initializeLogging(worker.get());
|
||||
|
||||
|
@ -102,7 +102,7 @@ namespace testing_helpers {
|
||||
}
|
||||
}
|
||||
|
||||
ScopedLogger::ScopedLogger() : _currentWorker(g3::LogWorker::createWithNoSink()) {}
|
||||
ScopedLogger::ScopedLogger() : _currentWorker(g3::LogWorker::createLogWorker()) {}
|
||||
ScopedLogger::~ScopedLogger() {}
|
||||
|
||||
g3::LogWorker* ScopedLogger::get() {
|
||||
|
Loading…
Reference in New Issue
Block a user