Asynchronous Low Latency C++ Logging Library

Quill logo

Quill

Asynchronous Low Latency C++ Logging Library


homebrew vcpkg conan
brew install quill vcpkg install quill quill/[>=1.2.3]

Introduction

Quill is a cross-platform low latency logging library based on C++14.

The main goals of the library are:

  • Simplicity A small example code snippet should be enough to get started and use most of features.
  • Performance Ultra low latency. No formatting on the hot-path, asynchronous only mode. No hot-path allocations for fundamental types, enums and strings (including std::string and std::string_view). Any other custom or user defined type gets copy constructed with the formatting done on a backend worker thread.
  • Convenience Ease application monitoring/debugging. Latency is equal to latencies of binary loggers, but the produced log is in human readable form.

Features

  • Log anything - Blazing fast. See Benchmarks.
  • Format outside of the hot-path in a backend logging thread. For non-built-in types ostream::operator<<() is called on a copy of the object by the backend logging thread. Unsafe to copy non-trivial user defined are detected in compile time. Those types can be tagged as safe-to-copy to avoid formatting them on the hot path. See User Defined Types.
  • Custom formatters. Logs can be formatted based on a user specified pattern. See Formatters.
  • Support for log stack traces. Store log messages in a ring buffer and display later on a higher severity log statement or on demand. See Backtrace Logging.
  • Various logging targets. See Handlers.
    • Console logging with colours support.
    • File Logging
    • Rotating log files
    • Time rotating log files
    • Custom Handlers
  • Filters for filtering log messages. See Filters.
  • guaranteed non-blocking or non-guaranteed logging. In non-guaranteed mode there is no heap allocation of a new queue but log messages can be dropped. See FAQ.
  • Support for wide character logging and wide character filenames (Windows only).
  • Log statements in timestamp order even when produced by different threads. This makes debugging easier in multi-threaded applications.
  • Log levels can be completely stripped out at compile time reducing if branches.
  • Clean warning-free codebase even on high warning levels.
  • Crash safe behaviour with a build-in signal handler.
  • Type safe python style API with compile type checks and built-in support for logging STL types/containers by using the excellent {fmt} library.

Performance

Log Numbers

The following message is logged 100'000 times per thread LOG_INFO(logger, "Logging int: {}, int: {}, double: {}", i, j, d).

1 Thread

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 20 22 25 27 34 67 118
Quill, Dual Queue Enabled, Unbounded Queue 20 24 28 30 36 69 134
Quill, Dual Queue Disabled, Unbounded Queue 23 31 35 37 52 75 134
PlatformLab NanoLog 19 22 23 25 28 64 128
MS BinLog 46 47 48 49 82 129 353
Reckless 69 70 74 80 106 133 5908477
Iyengar NanoLog 112 122 134 147 207 337 597293
spdlog 288 312 328 345 670 914 4794
g3log 2434 2886 2992 3055 3178 3338 5579

4 Threads

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 19 22 26 30 46 67 343
Quill, Dual Queue Enabled, Unbounded Queue 20 22 26 30 46 66 242
Quill, Dual Queue Disabled, Unbounded Queue 21 28 33 38 64 79 4207
PlatformLab NanoLog 18 21 23 24 42 58 223
MS BinLog 45 46 48 49 75 125 271
Reckless 93 117 125 129 163 358 30186464
Iyengar NanoLog 115 156 191 214 299 441 1142546
spdlog 335 537 714 796 1081 1534 27378
g3log 2834 2929 3032 3132 5081 5994 26563

Log Numbers and Large Strings

The following message is logged 100'000 times per thread LOG_INFO(logger, "Logging int: {}, int: {}, string: {}", i, j, large_string). The large string is over 35 characters to avoid short string optimisation of std::string

1 Thread

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 26 31 37 40 48 73 136
Quill, Dual Queue Enabled, Unbounded Queue 28 33 39 42 59 79 138
Quill, Dual Queue Disabled, Unbounded Queue 195 211 224 232 251 283 325
PlatformLab NanoLog 29 34 39 54 57 77 178
MS BinLog 51 53 56 58 75 131 343
Reckless 94 96 102 117 155 176 6924627
Iyengar NanoLog 111 119 127 131 172 319 9553
spdlog 231 253 269 282 587 806 1055
g3log 1122 1142 1368 2293 2516 2698 4051

4 Threads

Library 50th 75th 90th 95th 99th 99.9th Worst
Quill, Dual Queue Enabled, Bounded Queue 27 32 38 45 59 82 440
Quill, Dual Queue Enabled, Unbounded Queue 26 32 38 46 60 106 3866
Quill, Dual Queue Disabled, Unbounded Queue 203 226 243 252 269 300 4278
PlatformLab NanoLog 29 34 47 55 59 69 289
MS BinLog 51 54 58 62 96 133 375
Reckless 115 134 157 172 216 377 30721857
Iyengar NanoLog 111 121 137 175 231 811 32100
spdlog 266 309 593 672 911 1329 13600
g3log 1816 2207 2389 2497 3457 4211 8365

The benchmarks are done on Linux (Ubuntu/RHEL) with GCC 8.1.

Each thread is pinned on a different cpu. Unfortunately the cores are not isolated. Running the backend logger thread in the same CPU as the caller hot-path threads, slows down the log message processing on the backend logging thread and will cause the SPSC queue to fill faster and re-allocate.

Continuously Logging messages in a loop makes the consumer (backend logging thread) unable to follow up and the queue will have to re-allocate or block for most logging libraries expect very high throughput binary loggers like PlatformLab Nanolog. Therefore, a different approach was followed that suits more to a real time application:

  1. 20 messages are logged in a loop.
  2. calculate/store the average latency for those messages.
  3. wait between 1-2 ms.
  4. repeat for n iterations.

I run each logger benchmark four times and the above latencies are the second best result.

The benchmark code and results can be found here.

Supported Platforms And Compilers

Quill requires a C++14 compiler. Minimum required versions of supported compilers are shown in the below table.

Compiler Notes
GCC version >= 5.0
Clang version >= 5.0
MSVC++ version >= 14.3
Platform Notes
Linux Ubuntu, RHEL, Centos, Fedora
Windows Windows 10 - version 1607, Windows Server 2016
macOS Tested with Xcode 9.4

Basic usage

#include "quill/Quill.h"

