G3log is an asynchronous, "crash safe", logger that is easy to use with default logging sinks or you can add your own. G3log is made with plain C++14 (C++11 support up to release 1.3.2) with no external libraries (except gtest used for unit tests). G3log is made to be cross-platform, currently running on OSX, Windows and several Linux distros. See Readme below for details of usage.

Overview

G3log : Asynchronous logger with Dynamic Sinks

EXAMPLE Project with g3log

An example project integration of g3log, both statially and dynamically built can be found at g3log_example_integration

EXAMPLE USAGE

Optional to use either streaming or printf-like syntax

LOG(INFO) << "streaming API is as easy as ABC or " << 123;

LOGF(WARNING, "Printf-style syntax is also %s", "available");

Content

What G3Log is

  • 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]
  • 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.

Conditional logging

int less = 1; int more = 2
LOG_IF(INFO, (less<more)) <<"If [true], then this text will be logged";

// or with printf-like syntax
LOGF_IF(INFO, (less<more), "if %d<%d then this text will be logged", less,more);

Design-by-Contract

CHECK(false) will trigger a "fatal" message. It will be logged, and then the application will exit.

CHECK(less != more); // not FATAL
CHECK(less > more) << "CHECK(false) triggers a FATAL message";

Detailed API documentation

Please look at API.markdown for detailed API documentation