int main()
{
  quill::enable_console_colours();
  quill::start();

  quill::Logger* logger = quill::get_logger();
  logger->set_log_level(quill::LogLevel::TraceL3);

  // enable a backtrace that will get flushed when we log CRITICAL
  logger->init_backtrace(2, quill::LogLevel::Critical);

  LOG_BACKTRACE(logger, "Backtrace log {}", 1);
  LOG_BACKTRACE(logger, "Backtrace log {}", 2);

  LOG_INFO(logger, "Welcome to Quill!");
  LOG_ERROR(logger, "An error message. error code {}", 123);
  LOG_WARNING(logger, "A warning message.");
  LOG_CRITICAL(logger, "A critical error.");
  LOG_DEBUG(logger, "Debugging foo {}", 1234);
  LOG_TRACE_L1(logger, "{:>30}", "right aligned");
  LOG_TRACE_L2(logger, "Positional arguments are {1} {0} ", "too", "supported");
  LOG_TRACE_L3(logger, "Support for floats {:03.2f}", 1.23456);
}

Output

Screenshot-2020-08-14-at-01-09-43.png

CMake-Integration

External

Building and Installing Quill as Static Library
git clone https://github.com/odygrd/quill.git
mkdir cmake_build
cd cmake_build
make install

Note: To install in custom directory invoke cmake with -DCMAKE_INSTALL_PREFIX=/quill/install-dir/

Building and Installing Quill as Static Library With External libfmt
cmake -DCMAKE_PREFIX_PATH=/my/fmt/fmt-config.cmake-directory/ -DQUILL_FMT_EXTERNAL=ON -DCMAKE_INSTALL_PREFIX=/quill/install-dir/'

Then use the library from a CMake project, you can locate it directly with find_package()

Directory Structure
my_project/
├── CMakeLists.txt
├── main.cpp
CMakeLists.txt
# Set only if needed - quill was installed under a custom non-standard directory
set(CMAKE_PREFIX_PATH /test_quill/usr/local/)

find_package(quill REQUIRED)

# Linking your project against quill
add_executable(example main.cpp)
target_link_libraries(example PRIVATE quill::quill)
main.cpp

See basic usage

Embedded

To embed the library directly, copy the source folder to your project and call add_subdirectory() in your CMakeLists.txt file

Directory Structure
my_project/
├── quill/            (source folder)
├── CMakeLists.txt
├── main.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
project(my_project)

set(CMAKE_CXX_STANDARD 14)

add_subdirectory(quill)

add_executable(my_project main.cpp)
target_link_libraries(my_project PRIVATE quill::quill)
main.cpp

See basic usage

Documentation

Advanced usage and additional documentation can be found in the wiki pages.

The examples folder is also a good source of documentation.

License

Quill is licensed under the MIT License

Quill depends on third party libraries with separate copyright notices and license terms. Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses.