Benefits you get when using G3log

  1. Easy to use, clean syntax and a blazing fast logger.

  2. All the slow log I/O disk access is done in a background thread. This ensures that the LOG caller can immediately continue with other tasks and do not have to wait for the LOG call to finish.

  3. G3log provides logging, Design-by-Contract [#CHECK], and flush of log to file at shutdown. Buffered logs will be written to the sink before the application shuts down.

  4. It is thread safe, so using it from multiple threads is completely fine.

  5. It is CRASH SAFE. It will save the made logs to the sink before it shuts down. The logger will catch certain fatal events (Linux/OSX: signals, Windows: fatal OS exceptions and signals) , so if your application crashes due to, say a segmentation fault, SIGSEGV, it will log and save the crash and all previously buffered log entries before exiting.

  6. It is cross platform. Tested and used by me or by clients on OSX, Windows, Ubuntu, CentOS

  7. G3log and G2log are used worldwide in commercial products as well as hobby projects. G2log is used since early 2011.

  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 g3log exists.

    • This version: 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++14 support (C++11 support up to version: https://github.com/KjellKod/g3log/releases/tag/1.3.1).
    • 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. Currently there is not active development or support on g2log but feel free to shoot me a question if you need assistance.

G3log with sinks

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

It is crazy simple to create a custom sink. This example show what is needed to make a custom sink that is using custom log formatting but only using that for adding color to the default log formatting. The sink forwards the colored log to cout

// in file Customsink.hpp
#pragma once
#include <string>
#include <iostream>
#include <g3log/logmessage.hpp>

struct CustomSink {

// Linux xterm color
// http://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal
  enum FG_Color {YELLOW = 33, RED = 31, GREEN=32, WHITE = 97};

  FG_Color GetColor(const LEVELS level) const {
     if (level.value == WARNING.value) { return YELLOW; }
     if (level.value == DEBUG.value) { return GREEN; }
     if (g3::internal::wasFatal(level)) { return RED; }

     return WHITE;
  }

  void ReceiveLogMessage(g3::LogMessageMover logEntry) {
     auto level = logEntry.get()._level;
     auto color = GetColor(level);

     std::cout << "\033[" << color << "m"
       << logEntry.get().toString() << "\033[m" << std::endl;
  }
};

// in main.cpp, main() function

auto sinkHandle = logworker->addSink(std::make_unique<CustomSink>(),
                                     &CustomSink::ReceiveLogMessage);

Adding and Removing Sinks

You can safely remove and add sinks during the running of your program.

Keep in mind

  • Initialization of the logger should happen before you have started any other threads that may call the logger.
  • Destruction of the logger (RAII concept) should happen AFTER shutdown of other threads that are calling the logger.

Adding Sinks

   auto sinkHandle1 = logworker->addSink(std::make_unique<CustomSink>(),
                                          &CustomSink::ReceiveLogMessage);
   auto sinkHandle2 = logworker->addDefaultLogger(argv[0],
                                              path_to_log_file);
   logworker->removeSink(std::move(sinkHandle1)); // this will in a thread-safe manner remove the sinkHandle1
   logworker->removeAllSinks(); // this will in a thread-safe manner remove any sinks. 

More sinks can be found in the repository github.com/KjellKod/g3sinks.

Code Examples

Example usage where a custom sink is added. A function is called though the sink handler to the actual sink object.

// main.cpp
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>
#include <memory>

#include "CustomSink.h"

int main(int argc, char**argv) {
   using namespace g3;
   std::unique_ptr<LogWorker> logworker{ LogWorker::createLogWorker() };
   auto sinkHandle = logworker->addSink(std::make_unique<CustomSink>(),
                                          &CustomSink::ReceiveLogMessage);

   // initialize the logger before it can receive LOG calls
   initializeLogging(logworker.get());
   LOG(WARNING) << "This log call, may or may not happend before"
                << "the sinkHandle->call below";


   // You can call in a thread safe manner public functions on your sink
   // The call is asynchronously executed on your custom sink.
   std::future<void> received = sinkHandle->call(&CustomSink::Foo,
                                                 param1, param2);

   // If the LogWorker is initialized then at scope exit the g3::internal::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:
   g3::internal::shutDownLogging();
}


// some_file.cpp : To show how easy it is to get the logger to work
// in other parts of your software

#include <g3log/g3log.hpp>

void SomeFunction() {
   ...
   LOG(INFO) << "Hello World";
}

Example usage where a the default file logger is used and a custom sink is added

// main.cpp
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>
#include <memory>

#include "CustomSink.h"

int main(int argc, char**argv) {
   using namespace g3;
   auto worker = LogWorker::createLogWorker();
   auto defaultHandler = worker->addDefaultLogger(argv[0],
                                                 path_to_log_file);

   // logger is initialized
   g3::initializeLogging(worker.get());

   LOG(DEBUG) << "Make log call, then add another sink";

   worker->addSink(std::make_unique<CustomSink>(),
                                  &CustomSink::ReceiveLogMessage);

   ...
}

Building G3log

git clone https://github.com/KjellKod/g3log
cd g3log
mkdir build
cd build

Prerequisites

Assume you have got your shiny C++14 compiler installed, you also need these tools to build g3log from source:

  • CMake (Required)

    g3log uses CMake as a one-stop solution for configuring, building, installing, packaging and testing on Windows, Linux and OSX.

  • Git (Optional but Recommended)

    When building g3log it uses git to calculate the software version from the commit history of this repository. If you don't want that, or your setup does not have access to git, or you download g3log source archive from the GitHub Releases page so that you do not have the commit history downloaded, you can instead pass in the version as part of the CMake build arguments. See this issue for more information.

    cmake -DVERSION=1.3.2  ..
    

Configuration Options

g3log provides following CMake options (and default values):

$ cmake -LAH # List non-advanced cached variables. See `cmake --help` for more details.

...

// Fatal (fatal-crashes/contract) examples
ADD_FATAL_EXAMPLE:BOOL=ON

// g3log performance test
ADD_G3LOG_BENCH_PERFORMANCE:BOOL=OFF

// g3log unit tests
ADD_G3LOG_UNIT_TEST:BOOL=OFF

// Use DBUG logging level instead of DEBUG.
// By default DEBUG is the debugging level
CHANGE_G3LOG_DEBUG_TO_DBUG:BOOL=OFF

// Specifies the build type on single-configuration generators.
// Possible values are empty, Debug, Release, RelWithDebInfo, MinSizeRel, …
CMAKE_BUILD_TYPE:STRING=

// Install path prefix, prepended onto install directories.
// This variable defaults to /usr/local on UNIX
// and c:/Program Files/${PROJECT_NAME} on Windows.
CMAKE_INSTALL_PREFIX:PATH=

// The prefix used in the built package.
// On Linux, if this option is not set:
// 1) If CMAKE_INSTALL_PREFIX is given, then it will be
//    set with the value of CMAKE_INSTALL_PREFIX by g3log.
// 2) Otherwise, it will be set as /usr/local by g3log.
CPACK_PACKAGING_INSTALL_PREFIX:PATH=

// Enable Visual Studio break point when receiving a fatal exception.
// In __DEBUG mode only
DEBUG_BREAK_AT_FATAL_SIGNAL:BOOL=OFF

// Vectored exception / crash handling with improved stack trace
ENABLE_FATAL_SIGNALHANDLING:BOOL=ON

// Vectored exception / crash handling with improved stack trace
ENABLE_VECTORED_EXCEPTIONHANDLING:BOOL=ON

// iOS version of library.
G3_IOS_LIB:BOOL=OFF

// Log full filename
G3_LOG_FULL_FILENAME:BOOL=OFF

// Build shared library
G3_SHARED_LIB:BOOL=ON

// Build shared runtime library MSVC
G3_SHARED_RUNTIME:BOOL=ON

// Turn ON/OFF log levels.
// An disabled level will not push logs of that level to the sink.
// By default dynamic logging is disabled
USE_DYNAMIC_LOGGING_LEVELS:BOOL=OFF

// Use dynamic memory for message buffer during log capturing
USE_G3_DYNAMIC_MAX_MESSAGE_SIZE:BOOL=OFF

...

For additional option context and comments please also see Options.cmake

If you want to leave everything as it was, then you should:

cmake ..

You may also specify one or more of those options listed above from the command line. For example, on Windows:

cmake .. -G "Visual Studio 15 2017"
         -DG3_SHARED_LIB=OFF
         -DCMAKE_INSTALL_PREFIX=C:/g3log
         -DADD_G3LOG_UNIT_TEST=ON
         -DADD_FATAL_EXAMPLE=OFF

will use a Visual Studio 2017 solution generator, build g3log as a static library, headers and libraries will be installed to C:\g3log when installed from source, enable unit testing, but do not build fatal example.

MinGW users on Windows may find they should use a different generator:

cmake .. -G "MinGW Makefiles"

By default, headers and libraries will be installed to /usr/local on Linux when installed from build tree via make install. You may overwrite it by:

cmake .. -DCMAKE_INSTALL_PREFIX=/usr

This will install g3log to /usr instead of /usr/local.

Linux/OSX package maintainers may be interested in the CPACK_PACKAGING_INSTALL_PREFIX. For example:

cmake .. -DCPACK_PACKAGING_INSTALL_PREFIX=/usr/local

Build Commands

Once the configuration is done, you may build g3log with:

# Suppose you are still in the `build` directory. I won't repeat it anymore!
cmake --build . --config Release

You may also build it with a system-specific way.

On Linux, OSX and MinGW:

make

On Windows:

msbuild g3log.sln /p:Configuration=Release

Windows users can also open the generated Visual Studio solution file and build it happily.

Installation

Install from source in a CMake way:

cmake --build . --target install

Linux users may also use:

sudo make install

You may also create a package first and install g3log with it. See the next section.

Packaging

A CMake way:

cmake --build . --config Release --target package

or

cpack -C Release

if the whole library has been built in the previous step. It will generate a ZIP package on Windows, and a DEB package on Linux.

Linux users may also use a Linux way:

make package

If you want to use a different package generator, you should specify a -G option.

On Windows:

cpack -C Release -G NSIS;7Z

this will create a installable NSIS package and a 7z package.

Note: To use the NSIS generator, you should install NSIS first.

On Linux:

cpack -C Release -G TGZ

this will create a .tar.gz archive for you.

Once done, you may install or uncompress the package file to the target machine. For example, on Debian or Ubuntu:

sudo dpkg -i g3log-<version>-Linux.deb

will install the g3log library to CPACK_PACKAGING_INSTALL_PREFIX.

Testing

By default, tests will not be built. To enable unit testing, you should turn on ADD_G3LOG_UNIT_TEST.

Suppose the build process has completed, then you can run the tests with:

ctest -C Release

or:

make test

for Linux users. or for a detailed gtest output of all the tests:

cd build;
../scripts/runAllTests.sh

CMake module

g3log comes with a CMake module. Once installed, it can be found under ${CMAKE_INSTALL_PREFIX}/lib/cmake/g3log. Users can use g3log in a CMake-based project this way:

find_package(g3log CONFIG REQUIRED)
target_link_libraries(main PRIVATE g3log)

To make sure that CMake can find g3log, you also need to tell CMake where to search for it:

cmake .. -DCMAKE_PREFIX_PATH=<g3log's install prefix>

Overview of the API description

Most of the API that you need for using g3log is described in this readme. For more API documentation and examples please continue to read the API readme. Examples of what you will find here are:

  • Sink creation and utilization
  • Logging levels
    • disable/enabled levels at runtime
    • custom logging levels
  • Fatal handling
    • custom fatal handling
    • pre fatal hook
    • override of signal handling
    • disable fatal handling
  • LOG calls
  • CHECK calls

Performance

G3log aims to keep all background logging to sinks with as little log overhead as possible to the logging sink and with as small "worst case latency" as possible. For this reason g3log is a good logger for many systems that deal with critical tasks. Depending on platform the average logging overhead will differ. On my 2010 laptop the average call, when doing extreme performance testing, will be about ~2 us.

The worst case latency is kept stable with no extreme peaks, in spite of any sudden extreme pressure. I have a blog post regarding comparing worst case latency for g3log and other loggers which might be of interest. You can find it here: https://kjellkod.wordpress.com/2015/06/30/the-worlds-fastest-logger-vs-g3log/

Feedback

If you like this logger (or not) it would be nice with some feedback. That way I can improve g3log and g2log and it is also nice to see if someone is using it.

If you have ANY questions or problems please do not hesitate in contacting me on my blog http://kjellkod.wordpress.com/2011/11/17/kjellkods-g2log-vs-googles-glog-are-asynchronous-loggers-taking-over
or at Hedstrom at KjellKod dot cc

Say Thanks

This logger is available for free and all of its source code is public domain. A great way of saying thanks is to send a donation. It would go a long way not only to show your support but also to boost continued development.

Donate

  • $5 for a cup of coffee
  • $10 for pizza
  • $25 for a lunch or two
  • $100 for a date night with my wife (which buys family credit for evening coding)
  • $$$ for upgrading my development environment
  • $$$$ :)

Cheers

Kjell (a.k.a. KjellKod)

Comments
  • g3log hangs on a dll

    g3log hangs on a dll

    I have been trying to make g3log run on a DLL of my own but the DLL hangs the entire application.

    I have tried the following:

    • Defining a namespace with the variables as for #88 and #91 (Initializing logging on DLL_PROCESS_ATTACH and reseting the logger on DLL_PROCESS_DETACH)
    • Same as above but initializing at DllMain (using std::call_once).
    • Defining and initializing globally.

    On all situations the program using my DLL hangs at startup without writing anything.

    Any feedback is welcome!

    invalid question dismissed 
    opened by fmiceli24 34
  • g3Log Crashes the Application

    g3Log Crashes the Application

    If I initialize and log in sample cpp program having main method, it works properly but when I integrated in my dll project where there is no main method but I have method which I call firstly where i have followed the same code as explained in “https://github.com/KjellKod/g3log/issues/88#issuecomment-219030139”. It generates the log properly but immediately my java’s GUI system get crashed and I get the same error. Please help me to get rid of this.

    namespace {
    static std::once_flag g_initLogger;
    static std::unique_ptr g_logger;
    static std::unique_ptr g_loggerHandle;
    } // namespace
    
    void InitializeLogging(const std::string& logPrefix, const std::string& logPath) {
    std::call_once(g_initLogger, [&] {
    g_logger = g3::LogWorker::createLogWorker();
    g_loggerHandle = g_logger->addDefaultLogger(logPrefix, logPath);
    g3::initializeLogging(g_logger.get());
    });
    }
    bool IsLoggerEnabled() {
    return g3::internal::isLoggingInitialized();
    }
    
    void ShutdownLogging() {
    //g3::internal::shutDownLogging(); // HERE I HAVE commented as I calls internally
    g_logger.reset();
    }
    
    I CALL ABOVE METHODS IN MY METHOD WHICH I CALL IT FROM MY GUI TOOL BUILT IN JAVA
    
    JNIEXPORT jobjectArray JNICALL Java_com_mydll_loadDLLGetVersion(JNIEnv *env, jobject thisObj)
    {
    int versionNumber = 0;
    string resultStr;
    jobjectArray jresultStr = (*env).NewObjectArray(3, (*env).FindClass(“java/lang/String”), NULL);
    
    try
    {
    // Tried initializing here too however it is crashing
    /*
    auto worker = g3::LogWorker::createLogWorker();
    auto handle = worker->addDefaultLogger(“MyG3Log_”, “D:\\G3Logs\\”);
    g3::initializeLogging(worker.get());
    */
    InitializeLogging(“MyG3Log_”, “D:\\G3Logs\\”);
    
    LOG(INFO) << "Hello1";
    LOG(INFO) << "Hello2";
    LOG(INFO) << "Hello3";
    LOG(INFO) << "Hello4";
    LOG(INFO) << "Hello5";
    LOG(INFO) << "Hello6";
    LOG(INFO) << "Hello7";
    
    ShutdownLogging();
    }
    }
    catch (exception& e)
    {
    if(handleDLL != NULL) {
    UnloadDLLAPI(handleDLL);
    }
    resultStr += ";";
    resultStr += e.what();
    }
    return jresultStr;
    }
    
    

    I GET BELOW ERROR FROM g3Log

    g3log g3FileSink shutdown at: 15:42:22
    Log file at: [D:/G3Logs/MyG3Log_20190307-154222.log]
    
    FATAL CALL but logger is NOT initialized
    CAUSE: EXCEPTION_ACCESS_VIOLATION
    Message:
    2019/03/07 15:42:56
    
    ***** FATAL EXCEPTION RECEIVED *******
    
    ***** Vectored Exception Handler: Received fatal exception EXCEPTION_ACCESS_VIOLATION	PID: 13048
    
    *******	STACKDUMP *******
    stack dump [0]
    stack dump [1]
    stack dump [2]
    stack dump [3]
    stack dump [4]
    stack dump [5]
    stack dump [6]
    stack dump [7]
    stack dump [8]
    stack dump [9]
    stack dump [10]
    stack dump [11]
    stack dump [12]
    stack dump [13]
    stack dump [14]
    stack dump [15]
    

    I initialized the worker in the method however it crashed the application by throwing fatal errors. I tried to look up all your forums and documentation but i found nothing. As per my understanding i have implemented g3log like below :

    Mymethod(){
    Step 1. Initialized worker
    Strp 2. Log statement to print logs in file.
    Step 3. Worker.reset() or g3::internal::shutDownLogging()
    
    // my other application related businesses logic
    }
    

    Please accept my sincere apologies as I am new to CPP and I tried to find everything in your source code but all time it crashed my application.

    Please help.

    invalid dismissed user that needs assistance 
    opened by Mahendrakumar1985 27
  • Fix several CMake Issues

    Fix several CMake Issues

    Since g3log uses some kind of mixed "old" style CMake, it makes it problematic to use in other "modern" cmake projects. Although it is already CMake 3.1 is required, I tries to transform mainly the Build.cmake to conform with modern CMake style, particularly using target specific compile options. This avoids an unwanted pollution of the flags for other parts of bigger projects.

    I tried to keep the whole logic of compile flags for different platforms, moreover g3log now also build cleanly with the musl c-lib. Caused by the lack of other development systems and time, I only checked the CMake scripts in Linux with GCC and Clang but no Windows or OSX.

    Moreover, all other cmake-scripts should be reviewed for better compliance.

    opened by BenjaminBeichler 27
  • Windows build issues with CMAKE

    Windows build issues with CMAKE

    It has been sometime since I last pulled but in the past static and shared build used to work correctly. Now whatever you choose you get a shared build (in windows and probably in any other platform as well).

    It is pretty clear from the new cmake that the library is always shared ADD_LIBRARY(${G3LOG_LIBRARY} SHARED ${SRC_FILES})

    Instead it should have been something along the lines of

       IF (G3LOG_BUILD_SHARED)
         ADD_LIBRARY(${G3LOG_LIBRARY} SHARED ${SRC_FILES})
       ELSE
         ADD_LIBRARY(${G3LOG_LIBRARY} STATIC ${SRC_FILES})
    

    Also it seems that only 1 project is generated and not 2 compared to the past. Nothing wrong with that but then the flag ADD_BUILD_WIN_SHARED is kind of misleading since you never really add another build but instead the ADD_BUILD_WIN_SHARED flag is only handled to export the symbols. If you want to have a shared build in MSVC that is the only way to export the symbols, unless you go down the path of __declspec(dllexport) and __declspec(dllimport). So if it is MSVC and someone wants to have a shared build this should be set always set set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) If cmake < 3.4 the cmake should fail since the shared build wont be usable as no symbols are exported.

    enhancement 
    opened by cstamatopoulos 22
  • Exception in msvc2013

    Exception in msvc2013

    I am not sure why this happens but the code below throws an exception in msvc2013 but it is all good in 2015. The exception is thrown at the lock in shutDownLogging.

    auto worker = g3::LogWorker::createLogWorker();
    
    int main(int argc, char* argv[])
    {
        using namespace g3;
        auto defaultHandler = worker->addDefaultLogger(argv[0], "./");
        g3::initializeLogging(worker.get());
    }
    

    Now you might ask why someone would want to do that but unfortunately for old apps with MFC there is no main function, just a WinMain which you dont have access to.

    opened by cstamatopoulos 18
  • Missing import lib on windows dll

    Missing import lib on windows dll

    Hi,

    When compiling the VC2013 solution, there's no g3logger_shared.lib generated.

    Looking into the solution, i see no definition file or /EXPORT compiler flag or __declspec(export) into g2log.hpp, so VC2013 does not generate import lib (see https://msdn.microsoft.com/en-us/library/67wc07b9.aspx for more information).

    enhancement help wanted 
    opened by pendenaor 18
  • Adding custom log levels to dynamic logging

    Adding custom log levels to dynamic logging

    Hi KjellKod Thanks for your great logger. There is one issue I don't find a way to solve: I have defined additional debug levels (e.g. LEVELS ERROR) and want to activate/deactivate them dynamically. But as far I can see one can only do it for the preconfigured log levels (INFO, WARNING etc.) because there seems to be no way to add custom LEVELS to g_log_level_status in loglevels.cpp. Or am I overlooking something?! Thanks

    enhancement question 
    opened by Jawan81 17
  • Program crashed when worker not define in local

    Program crashed when worker not define in local

    When I run the following code

    #include "g3log/logworker.hpp"
    
    std::unique_ptr<g3::LogWorker> worker;
    
    int main(int argc, const char * argv[]) {
        worker = g3::LogWorker::createLogWorker();
        return 0;
    }
    

    the program crash when exit(after return 0). Is this acceptable? Besides, if I put the define of worker in main. No crash. Thanks.

    I've test in VS2013 and Xcode. Both crashed. the xcode message

    LOGGER NOT INITIALIZED:
            Hello
    libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: mutex lock failed: Invalid argument
    

    stack trace:

    #0  0x00007fff95f55f06 in __pthread_kill ()
    #1  0x00000001000a842d in pthread_kill ()
    #2  0x00007fff8a8446e7 in abort ()
    #3  0x00007fff86c14f81 in abort_message ()
    #4  0x00007fff86c3aa2f in default_terminate_handler() ()
    #5  0x00007fff9457e6c3 in _objc_terminate() ()
    #6  0x00007fff86c3819e in std::__terminate(void (*)()) ()
    #7  0x00007fff86c38213 in std::terminate() ()
    #8  0x0000000100001d6f in __clang_call_terminate ()
    #9  0x000000010000fbb8 in g3::LogWorker::~LogWorker() ()
    #10 0x0000000100001c83 in std::__1::default_delete<g3::LogWorker>::operator()(g3::LogWorker*) const [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2516
    #11 0x0000000100001c68 in std::__1::unique_ptr<g3::LogWorker, std::__1::default_delete<g3::LogWorker> >::reset(g3::LogWorker*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2715
    #12 0x0000000100001c0b in std::__1::unique_ptr<g3::LogWorker, std::__1::default_delete<g3::LogWorker> >::~unique_ptr() [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2683
    #13 0x0000000100001bfb in std::__1::unique_ptr<g3::LogWorker, std::__1::default_delete<g3::LogWorker> >::~unique_ptr() at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2683
    #14 0x00007fff8a84546b in __cxa_finalize_ranges ()
    #15 0x00007fff8a84576f in exit ()
    #16 0x00007fff8f4315b4 in start ()
    #17 0x00007fff8f4315ad in start ()
    
    opened by cztchoice 17
  • Enable an install target

    Enable an install target

    Should work fine on Unix systems, and support install prefixes. Installs both a static and a shared library to the same location, so we get an .a and a .so/.dylib file, which can be linked to in the ordinary way, ie. -lg3logger.

    As discussed in #49

    More work could be done, but for now I think we need some basic support added.

    opened by hansarnholm 15
  • new feature:  dynamic logging level per file or class

    new feature: dynamic logging level per file or class

    Being able to change the logging level that is active but on a file or class (or some other unique identifier)

    --- The purpose is to be able to at runtime specify that instances (files, class or similar) can get increased or decreased active logging levels.

    enhancement 
    opened by KjellKod 15
  • Improve CMake module file

    Improve CMake module file

    I am trying to add g3log to vcpkg: https://github.com/Microsoft/vcpkg/pull/5961 these days, and encountered some issues:

    • Lack of install target on Win32
    • The g3loggerConfig.cmake doesn't work out on Win32
    • The g3loggerConfig.cmake only takes care of SHARED library
    opened by myd7349 14
  • Function name much more verbose than before

    Function name much more verbose than before

    I updated recently to g3log 2.1.0 from 1.3.4 in order to support C++20.

    Since then, I realised that our logs are much more verbose. Here an example.

    1.3.4 2022-03-23-08:11:47,521327 | INFO | Workstation ID: 1 activated | AssemblerHardwareControler.cpp->adam::AssemblerHardwareControler::makeHardwareControler:125

    2.1.0 2022-11-23-08:50:43,603630 | INFO | Workstation ID: 1 activated | AssemblerHardwareController.cpp->static Result<unique_ptr_qobjectadam::WorkstationsList> __cdecl adam::AssemblerHardwareController::makeHardwareControllerDrf(const adam::SoftwareOptions &, const QJsonDocument &):154

    Some of our methods have arguments based on Boost units and since it is very templated, it takes several lines in our logs. Example: 2022-11-22-11:04:27,635036 | ERROR | VacuDAP: Failed setting voltage. Only voltage values between 30 and 150 are allowed. Value sent: 29 | VacuDapHandler.cpp->struct adam::detail::DefaultResult __cdecl adam::VacuDapHandler::SetParameterTubeVoltage(const class boost::units::quantity<class boost::units::unit<struct boost::units::list<struct boost::units::dim<struct boost::units::length_base_dimension,class boost::units::static_rational<2,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::mass_base_dimension,class boost::units::static_rational<1,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::time_base_dimension,class boost::units::static_rational<-3,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::current_base_dimension,class boost::units::static_rational<-1,1> >,struct boost::units::dimensionless_type> > > >,struct boost::units::heterogeneous_system<struct boost::units::heterogeneous_system_impl<struct boost::units::list<struct boost::units::heterogeneous_system_dim<struct boost::units::si::meter_base_unit,class boost::units::static_rational<2,1> >,struct boost::units::list<struct boost::units::heterogeneous_system_dim<struct boost::units::scaled_base_unit<struct boost::units::cgs::gram_base_unit,struct boost::units::scale<10,class boost::units::static_rational<3,1> > >,class boost::units::static_rational<1,1> >,struct boost::units::list<struct boost::units::heterogeneous_system_dim<struct boost::units::si::second_base_unit,class boost::units::static_rational<-3,1> >,struct boost::units::list<struct boost::units::heterogeneous_system_dim<struct boost::units::si::ampere_base_unit,class boost::units::static_rational<-1,1> >,struct boost::units::dimensionless_type> > > >,struct boost::units::list<struct boost::units::dim<struct boost::units::length_base_dimension,class boost::units::static_rational<2,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::mass_base_dimension,class boost::units::static_rational<1,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::time_base_dimension,class boost::units::static_rational<-3,1> >,struct boost::units::list<struct boost::units::dim<struct boost::units::current_base_dimension,class boost::units::static_rational<-1,1> >,struct boost::units::dimensionless_type> > > >,struct boost::units::list<struct boost::units::scale_list_dim<struct boost::units::scale<10,class boost::units::static_rational<3,1> > >,struct boost::units::dimensionless_type> > >,void> const ,double> &):211

    Is it a feature or a bug? ;-)

    Did anything change? I did not find anything in the release notes of 2.0.1 and 2.1.0 mentioning a change in behaviour.

    under investigation 
    opened by morph208 3
  • [Question] Different levels for different domain

    [Question] Different levels for different domain

    HI,

    I am trying to figure what would be the best strategy to support having different level for different domains. For example, lets says I want to debug networking things in my code I would want to set a lower level but just the log entries corresponding to my networking stack.

    Using different log system instance would work but I understand that this is not supported.

    Another method is to use different specialized sink(s) and use the LEVEL space by allocating different ranges to different domains. This would work but appears to be a kludge.

    But is there another strategy / feature that I am not aware of?

    question 
    opened by clauderobi 7
  • Mac Os stack dump is not correctly demangled because of different format

    Mac Os stack dump is not correctly demangled because of different format

    https://github.com/KjellKod/g3log/blob/5adecb5ad96b94b426a5d00ca49285ceac973cf0/src/crashhandler_unix.cpp#L160

    See https://stackoverflow.com/questions/52693431/backtrace-info-different-on-macos-v-s-linux for an example of mac os vs Linux.

    Looking for parenthesis in the string does not work so demangling will also not work.

    enhancement 
    opened by gglowacki 1