Owner
Odysseas Georgoudis
Odysseas Georgoudis
Comments
  • Thread Sanitizer Reporting data race

    Thread Sanitizer Reporting data race

    Running my program with -fsanitize=thread produces a data race warning with quill. Is this potentially because some other thread is accessing a value passed to a quill log statement that has not yet completed?

    It looks like thread T2, created by quill, is reading from the same data that thread T8 is writing to. Thread T8 was created by taskflow.

    If it's expected behavior that the threaded nature of quill could potentially cause a data race if some other thread is modifying the same data that was passed to quill, then this may not be a quill bug and I need to be more careful with my usage of quill.

    From the summary at the bottom of the thread trace:

    SUMMARY: ThreadSanitizer: data race /home/xander/dev/vcpkg/installed/x64-linux/include/quill/detail/sps
    c_queue/UnboundedSPSCEventQueue.h:140:27 in quill::detail::UnboundedSPSCEventQueue<quill::detail::BaseE
    vent>::try_pop()
    

    Thanks for this fantastic open source library. Grateful for any guidance on usage in a multi-threaded environment.

    Full thread trace:

    ==================                                                                                     
    WARNING: ThreadSanitizer: data race (pid=18389)
      Read of size 8 at 0x7b4800090100 by thread T2:                                                           
    #0 quill::detail::UnboundedSPSCEventQueue<quill::detail::BaseEvent>::try_pop() /home/xander/dev/vc$
    kg/installed/x64-linux/include/quill/detail/spsc_queue/UnboundedSPSCEventQueue.h:140:27 (MyDataPre$rocessor+0x42df57)
        #1 quill::detail::BackendWorker::_read_event_queue(quill::detail::ThreadContext*) 
    /home/xander/dev$vcpkg/installed/x64-linux/include/quill/detail/backend/BackendWorker.h:352:37 (MyDataPreProcessor+$
    x42df57)
        #2 quill::detail::BackendWorker::_populate_priority_queue(std::vector<quill::detail::ThreadContext$
    , quill::detail::CacheAlignedAllocator<quill::detail::ThreadContext*> > const&) /home/xander/dev/vcpkg$
    installed/x64-linux/include/quill/detail/backend/BackendWorker.h:335:5 (MyDataPreProcessor+0x42d3a$
    )
        #3 quill::detail::BackendWorker::_main_loop() /home/xander/dev/vcpkg/installed/x64-linux/include/q$
    ill/detail/backend/BackendWorker.h:548:3 (MyDataPreProcessor+0x42d3a5)
        #4 quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda'()::operator()() c$
    nst /home/xander/dev/vcpkg/installed/x64-linux/include/quill/detail/backend/BackendWorker.h:296:21 (Pl$
    tusDataPreProcessor+0x51a6c7)
        #5 void std::__invoke_impl<void, quill::detail::BackendWorker::run()::'lambda'()::operator()() con$
    t::'lambda'()>(std::__invoke_other, quill::detail::BackendWorker::run()::'lambda'()::operator()() cons$
    ::'lambda'()&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14
    (MyDataPreProcessor+0x51a559)
        #6 std::__invoke_result<quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lamb$
    a'()>::type std::__invoke<quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda$
    ()>(quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda'()&&) /usr/bin/../lib$
    gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (MyDataPreProcessor+0x51a55$
    )
        #7 void std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::'lambda'()::operator$
    )() const::'lambda'()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/$
    0/../../../../include/c++/10/thread:264:13 (MyDataPreProcessor+0x51a559)
        #8 std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::'lambda'()::operator()() $
    onst::'lambda'()> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/t$
    read:271:11 (MyDataPreProcessor+0x51a559)
        #9 std::thread::_State_impl<std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::$
    lambda'()::operator()() const::'lambda'()> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../..$
    ../../include/c++/10/thread:215:13 (MyDataPreProcessor+0x51a559)
        #10 execute_native_thread_routine /home/conda/feedstock_root/build_artifacts/ctng-compilers_161823$
    181388/work/.build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:80:18 (libstdc++.so$
    6+0xc9066)
    
      Previous write of size 8 at 0x7b4800090100 by thread T8:
        #0 posix_memalign <null> (MyDataPreProcessor+0x435c98)                                             
    #1 quill::detail::aligned_alloc(unsigned long, unsigned long) /home/xander/dev/vcpkg/buildtrees/qu$
    ll/src/v1.6.2-b72390cb62.clean/quill/src/detail/misc/Os.cpp:254:28 (MyDataPreProcessor+0x5979cb)
        #2 ccMydata::preprocess_record_batch(std::shared_ptr<arrow::RecordBatch>, junction::Concurrent$
    ap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits<long>, junction::DefaultValu$
    Traits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr<ccMydata::Book>, s$
    d::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std::unordered_map<long, folly::$
    bvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::Or$
    erBookLevel> > >, std::hash<long>, std::equal_to<long>, std::allocator<std::pair<long const, folly::fb$
    ector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::Orde$
    BookLevel> > > > > >&, std::unordered_set<long, std::hash<long>, std::equal_to<long>, std::allocator<l$
    ng> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::shared_ptr<std::deque<folly::fbvecto$
    <std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator
    <std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<std::shared_ptr<std::deque<fol
    ly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata
    ::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, st
    d::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&, unsigned short&)::$_2::opera
    tor()() const /home/xander/dev/My_model/pyMydata/pyMydata/PreprocessData.cc:152:41 (MyD
    ataPreProcessor+0x4dd52a)
        #3 void std::__invoke_impl<void, ccMydata::preprocess_record_batch(std::shared_ptr<arrow::Recor
    dBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits
    <long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr<c
    cMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std
    ::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std
    ::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allocator<st
    d::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::
    shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>, std::equ
    al_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::shared_
    ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::share
    d_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::O
    rderBookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<
    std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocato
    r<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccp
    lutusdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&
    , unsigned short&)::$_2&>(std::__invoke_other, ccMydata::preprocess_record_batch(std::shared_ptr<ar
    row::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::Defaul
    tKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::sh
    ared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&,
    long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::all
    ocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::al
    locator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloc
    ator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>
    , std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<st
    d::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<
    std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccplu
    tusdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::
    allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std
    ::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shar
    ed_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >
    > > > > >&, unsigned short&)::$_2&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/
    bits/invoke.h:60:14 (MyDataPreProcessor+0x4dd52a)
    
    #4 std::enable_if<is_invocable_r_v<void, ccMydata::preprocess_record_batch(std::shared_ptr<arro
    w::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultK
    eyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shar
    ed_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, lo
    ng&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloc
    ator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allo
    cator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocat
    or<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>,
    std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std:
    :shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<st
    d::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccplutu
    sdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::al
    locator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::
    allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared
    _ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > >
    > > > >&, unsigned short&)::$_2&>, void>::type std::__invoke_r<void, ccMydata::preprocess_record_ba
    tch(std::shared_ptr<arrow::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, f
    olly::fbvector<std::shared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata
    ::Book> > >&, long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::Ord
    erBookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::e
    qual_to<long>, std::allocator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::Order
    BookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set
    <long, std::hash<long>, std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflo
    w&, folly::fbvector<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector
    <std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata
    ::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<fol
    ly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata
    ::BookItem> > > > > > > >&, unsigned short&)::$_2&>(ccMydata::preprocess_record_batch(std::sh
    ared_ptr<arrow::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junct
    ion::DefaultKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvec
    tor<std::shared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem
    >, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<lon
    g>, std::allocator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>,
     std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std:
    :hash<long>, std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::
    fbvector<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std:
    :allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::share
    d_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > >
     > >, std::allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvecto
    r<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&, unsigned short&)::$_2&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../incl
    ude/c++/10/bits/invoke.h:110:2 (MyDataPreProcessor+0x4dd52a)
    
    #5 std::_Function_handler<void (), ccMydata::preprocess_record_batch(std::shared_ptr<arrow::Rec
    ordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTrai
    ts<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr
    <ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, s
    td::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<s
    td::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allocator<
    std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std
    ::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>, std::e
    qual_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::share
    d_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::sha
    red_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata:
    :BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocato
    r<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloca
    tor<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<c
    cMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > >
    >&, unsigned short&)::$_2>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/..
    /../../../include/c++/10/bits/std_function.h:291:9 (MyDataPreProcessor+0x4dd52a)
        #6 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../i
    nclude/c++/10/bits/std_function.h:622:14 (MyDataPreProcessor+0x50ffd8)
        #7 tf::Executor::_invoke_static_task(tf::Worker&, tf::Node*) /home/xander/dev/vcpkg/installed/x64-l
    inux/include/taskflow/core/algorithm/../executor.hpp:818:3 (MyDataPreProcessor+0x50ffd8)
        #8 tf::Executor::_invoke(tf::Worker&, tf::Node*) /home/xander/dev/vcpkg/installed/x64-linux/include
    /taskflow/core/algorithm/../executor.hpp:666:7 (MyDataPreProcessor+0x50f3a1)
        #9 tf::Executor::_exploit_task(tf::Worker&, tf::Node*&) /home/xander/dev/vcpkg/installed/x64-linux/
    include/taskflow/core/algorithm/../executor.hpp:462:7 (MyDataPreProcessor+0x50e957)
        #10 tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&)::operator()(tf::Worker&) const /home
    /xander/dev/vcpkg/installed/x64-linux/include/taskflow/core/algorithm/../executor.hpp:392:9 (MyData
    PreProcessor+0x50e957)
        #11 void std::__invoke_impl<void, tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), std::
    reference_wrapper<tf::Worker> >(std::__invoke_other, tf::Executor::_spawn(unsigned long)::'lambda'(tf::
    Worker&)&&, std::reference_wrapper<tf::Worker>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../i
    nclude/c++/10/bits/invoke.h:60:14 (MyDataPreProcessor+0x50e809)
        #12 std::__invoke_result<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), std::reference
    _wrapper<tf::Worker> >::type std::__invoke<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&),
    std::reference_wrapper<tf::Worker> >(tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&)&&, std:
    :reference_wrapper<tf::Worker>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bi
    ts/invoke.h:95:14 (MyDataPreProcessor+0x50e809)
        #13 void std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&
    ), std::reference_wrapper<tf::Worker> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/bin/..
    /lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (MyDataPreProcessor+0x50e809)
        #14 std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), st
    d::reference_wrapper<tf::Worker> > >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../
    include/c++/10/thread:271:11 (MyDataPreProcessor+0x50e809)
        #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::
    'lambda'(tf::Worker&), std::reference_wrapper<tf::Worker> > > >::_M_run() /usr/bin/../lib/gcc/x86_64-li
    nux-gnu/10/../../../../include/c++/10/thread:215:13 (MyDataPreProcessor+0x50e809)
        #16 execute_native_thread_routine /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239
    181388/work/.build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:80:18 (libstdc++.so.
    6+0xc9066)
    
      As if synchronized via sleep:
        #0 nanosleep <null> (MyDataPreProcessor+0x433b2d)
        #1 void std::this_thread::sleep_for<long, std::ratio<1l, 1000000000l> >(std::chrono::duration<long,
     std::ratio<1l, 1000000000l> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/
    10/thread:401:9 (MyDataPreProcessor+0x42d4ef)
        #2 quill::detail::BackendWorker::_main_loop() /home/xander/dev/vcpkg/installed/x64-linux/include/qu
    ill/detail/backend/BackendWorker.h:570:5 (MyDataPreProcessor+0x42d4ef)
        #3 quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda'()::operator()() co
    nst /home/xander/dev/vcpkg/installed/x64-linux/include/quill/detail/backend/BackendWorker.h:296:21 (Plu
    tusDataPreProcessor+0x51a6c7)
        #4 void std::__invoke_impl<void, quill::detail::BackendWorker::run()::'lambda'()::operator()() cons
    t::'lambda'()>(std::__invoke_other, quill::detail::BackendWorker::run()::'lambda'()::operator()() const
    ::'lambda'()&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14
    (MyDataPreProcessor+0x51a559)
        #5 std::__invoke_result<quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambd
    a'()>::type std::__invoke<quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda'
    ()>(quill::detail::BackendWorker::run()::'lambda'()::operator()() const::'lambda'()&&) /usr/bin/../lib/
    gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (MyDataPreProcessor+0x51a559
    )
        #6 void std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::'lambda'()::operator(
    )() const::'lambda'()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/1
    0/../../../../include/c++/10/thread:264:13 (MyDataPreProcessor+0x51a559)
        #7 std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::'lambda'()::operator()() c
    onst::'lambda'()> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/th
    read:271:11 (MyDataPreProcessor+0x51a559)
        #8 std::thread::_State_impl<std::thread::_Invoker<std::tuple<quill::detail::BackendWorker::run()::'
    lambda'()::operator()() const::'lambda'()> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../
    ../../include/c++/10/thread:215:13 (MyDataPreProcessor+0x51a559)
        #9 execute_native_thread_routine /home/conda/feedstock_root/build_artifacts/ctng-compilers_16182391
    81388/work/.build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:80:18 (libstdc++.so.6
    +0xc9066)
    
    Location is heap block of size 384 at 0x7b4800090000 allocated by thread T8:
        #0 posix_memalign <null> (MyDataPreProcessor+0x435c98)
        #1 quill::detail::aligned_alloc(unsigned long, unsigned long) /home/xander/dev/vcpkg/buildtrees/qui
    ll/src/v1.6.2-b72390cb62.clean/quill/src/detail/misc/Os.cpp:254:28 (MyDataPreProcessor+0x5979cb)
        #2 ccMydata::preprocess_record_batch(std::shared_ptr<arrow::RecordBatch>, junction::ConcurrentM
    ap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits<long>, junction::DefaultValue
    Traits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr<ccMydata::Book>, st
    d::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std::unordered_map<long, folly::f
    bvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::Ord
    erBookLevel> > >, std::hash<long>, std::equal_to<long>, std::allocator<std::pair<long const, folly::fbv
    ector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::Order
    BookLevel> > > > > >&, std::unordered_set<long, std::hash<long>, std::equal_to<long>, std::allocator<lo
    ng> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::shared_ptr<std::deque<folly::fbvector
    <std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator
    <std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<std::shared_ptr<std::deque<fol
    ly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata
    ::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, st
    d::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&, unsigned short&)::$_2::opera
    tor()() const /home/xander/dev/My_model/pyMydata/pyMydata/PreprocessData.cc:152:41 (MyD
    ataPreProcessor+0x4dd52a)
        #3 void std::__invoke_impl<void, ccMydata::preprocess_record_batch(std::shared_ptr<arrow::Recor
    dBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits
    <long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr<c
    cMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std
    ::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std
    ::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allocator<st
    d::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::
    shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>, std::equ
    al_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::shared_
    ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::share
    d_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata::O
    rderBookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<
    std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocato
    r<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccp
    lutusdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&
    , unsigned short&)::$_2&>(std::__invoke_other, ccMydata::preprocess_record_batch(std::shared_ptr<ar
    row::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::Defaul
    tKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::sh
    ared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&,
    long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::all
    ocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::al
    locator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloc
    ator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>
    , std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<st
    d::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<
    std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccplu
    tusdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::
    allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std
    ::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shar
    ed_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >
    > > > > >&, unsigned short&)::$_2&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/
    bits/invoke.h:60:14 (MyDataPreProcessor+0x4dd52a)
    
    #4 std::enable_if<is_invocable_r_v<void, ccMydata::preprocess_record_batch(std::shared_ptr<arro
    w::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultK
    eyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shar
    ed_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, lo
    ng&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloc
    ator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allo
    cator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocat
    or<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>,
    std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std:
    :shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<st
    d::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccplutu
    sdata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::al
    locator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::
    allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared
    _ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > >
    > > > >&, unsigned short&)::$_2&>, void>::type std::__invoke_r<void, ccMydata::preprocess_record_ba
    tch(std::shared_ptr<arrow::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, f
    olly::fbvector<std::shared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata
    ::Book> > >&, long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::Ord
    erBookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::e
    qual_to<long>, std::allocator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::Order
    BookLevel>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set
    <long, std::hash<long>, std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflo
    w&, folly::fbvector<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector
    <std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata
    ::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<fol
    ly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata
    ::BookItem> > > > > > > >&, unsigned short&)::$_2&>(ccMydata::preprocess_record_batch(std::sh
    ared_ptr<arrow::RecordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junct
    ion::DefaultKeyTraits<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvec
    tor<std::shared_ptr<ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, std::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem
    >, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<lon
    g>, std::allocator<std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>,
     std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std:
    :hash<long>, std::equal_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::
    fbvector<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std:
    :allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::share
    d_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > >
     > >, std::allocator<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvecto
    r<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > > >&, unsigned short&)::$_2&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../incl
    ude/c++/10/bits/invoke.h:110:2 (MyDataPreProcessor+0x4dd52a)
    
    #5 std::_Function_handler<void (), ccMydata::preprocess_record_batch(std::shared_ptr<arrow::Rec
    ordBatch>, junction::ConcurrentMap_Leapfrog<long, ccMydata::Book*, junction::DefaultKeyTrai
    ts<long>, junction::DefaultValueTraits<ccMydata::Book*> >&, folly::fbvector<std::shared_ptr
    <ccMydata::Book>, std::allocator<std::shared_ptr<ccMydata::Book> > >&, long&, s
    td::unordered_map<long, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<s
    td::shared_ptr<ccMydata::BookItem> > >, std::hash<long>, std::equal_to<long>, std::allocator<
    std::pair<long const, folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std
    ::shared_ptr<ccMydata::BookItem> > > > > >&, std::unordered_set<long, std::hash<long>, std::e
    qual_to<long>, std::allocator<long> >&, long&, tf::Executor&, tf::Taskflow&, folly::fbvector<std::share
    d_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::allocator<std::sha
    red_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<ccMydata:
    :BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > >, std::allocato
    r<std::shared_ptr<std::deque<folly::fbvector<std::shared_ptr<ccMydata::BookItem>, std::alloca
    tor<std::shared_ptr<ccMydata::BookItem> > >, std::allocator<folly::fbvector<std::shared_ptr<c
    cMydata::BookItem>, std::allocator<std::shared_ptr<ccMydata::BookItem> > > > > > >
    >&, unsigned short&)::$_2>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/..
    /../../../include/c++/10/bits/std_function.h:291:9 (MyDataPreProcessor+0x4dd52a)
        #6 std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../i
    nclude/c++/10/bits/std_function.h:622:14 (MyDataPreProcessor+0x50ffd8)
        #7 tf::Executor::_invoke_static_task(tf::Worker&, tf::Node*) /home/xander/dev/vcpkg/installed/x64-l
    inux/include/taskflow/core/algorithm/../executor.hpp:818:3 (MyDataPreProcessor+0x50ffd8)
        #8 tf::Executor::_invoke(tf::Worker&, tf::Node*) /home/xander/dev/vcpkg/installed/x64-linux/include
    /taskflow/core/algorithm/../executor.hpp:666:7 (MyDataPreProcessor+0x50f3a1)
        #9 tf::Executor::_exploit_task(tf::Worker&, tf::Node*&) /home/xander/dev/vcpkg/installed/x64-linux/
    include/taskflow/core/algorithm/../executor.hpp:462:7 (MyDataPreProcessor+0x50e957)
        #10 tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&)::operator()(tf::Worker&) const /home
    /xander/dev/vcpkg/installed/x64-linux/include/taskflow/core/algorithm/../executor.hpp:392:9 (MyData
    PreProcessor+0x50e957)
        #11 void std::__invoke_impl<void, tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), std::
    reference_wrapper<tf::Worker> >(std::__invoke_other, tf::Executor::_spawn(unsigned long)::'lambda'(tf::
    Worker&)&&, std::reference_wrapper<tf::Worker>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../i
    nclude/c++/10/bits/invoke.h:60:14 (MyDataPreProcessor+0x50e809)
        #12 std::__invoke_result<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), std::reference
    _wrapper<tf::Worker> >::type std::__invoke<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&),
    std::reference_wrapper<tf::Worker> >(tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&)&&, std:
    :reference_wrapper<tf::Worker>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bi
    ts/invoke.h:95:14 (MyDataPreProcessor+0x50e809)
        #13 void std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&
    ), std::reference_wrapper<tf::Worker> > >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/bin/..
    /lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (MyDataPreProcessor+0x50e809)
        #14 std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::'lambda'(tf::Worker&), st
    d::reference_wrapper<tf::Worker> > >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../
    include/c++/10/thread:271:11 (MyDataPreProcessor+0x50e809)
        #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<tf::Executor::_spawn(unsigned long)::
    'lambda'(tf::Worker&), std::reference_wrapper<tf::Worker> > > >::_M_run() /usr/bin/../lib/gcc/x86_64-li
    nux-gnu/10/../../../../include/c++/10/thread:215:13 (MyDataPreProcessor+0x50e809)
        #16 execute_native_thread_routine /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239
    181388/work/.build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:80:18 (libstdc++.so.
    6+0xc9066)
    
     Thread T2 'Quill_Backend' (tid=18392, running) created by main thread at:
        #0 pthread_create <null> (MyDataPreProcessor+0x4361db)
        #1 __gthread_create /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239181388/work/.b
    uild/x86_64-conda-linux-gnu/build/build-cc-gcc-final/x86_64-conda-linux-gnu/libstdc++-v3/include/x86_64
    -conda-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xc91f8)
        #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::threa
    d::_State> >, void (*)()) /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239181388/work/
    .build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:135:37 (libstdc++.so.6+0xc91f8)
        #3 void std::__invoke_impl<void, quill::detail::BackendWorker::run()::'lambda'()>(std::__invoke_oth
    er, quill::detail::BackendWorker::run()::'lambda'()&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../..
    /../include/c++/10/bits/invoke.h:60:14 (MyDataPreProcessor+0x51a346)
        #4 std::__invoke_result<quill::detail::BackendWorker::run()::'lambda'()>::type std::__invoke<quill:
    :detail::BackendWorker::run()::'lambda'()>(quill::detail::BackendWorker::run()::'lambda'()&&) /usr/bin/
    ../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (MyDataPreProcessor+0
    x51a346)
        #5 void std::call_once<quill::detail::BackendWorker::run()::'lambda'()>(std::once_flag&, quill::det
    ail::BackendWorker::run()::'lambda'()&&)::'lambda'()::operator()() const /usr/bin/../lib/gcc/x86_64-lin
    ux-gnu/10/../../../../include/c++/10/mutex:717:4 (MyDataPreProcessor+0x51a346)
        #6 void std::call_once<quill::detail::BackendWorker::run()::'lambda'()>(std::once_flag&, quill::det
    ail::BackendWorker::run()::'lambda'()&&)::'lambda0'()::operator()() const /usr/bin/../lib/gcc/x86_64-li
    nux-gnu/10/../../../../include/c++/10/mutex:722:25 (MyDataPreProcessor+0x51a346)
        #7 void std::call_once<quill::detail::BackendWorker::run()::'lambda'()>(std::once_flag&, quill::det
    ail::BackendWorker::run()::'lambda'()&&)::'lambda0'()::__invoke() /usr/bin/../lib/gcc/x86_64-linux-gnu/
    10/../../../../include/c++/10/mutex:722:21 (MyDataPreProcessor+0x51a346)
        #8 pthread_once <null> (MyDataPreProcessor+0x439595)
        #9 __gthread_once(int*, void (*)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/x86
    _64-linux-gnu/c++/10/bits/gthr-default.h:700:12 (MyDataPreProcessor+0x51a2e0)
        #10 void std::call_once<quill::detail::BackendWorker::run()::'lambda'()>(std::once_flag&, quill::de
    tail::BackendWorker::run()::'lambda'()&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c
    ++/10/mutex:729:17 (MyDataPreProcessor+0x51a2e0)
        #11 quill::detail::BackendWorker::run() /home/xander/dev/vcpkg/installed/x64-linux/include/quill/de
    tail/backend/BackendWorker.h:249:3 (MyDataPreProcessor+0x42ad10)
        #12 quill::detail::LogManager::start_backend_worker(bool, std::initializer_list<int> const&) /home/
    xander/dev/vcpkg/installed/x64-linux/include/quill/detail/LogManager.h:150:21 (MyDataPreProcessor+0
    x42ad10)
        #13 quill::start(bool, std::initializer_list<int>) /home/xander/dev/vcpkg/installed/x64-linux/inclu
    de/quill/Quill.h:60:57 (MyDataPreProcessor+0x42ac55)
        #14 initialize_logging() /home/xander/dev/My_model/pyMydata/pyMydata/PreprocessData.cc:
    483:5 (MyDataPreProcessor+0x4dc771)
        #15 main /home/xander/dev/My_model/pyMydata/pyMydata/PreprocessData.cc:490:5 (MyDat
    aPreProcessor+0x4dc832)
    
      Thread T8 (tid=18399, running) created by main thread at:
        #0 pthread_create <null> (MyDataPreProcessor+0x4361db)
        #1 __gthread_create /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239181388/work/.b
    uild/x86_64-conda-linux-gnu/build/build-cc-gcc-final/x86_64-conda-linux-gnu/libstdc++-v3/include/x86_64
    -conda-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xc91f8)
        #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::threa
    d::_State> >, void (*)()) /home/conda/feedstock_root/build_artifacts/ctng-compilers_1618239181388/work/
    .build/x86_64-conda-linux-gnu/src/gcc/libstdc++-v3/src/c++11/thread.cc:135:37 (libstdc++.so.6+0xc91f8)
        #3 tf::Executor::Executor(unsigned long) /home/xander/dev/vcpkg/installed/x64-linux/include/taskflo
    w/core/algorithm/../executor.hpp:277:3 (MyDataPreProcessor+0x4e92cf)
        #4 ccMydata::process_incoming_batches(unsigned short&) /home/xander/dev/My_model/pyMyda
    ta/pyMydata/PreprocessData.cc:294:22 (MyDataPreProcessor+0x4d54d3)
        #5 main /home/xander/dev/My_model/pyMydata/pyMydata/PreprocessData.cc:493:5 (MyData
    PreProcessor+0x4dc858)
    
    SUMMARY: ThreadSanitizer: data race /home/xander/dev/vcpkg/installed/x64-linux/include/quill/detail/sps
    c_queue/UnboundedSPSCEventQueue.h:140:27 in quill::detail::UnboundedSPSCEventQueue<quill::detail::BaseE
    vent>::try_pop()
    
  • Please support local timezone

    Please support local timezone

    Thank you for your great work! I love this library.

    One thing to prevent using quill is supporting local time zone. Please support local timezone. Currently quill::PatternFormatter::_timezone_type is private and hard coded.

  • to support compiling dynamic library

    to support compiling dynamic library

    Hi Quill team,

    We are currently using your quill logger for our C++ projects which works brilliantly. Thanks.

    Now we would like to utilize quill logger for JAVA applications as well by loading it as a dynamic library. In this way, Quill need to dynamically depend on fmt lib as well instead of being bundled together, as we are also using fmt-cpp's dynamic library.

    Is that possible you can help to add the support of generating dynamic library as well, together with existing support of static library for quill?

    Thanks in advance, Xiong

  • Unable to compile with Visual Studio 2019 and vcpkg

    Unable to compile with Visual Studio 2019 and vcpkg

    Hello,

    I don't know if this is the appropriate place for this issue since I don't know who is the maintainer of the vpckg quill package, let me know if I should make a similar issue directly on vcpkg.

    Tools used

    • Visual Studio: v16.9.2
    • Windows 10: 20h2 (build 19042.746)
    • vcpkg: 2021-01-13-768d8f95c9e752603d2c5901c7a7c7fbdb08af35

    Builds have been done on both x86 and x64, Debug and Release modes.

    Code snippet

    Nothing unusual here, I reduced the code and the dependencies to the minimum and the problem still persists.

    #include <quill/Quill.h>
    
    int main()
    {
        quill::start();
    
        quill::Logger* logger = quill::get_logger();
    
        // Here is the IDE first error (C++ pointer to incomplete class type is not allowed)
        logger->set_log_level(quill::LogLevel::Info);
    
        LOG_INFO(logger, "A simple test.");
    
        return 0;
    }
    

    What is the problem?

    I was looking for a fast and lightweight logger, and quill appeared to me as the perfect library to use. However, I'm working with Visual Studio and there is an annoying issue with vcpkg concerning quill.

    When I try to compile, I get a long list of errors, which seem to come from the bundled version of fmt inside of quill. Here is the output of the build (the actual error list of VS is composed of 32 errors, but they're all coming from the fmt integration):

    Build started...
    1>------ Build started: Project: QuillTest, Configuration: Debug Win32 ------
    1>main.cpp
    1>C:\Users\Armillus\Programming\vcpkg\installed\x86-windows\include\quill\Fmt.h(20,12): fatal error C1083: Cannot open include file: 'quill/bundled/fmt/chrono.h': No such file or directory
    1>Done building project "QuillTest.vcxproj" -- FAILED.
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    

    Of course, I can't compile nor run the program, but the IDE isn't recognizing properly the code after quill::Logger* logger = quill::get_logger();. On next line, it complains during static analysis about the logger object (C++ pointer to incomplete class type is not allowed).

    What about CMake?

    When it comes to CMake, everything is working well, the vcpkg integrations works nicely and I don't have any error. For the sake of accuracy and completeness, here is the CMakeLists.txt that I used.

    cmake_minimum_required(VERSION 3.1.0)
    project(NAlamo)
    
    set(CMAKE_CXX_STANDARD 14)
    
    find_package(quill CONFIG REQUIRED)
    
    add_executable(NAlamo "main.cpp")
    
    target_link_libraries(NAlamo PRIVATE quill::quill)
    

    Eventually, this error seems to come from the vcpkg package itself and maybe you'll have an idea about how to fix it. I can still compile with CMake, but I don't use it in the project where I plan to use quill and the IDE integration failure is quite disturbing.

    Thank you in advance for your help!

  • got an assert error `BaseEvent has a std::chrono timestamp, but the backend thread is using rdtsc timestamp`

    got an assert error `BaseEvent has a std::chrono timestamp, but the backend thread is using rdtsc timestamp`

    Please help. Error message:

    quill/detail/BackendWorker.h:396: std::chrono::nanoseconds quill::detail::BackendWorker::_get_real_timestamp(const quill::detail::BaseEvent*) const: Assertion `base_event->using_rdtsc() && "BaseEvent has a std::chrono timestamp, but the backend thread is using rdtsc timestamp"' failed.

  • Cannot compile example_trivial.cpp in Linux

    Cannot compile example_trivial.cpp in Linux

    I try to compile example_trivial.cpp in Linux using clang++-9.0.1 and get below compilation errors. Do you have any suggestion?

    Thanks, Hung

    [ 50%] Building CXX object CMakeFiles/test_quill.dir/test_quill.cpp.o                                                                                                                                                                 
    In file included from /home/hungptit/working/cppidioms/src/test_quill.cpp:1:                                                                                                                                                          
    In file included from /home/hungptit/working/cppidioms/src/../3p/include/quill/Quill.h:8:                                                                                                                                             
    /home/hungptit/working/cppidioms/src/../3p/include/quill/detail/LogMacros.h:39:62: error: token pasting of ',' and                                                                                                                    
          __VA_ARGS__ is a GNU extension [-Werror,-Wgnu-zero-variadic-macro-arguments]                                                                                                                                                    
        QUILL_LOGGER_CALL(logger, quill::LogLevel::TraceL3, fmt, ##__VA_ARGS__)                                                                                                                                                           
                                                                 ^                                                                                                                                                                        
    /home/hungptit/working/cppidioms/src/../3p/include/quill/detail/LogMacros.h:33:54: error: token pasting of ',' and                                                                                                                    
          __VA_ARGS__ is a GNU extension [-Werror,-Wgnu-zero-variadic-macro-arguments]                                                                                                                                                    
        logger->log<log_statement_level>(&log_line_info, ##__VA_ARGS__)...                                                                                                                                                                
                                                         ^                                                                                                                                                                                
    /home/hungptit/working/cppidioms/src/../3p/include/quill/detail/LogMacros.h:46:62: error: token pasting of ',' and                                                                                                                    
          __VA_ARGS__ is a GNU extension [-Werror,-Wgnu-zero-variadic-macro-arguments]                                                                                                                                                    
        QUILL_LOGGER_CALL(logger, quill::LogLevel::TraceL2, fmt, ##__VA_ARGS__)                                                                                                                                                           
                                                                 ^                                                                                                                                                                        
    /home/hungptit/working/cppidioms/src/../3p/include/quill/detail/LogMacros.h:33:54: error: token pasting of ',' and                                                                                                                    
          __VA_ARGS__ is a GNU extension [-Werror,-Wgnu-zero-variadic-macro-arguments]                                                                                                                                                    
        logger->log<log_statement_level>(&log_line_info, ##__VA_ARGS__)...                                                              
    

    And this is the compilation command

    {                                                                                                                                                                                                                                     
      "directory": "/home/hungptit/working/cppidioms/src",                                                                                                                                                                                
      "command": "clang++   -I/home/hungptit/working/cppidioms/src/../3p/include -I/home/hungptit/working/cppidioms/src/../src    -O3  -march=native  -std=c++17  -Wall  -pedantic  -pedantic-errors  -fstrict-aliasing  -Wstrict-aliasing  -DFMT_HEADER_ONLY  -DCEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS  -flto  -static -O3 -DNDEBUG   -o CMakeFiles/test_quill.dir/test_quill.cpp.o -c /home/hungptit/working/cppidioms/src/test_quill.cpp",                                  
      "file": "/home/hungptit/working/cppidioms/src/test_quill.cpp"                                                                                                                                                                       
    },
    
  • Release build using nvcc crashes if dual queue mode is activated

    Release build using nvcc crashes if dual queue mode is activated

    I am observing a strange issue: When building a CUDA application using quill in Debug mode everything works fine. As soon as I switch to Release the application crashes with an access violation. The same application works fine, when not building with nvcc, but with MSVC.

    It is hard to debug this issue, because the application does not crash in Debug or RelWithDebInfo. Any ideas?

    Some more information: OS: Windows 10 MSVC: 19.28.29913.0 NVCC: 11.3.58

    Stack when crashing: 0x00007ff67b4d567d 0x00007ff67b4d5045 0x00007ff67b4d366e _configthreadlocale 0x00007ffbc1591bb2 BaseThreadInitThunk 0x00007ffbc21b7034 RtlUserThreadStart 0x00007ffbc3e82651

    Attached you find a minimal reproducer:

    quill_nvcc.zip

  • Quill::Logger crashes on Windows 2016 and below version  of windows

    Quill::Logger crashes on Windows 2016 and below version of windows

    Just started to use Quill:logger and when we are trying to run it on windows 2016 or below versions it wont start. Reason probably is that quill uses API that does not work in those systems.

    See bug https://github.com/MicrosoftDocs/visualstudio-docs/issues/4124

    Can make this use of SetThreadDescription conditional for those platform or use some other way?

  • file_handler/rotating_file_handler with MinGW-32

    file_handler/rotating_file_handler with MinGW-32

    I'm having problems with the (rotating)_file_handler.

    When trying quill::file_handler("my.log", "a") or quill::file_handler(L"my.log", "a") this error occur: Invalid parameter passed to C runtime function. terminate called after throwing an instance of 'quill::QuillError what(): fopen failed with error message errno: "22"

    MinGW, 32bit, Windows10

  • QUILL_USE_BOUNDED_QUEUE cause assertion error :

    QUILL_USE_BOUNDED_QUEUE cause assertion error : "Object should always be cache aligned"

    Thank you for fast development. I love using this library. When I try to use QUILL_USE_BOUNDED_QUEUE in In quill 1.3.1, I met the assertion error message:

    .../include/quill/detail/BoundedSPSCQueue.h:362: quill::detail::BoundedSPSCQueue<TBaseObject, Capacity>::Handle quill::detail::BoundedSPSCQueue<TBaseObject, Capacity>::try_pop() [with TBaseObject = quill::detail::RecordBase; long unsigned int Capacity = 262144]: Assertion `(reinterpret_cast<uintptr_t>(buffer_pos) % CACHELINE_SIZE == 0) && "Object should always be cache aligned"' failed.
    

    Please tell me workaround.

    my environment : Fedora 32, gcc 10.1, glibc 2.31 quill version: 1.3.1

  •  RotatingFileHandler::_rotate doesn't handle rotation if file is opened in append mode

    RotatingFileHandler::_rotate doesn't handle rotation if file is opened in append mode

    I am using RotatingFileHandler with append mode (a). This causes the rotation to stop working. Exceptions are:

    failed to close previous log file during rotation, with error message errno: "17"
    fwrite failed with error message errno: "9"
    

    quill::Handler *file_handler = quill::rotating_file_handler(logDirFile, "a", maxFileSize, backupCount);

    Problem seems to be that the rotate() function doesn't initialize the _currentIndex variable when booting up. This causes rotation always trying to rename function to logfile.1.log which already exists and rename operation fails.

    See the code from rotate function and the comment // then we will always rename the base filename to 1

    // if we have more than 2 files we need to start renaming recursively
      for (uint32_t i = _current_index; i >= 1; --i)
      {
        filename_t const previous_file = detail::file_utilities::append_index_to_filename(_filename, i);
        filename_t const new_file = detail::file_utilities::append_index_to_filename(_filename, i + 1);
    
        quill::detail::rename(previous_file, new_file);
      }
    
      // then we will always rename the base filename to 1
      filename_t const previous_file = _filename;
      filename_t const new_file = detail::file_utilities::append_index_to_filename(_filename, 1);
    
      quill::detail::rename(previous_file, new_file);
    

    If we open the file in 'w' mode the previous file gets overwritten and log writing is started ok.

    Is this by design or can this be corrected?

  • PVS Studio Warning

    PVS Studio Warning

    quill/detail/misc/Os.h 122 err V1076 Code contains invisible characters that may alter its logic. Consider enabling the display of invisible characters in the code editor.

    This is issue is for your information. I am using v1.7.3

  • file event callbacks

    file event callbacks

    Discussed in https://github.com/odygrd/quill/discussions/183

    Originally posted by jmccabe July 12, 2022 I've just been having a brief look at quill, with the focus on whether it could replace spdlog in our code because there are a couple of things we want to be able to do that, to some extent, are more difficult than we'd hoped with spdlog.

    The first thing is that, when using a rotating file handler (or "sink" in spdlog terms), we'd like to log a few lines of "header" info in. Until recently, doing that in spdlog was awkward as there was no indication of when the rotate occurred, and the rotating file sink was a final class, with a private "rotate" function, that meant just deriving and handling the rotate slightly differently wasn't possible. Spdlog's latest version adds support for callbacks that help this to be done. Unfortunately, though, quill (unless I'm missing something) seems to suffer from the same restriction; class rotating_file_handler is private and there are no indications that a rotate is about to happen :-(

    The other thing would be to take the formatted text and encode/encrypt it before it gets written to a file. While it looks like it may be possible to work around this, somehow (possibly in the same way you need to with spdlog currently), it would be really nice to be able to configure everything 'normally' then, when you're sure it's all working, just be able to pass a callback in where the formatted log message was passed in, and an encoded version of it was returned which was then stored in the file, instead of the original formatted string.

    Are either of these the sort of thing that could be considered for quill?

  • Quill built with QUILL_FMT_EXTERNAL fails to find system Fmt includes

    Quill built with QUILL_FMT_EXTERNAL fails to find system Fmt includes

    Hello, I encountered this issue in trying to package Quill for the Homebrew package manager. Right now we build Quill and use its bundled Fmt. Ideally we would use system/external Fmt, to reduce duplication of dependencies and make updating dependencies easier.

    When building Quill with the QUILL_FMT_EXTERNAL option, the build and install succeeds. I see that the bundled Fmt is not installed. However, trying to include Quill headers results in:

    In file included from /usr/local/Cellar/quill/1.6.3/include/quill/Logger.h:8:
    /usr/local/Cellar/quill/1.6.3/include/quill/Fmt.h:20:12: fatal error: 'quill/bundled/fmt/chrono.h' file not found
      #include "quill/bundled/fmt/chrono.h"
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1 error generated.
    

    The issue is that when building with QUILL_FMT_EXTERNAL, Fmt headers are located somewhere else. But the Quill headers still expect Fmt to be present in the bundled location. A workaround for now that worked for me is to symlink the Fmt headers folder into the bundled location, but for distributing via package manager, this is not ideal.

  • [FR]  define custom format with callbacks.

    [FR] define custom format with callbacks.

    It's commonly used that we will use some callbacks to set the format of the logger. For example:

    1. In some cases, we want to use the user passed timestamp rather than the system.
    2. we want to pass some globally defined information to the logger.
  • Test Issue: FileUtilities append_date_to_filename test expects local timezone to be GMT0

    Test Issue: FileUtilities append_date_to_filename test expects local timezone to be GMT0

    Looks like the FileUtilities test has a time zone issue that causes a false failure in some geo locations. The append_date_to_filename test constructs a system_clock::time_point from epoch seconds(1583376945), and then serializes it to a suffix string for a log file and compares it to an expected result (2020-03-05). The problem is that the input epoch timestamp translates to the date 2020-03-04 in some time zones and 2020-03-05 in others. The test should probably manually override the current timezone setting internally before running the convert and append function.

    Nice library folks. I just started looking at it, but it's quite fancy.

  • TimeRotatingFileHandler doesn't rotate when constructed

    TimeRotatingFileHandler doesn't rotate when constructed

    Previously used the DailyFileHandler, recently updated to TimeRotatingFileHandler but notice that our logs no longer rotate.

    The application does not run 24/7 but we wanted to store the last 14 days of logs, the previous file handler would create a log file and name it based on the current day. The new one just seems to make a log file with the base name and then not rotate unless its active.

    This would essentially render it useless for us in a lot of cases as we will have to manually name our logs per day, and check them ourselves to see if they need to be deleted.

    If its intended to run 24/7 then that should be made clearer in the documentation. However it would be nice if when logs were created it also ran the same rotation checks.

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

Jul 17, 2022
fmtlog is a performant fmtlib-style logging library with latency in nanoseconds.

fmtlog fmtlog is a performant asynchronous logging library using fmt library format. Features Faster - lower runtime latency than NanoLog and higher t

Jan 6, 2023
Colorful Logging is a simple and efficient library allowing for logging and benchmarking.
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

Feb 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

Dec 20, 2022
A lightweight C++ logging library
A lightweight C++ logging library

Loguru: a lightweight and flexible C++ logging library. At a glance Documentation Documentation can be found at https://emilk.github.io/loguru/index.h

Jan 7, 2023
Portable, simple and extensible C++ logging library
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

Dec 29, 2022
Fast C++ logging library.

spdlog Very fast, header-only/compiled, C++ logging library. Install Header only version Copy the source folder to your build tree and use a C++11 com

Jan 1, 2023
Cute Log is a C++ Library that competes to be a unique logging tool.

Cute Log Cute Log is a C++ Library that competes to be a unique logging tool. Version: 2 Installation Click "Code" on the main repo page (This one.).

Oct 13, 2022
Minimalistic logging library with threads and manual callstacks

Minimalistic logging library with threads and manual callstacks

Dec 5, 2022
logog is a portable C++ library to facilitate logging of real-time events in performance-oriented applications

logog is a portable C++ library to facilitate logging of real-time events in performance-oriented applications, such as games. It is especially appropriate for projects that have constrained memory and constrained CPU requirements.

Oct 21, 2020
Boost Logging library

Boost.Log, part of collection of the Boost C++ Libraries, provides tools for adding logging to libraries and applications. Directories build - Boost.L

Dec 22, 2022
C++ implementation of the Google logging module

Google Logging Library The Google Logging Library (glog) implements application-level logging. The library provides logging APIs based on C++-style st

Jan 9, 2023
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

Jan 4, 2023
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

Sep 29, 2022
An Ultra Low Power temperature logger based on the ESP8266 MCU.
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

Nov 16, 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

Dec 20, 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

Jul 17, 2022