Releases(2.1)
  • 2.1(Nov 10, 2022)

    What's Changed

    • exitWithDefaultSignalHandler() should block until signal handler returns by @ablangy in https://github.com/KjellKod/g3log/pull/464

    New Contributors

    • @ablangy made their first contribution in https://github.com/KjellKod/g3log/pull/464 Full Changelog: https://github.com/KjellKod/g3log/compare/2.0.1...2.1
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Nov 6, 2022)

    This is the first release where c++17/20 is supported. Users of c++14 should use g3log 1.3.4.

    What's Changed

    C++17 adjustment

    • Replace std::result_of with std::invoke_result by @Friendly0Fire in https://github.com/KjellKod/g3log/pull/392
    • Avoid copying LOGLEVELS for g3::logLevel call by @lukeocamden in https://github.com/KjellKod/g3log/pull/399

    Platform improvements

    • Fix ARM compilation for windows. by @englercj in https://github.com/KjellKod/g3log/pull/401
    • SOName needs to be less volatile by @Shachar in https://github.com/KjellKod/g3log/pull/402
    • Fix soname 2 by @KjellKod in https://github.com/KjellKod/g3log/pull/404

    Documentation now available at: https://kjellkod.github.io/g3log/

    • Create CODE_OF_CONDUCT.md by @KjellKod in https://github.com/KjellKod/g3log/pull/411
    • Readme improvement by @KjellKod in https://github.com/KjellKod/g3log/pull/441
    • Update PULL_REQUEST_TEMPLATE.md by @KjellKod in https://github.com/KjellKod/g3log/pull/440
    • Create publish_docs.yml by @KjellKod in https://github.com/KjellKod/g3log/pull/442
    • Update API.md by @KjellKod in https://github.com/KjellKod/g3log/pull/446
    • Update index.md by @KjellKod in https://github.com/KjellKod/g3log/pull/447 https://github.com/KjellKod/g3log/pull/449
    • Update mkdocs.yml by @KjellKod in https://github.com/KjellKod/g3log/pull/448 https://github.com/KjellKod/g3log/pull/450 https://github.com/KjellKod/g3log/pull/451 https://github.com/KjellKod/g3log/pull/452 https://github.com/KjellKod/g3log/pull/453 https://github.com/KjellKod/g3log/pull/455
    • Create .ciignore by @KjellKod in https://github.com/KjellKod/g3log/pull/454
    • Update README.md by @KjellKod in https://github.com/KjellKod/g3log/pull/456, @SkiddyToast in https://github.com/KjellKod/g3log/pull/458, @mudream4869 in https://github.com/KjellKod/g3log/pull/460

    Functionality improvements

    • Enable coredump for containerized applications by @hoditohod in https://github.com/KjellKod/g3log/pull/419
    • Fix pretty function magic constant overwriting by @landwehrj in https://github.com/KjellKod/g3log/pull/424

    Bugfix

    • Fixes #428: memory leak in g3::internal::createLogFile by @DlubalSmidJaroslav in https://github.com/KjellKod/g3log/pull/430

    CI, test, build, warnings

    • update gtest zip URL by @KjellKod in https://github.com/KjellKod/g3log/pull/417
    • dummy circle-ci by @KjellKod in https://github.com/KjellKod/g3log/pull/434
    • Delete .travis.yml by @KjellKod in https://github.com/KjellKod/g3log/pull/435
    • updated doc circle ci by @KjellKod in https://github.com/KjellKod/g3log/pull/436
    • Update cmake.yml by @KjellKod in https://github.com/KjellKod/g3log/pull/437
    • fix(cmake): fixes #413 by @zjeffer in https://github.com/KjellKod/g3log/pull/457
    • Resolve noexcept warnings on lambdas by @bmagistro in https://github.com/KjellKod/g3log/pull/463

    New Contributors

    • @Friendly0Fire made their first contribution in https://github.com/KjellKod/g3log/pull/392
    • @lukeocamden made their first contribution in https://github.com/KjellKod/g3log/pull/399
    • @englercj made their first contribution in https://github.com/KjellKod/g3log/pull/401
    • @Shachar made their first contribution in https://github.com/KjellKod/g3log/pull/402
    • @hoditohod made their first contribution in https://github.com/KjellKod/g3log/pull/419
    • @landwehrj made their first contribution in https://github.com/KjellKod/g3log/pull/424
    • @DlubalSmidJaroslav made their first contribution in https://github.com/KjellKod/g3log/pull/430
    • @zjeffer made their first contribution in https://github.com/KjellKod/g3log/pull/457
    • @SkiddyToast made their first contribution in https://github.com/KjellKod/g3log/pull/458
    • @mudream4869 made their first contribution in https://github.com/KjellKod/g3log/pull/460

    Full Changelog: https://github.com/KjellKod/g3log/compare/1.3.4...2.0.1

    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Dec 16, 2020)

    This is a release to give the latest changes for the C++14 community. After this change master will be on C++17/20.

    Minor cleanups

    • compiler warnings, mingw cmake support, typo fixes #389, #390 @alvin-777
    • documentation change #378 @xiaotianrandom
    • bugfix vsnprintf_s, typo fixes #373, #365, #363 @shiyuge
    • documentation improvements #359 @xgdgsc
    Source code(tar.gz)
    Source code(zip)
  • 1.3.3(Jun 7, 2020)

    Documentation changes

    • Numerous changes to API, code examples @KjellKod
    • Cleanup and improvement (#328, #353) @jecaro, @mkilivan

    #Feature improvement

    • Fatal handling (#349), @ripopov
    • Google test dynamic download (#355) @mkilivan

    Cleanup Help

    Debug levels (#259) @DerekJuba-NIST Ambiguous constructor error. (#262) @DigitalInBlue Warning about whitespace (#265) @codekrafter Code Cleanup (#336) @JoelStienlet

    Bug fixing

    • Macro safe calling (#320) @madscientist
    • Windows stacktrace (#334 @lederernc

    Platform support and Build Improvements

    • MinGW / Windows fixes (#260) @tkhyn
    • VS2013, VS2015 improvements (#266, #273, #277, #275, #278, #291, #292, #293 ) @AndreasSchoenle, @outkontroll, @ccvca, @AlexP11223, @cstamatopoulos, @ctapmex
    • CMake improvements (#190, #267, #272, #268, #299, #294, #312, #321 ) @julien-lecomte, @AndreasSchoenle, @mobileben, @MaxSavenkov, @michaelbgratton, @BenjaminBeichler, @myd7349
    • Clang build improvements (#283) @ngladitz
    • CI improvements (#300, #301, #340 ) @KjellKod
    • arm64 support (#307) @mobileben
    • iOS fatal signal handling (#309) @mobileben

    Installation and Project integration

    • project integration (#333,) @bmagistro
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Mar 31, 2018)

    UPDATE: New High-Value Functionality will in the future be ported into this C++11 branch. https://github.com/KjellKod/g3log/tree/c++11-master

    Changes with 1.3.2.

    g3log v.1.3.1 had a CMake error that stopped c++11 only compiler from building. g3log v1.3.2 contains the corrected CMake files.

    Thanks to @esdevcr for providing this patch correction.

    As g3log goes forward the branch 1.3.x will be the "c++11 master branch" in case of future changes.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Mar 3, 2018)

    UPDATE: New High-Value Functionality will in the future be ported into this C++11 branch. https://github.com/KjellKod/g3log/tree/c++11-master

    Summary of changes since version 1.3

    Thanks to the following coders for both major and minor contributions

    • @jkhoogland
    • @AndreasSchoenle
    • @maj-tom
    • @pshurgal
    • @ttencate
    • @mobileben
    • @melion
    • @Jawan81
    • @AndreasSchoenle
    • @ctapmex
    • @spinorx
    • @ze897c
    • @PeasantCodeFarmer
    • @jcfr

    Major changes mentioned below, smaller changes not mentioned.

    Major Improvements

    • Significantly improved CMake options for install options on multiple platforms
    • support for full filenames in logs 226(thanks @spinorx)
    • huge improvements for low granularity of log timestamps on both Windows and Linux 200
    • iOS support 198
    • CMake support for arbitrary, compile time decided max value for the "printf" like logs [208] (https://github.com/KjellKod/g3log/pull/208)

    Major Bugfix:

    • LOG macros and if-statements without curly brances (231
    • doc updates for API and internal code comments

    Noteworthy:

    Thanks to @AndreasSchoenle 191 there is now a branch with WCHAR support. See branch: wchar_support

    Source code(tar.gz)
    Source code(zip)
  • 1.3(Mar 30, 2017)

    Summary of changes since 1.2

    • Greatly improved logging format with nanoseconds support.
    • Added ARM support as well as improved OSX and Windows support
    • Build and API improvements
    • Build and API document improvements

    Contributions

    Thanks to the community for feedback, usage, code and review contributions. The following deserves an extra thank you :) AndreasSchoenle cstamatopoulos ctapmex dasmysh dasmysh d-led jkhoogland kmohanram lynn Nitaym OfekShilon rickyzhang82

    Chronological Summary

    March 2017

    • cpackage improvements : make install and make package
    • improved API and README
    • bugfix nanosecond fractions on 32 bit Windows systems

    February 2017

    • mingw improvements

    January 2017

    • bugfix nanosecond fractions for - OS speifics
    • Visual studio build improvements

    December 2016

    • added support for ARM
    • build and continuous integration updates
    • logging levels improvement
    • unit test corrections for fatal signal handling on Windows
    • cleanup

    October 2016

    • bugfixes
    • logging for Windows improved
    • added unit tests missing for Windows logging levels

    August 2016

    • added nanosecond timestamps to log and improved the logging formatting
    • API and README updated
    • bugfixes

    July 2016

    • cleanup

    June 2016

    • cross compiler linking improvements

    May 2016

    • bugfix for potential deadlock during shutdown

    March 2016

    • log formatting bug corrected.
    Source code(tar.gz)
    Source code(zip)
  • 1.2(Mar 7, 2016)

    Nothing major but it's a good point to call a new g3log release, 1.2, since we have some nice improvement to fatal handling, default logging as well as improved platform support on FreeBSD, Windows, Linux and OSX.

    On Linux we now also have the possibility to do 'make package'. On OSX installation can be done with 'brew install g3log'.

    Summary of changes since 1.1: March Fixed CPackage to work for Linux. Thanks to Hans Duedal #83 FYI: OSX users can now use ‘brew install g3log’

    February Possiblity to override the default ‘g3log’ adding to the file name for the default file logger. Thanks to jkhoogland, pull request #82, issue: ##75 Allowed parenthesis in filename paths. pull request #81, issue ##31 Improved Linux Clang support, pull request: #77

    January cleanup code, removed unused includes: #72

    December API cleanup. pull request: #66 thanks to Lu Guanqun Windows build support, adding debug symbols, pull request #65 thanks to Christos cstamatopoulos\

    November fixed Windows compilation issue with atomic, pull request: #63 thanks to Christos Cstamatopoulos Improved API documentation Readme.markdown and API.markdown, pull requests: #64, #54 default logger will flush after every log entry written. (see github.com/KjellKod/g3sinks for other ways of handling log writing), pull request: #58 CHECK_F and CHECKF exists. CHECK_F is kept for backwards compatiability. improved testing for dynamic logging levels

    October 2015 removed warnings for gcc5, pull request: #55 Added API.markdown to explain in more detail the g3log API suppress 'thread attribute directive ignored' warning on mingw (thands to Turenar )

    September 2015 Override of signal handler (especially useful for zmq users who need this for overriding SIGTERM, pull request #48 default log formatting improved. pull request #52, #50, thanks to Craig Cogdill <date and time> <file>:L<line> to <date and time> <file>-><function>:<line>, Support for FreeBSD, pull request #53,. thanks to Robert Ayrapetyan.

    Source code(tar.gz)
    Source code(zip)
  • v1.1(Sep 10, 2015)

    With this release g3log will:

    1) Gracefully handle aggressive crashing scenarios: Imagine hundreds or throusands of threads starting up and all racing to do a SIGSEGV crash? (On v1.0 that worked fine for Linux/Gcc but for OSX/Clang it did not work well. And the exit of the process could be delayed a very long time)

    2) Improved sink construction and logger initialization API. See example a,b,c below a. Create a logger std::unique_ptr<LogWorker> logworker{ LogWorker::createLogWorker() }

    b) Add of custom sinks (here named "CustomSink")

    auto sinkHandle = logworker->addSink(std2::make_unique<CustomSink>(), 
        &CustomSink::ReceiveLogMessage);
    

    c) Add a default file logging sink (more sinks are available at g3sinks)

    auto handle= worker->addDefaultLogger(prefix, path_to_log_file);
    

    3) Custom logging levels can be created. Please see g3log/loglevels.hpp for the value ranges The example will create a logging level "HEY".

    const LEVELS  HEY {WARNING.value + 1, {"Hey There"}};
    LOG(HEY) << "Hello"
    

    4) A custom pre death hook can be put in place to do custom actions when a fatal event is caught. This should be set after the initialization of the logger (the initialization will otherwise clear it)

              // example showing a simple LOG(INFO) call but it could really be anything
              // After the hook is called it will be cleared so it can only be called once
             // if you need multiple "death cleanup" calls then the best is to bundle them within the allowed callback
            namespace {
            void  Ooops() {
               LOG(INFO) << "Death is imminent";
            }
            } // namespace
    
           .... elsewhere in the code 
              g3::setFatalPreLoggingHook(&Ooops);
    
    Source code(tar.gz)
    Source code(zip)
Owner
Kjell Hedström : Engineering Leadership
https://www.linkedin.com/in/kjellkod
Kjell Hedström : Engineering Leadership
Reckless logging. Low-latency, high-throughput, asynchronous logging library for C++.

Introduction Reckless is an extremely low-latency, high-throughput logging library. It was created because I needed to perform extensive diagnostic lo

Mattias Flodin 443 Dec 1, 2022
📝 Kernel module that can be used as a replacement for logger or logwrapper

Kernel logger Kernel logger is a kernel module that can be used as a replacement for logger or logwrapper. Its log is similar to systemd's journal and

Tian Yuanhao 38 May 21, 2022
Colorful Logging is a simple and efficient library allowing for logging and benchmarking.

Colorful-Logging "Colorful Logging" is a library allowing for simple and efficient logging as well for benchmarking. What can you use it for? -Obvious

Mateusz Antkiewicz 1 Feb 17, 2022
Asynchronous Low Latency C++ Logging Library

Quill Asynchronous Low Latency C++ Logging Library Introduction Features Performance Supported Platforms And Compilers Basic Usage CMake Integration D

Odysseas Georgoudis 671 Nov 30, 2022
Uberlog - Cross platform multi-process C++ logging system

uberlog uberlog is a cross platform C++ logging system that is: Small Fast Robust Runs on Linux, Windows, OSX MIT License Small Two headers, and three

IMQS Software 15 Sep 29, 2022
Windows token logger written in c++ with option of persistence

Windows token logger written in c++ with option of persistence

null 3 Feb 3, 2022
log4cplus is a simple to use C++ logging API providing thread-safe, flexible, and arbitrarily granular control over log management and configuration. It is modelled after the Java log4j API.

% log4cplus README Short Description log4cplus is a simple to use C++17 logging API providing thread--safe, flexible, and arbitrarily granular control

null 1.4k Nov 27, 2022
A DC power monitor and data logger

Hoverboard Power Monitor I wanted to gain a better understanding of the power consumption of my hoverboard during different riding situations. For tha

Niklas Roy 22 May 1, 2021
Android-Syscall-Logger

Android-Syscall-Logger A kernel module that hook some of your system call on your Android Device by rewriting syscall table. Prerequisite pixel 1 andr

null 92 Sep 28, 2021
An Ultra Low Power temperature logger based on the ESP8266 MCU.

Temperature logging IoT node Overview: The real node wired on a breadboard This is an ultra low power (ULP) temperature logging IoT node based on the

Radhi SGHAIER 12 Nov 16, 2022
A simple Keystroke logger written in C++

BufferX A simple keylogger written in C++ Disclaimer: This project is made for knowledge and learning purpose. I am not responsible for any damage , i

Ibne Nahian 2 Aug 18, 2022
zeroEngine Logger Code-Base

zero-logger zeroEngine Logger - Part of zeroSDK Features basic log-levels lightweight unicode support by native wchar_t multibyte chars support platfo

Denis 1 Dec 11, 2021
Building a basic logger from scratch using the C programming language.

Logger Building a basic logger from scratch using the C programming language. Compiling and Running the program: Using the gcc compiler: gcc example.c

Nicolas Gonzalez 1 May 14, 2022
Fast binary logger for C++

Highlights Logs messages in a compact binary format Fast Hundreds of millions of logs per second Average latency of 2-7 ns for basic data types See be

Pranav 173 Nov 26, 2022
Portable, simple and extensible C++ logging library

Plog - portable, simple and extensible C++ logging library Pretty powerful logging library in about 1000 lines of code Introduction Hello log! Feature

Sergey Podobry 1.6k Nov 26, 2022
Minimalistic logging library with threads and manual callstacks

Minimalistic logging library with threads and manual callstacks

Sergey Kosarevsky 21 Jun 24, 2022
A Fast and Convenient C++ Logging Library for Low-latency or Real-time Environments

xtr What is it? XTR is a C++ logging library aimed at applications with low-latency or real-time requirements. The cost of log statements is minimised

null 10 Jul 17, 2022
Yet another logging library.

Blackhole - eating your logs with pleasure Blackhole is an attribute-based logger with strong focus on gaining maximum performance as possible for suc

Evgeny Safronov 189 Dec 2, 2022