Browse by type
Very fast C++17 logging library
git clone --recursive https://github.com/ChristianPanov/lwlog
cmake -B <Build Directory> -S <Directory of CMakeLists.txt> -DCMAKE_INSTALL_PREFIX=<Installation Directory>
cmake --build <Build Directory> --target install --config <Debug/Release>
find_package(lwlog_lib HINTS <Installation Directory>/lib/cmake)
target_link_libraries(MyExe PRIVATE lwlog::lwlog_lib)
The project is continuously tested on the following platforms and compilers: | Platform | Architecture | Compilers Supported |----------|----------------------|----------------------------------------------- | Windows | x64 | MSVC, MinGW (MINGW64, UCRT64), Clang | Linux | x64 | GCC, Clang, Intel oneAPI (icx/icpx) | Linux | arm64 | GCC, Clang | macOS | x64 | Apple Clang
Another logging library, how boring, right, as If we don't see a new one each week. So why do I keep shoving it down your throats for a drop of recognition? I will cut short on the speed or code simplicity that every other logging library boasts about. The actual importance of the library lies within its meaning to me. This library has served as a pivotal factor in my journey to becoming a software craftsman. I started it when I knew very little, and when I still made no distinction between writing reusable pieces of code and crafting libraries. I can say that I am proud of what I've made, for it has been a long journey comprised of not giving up and constantly daring to do what was currently impossible for me, which forced me to broaden my knowledge very quickly and apply that knowledge in practice. As you will see later in the documentation, I do claim this library to be very fast and to have very clean code. I do claim to have designed it in a good way. However, even if that weren't objectively true, that would make no difference in the importance of this work to me, as I would still be just as proud of it, for it's an extension of my essence, a reflection of my discipline, perseverance, my desire for perfection and improvement, most importantly, of my love of the process, love of the craft. And if it were a half-baked product of any of those attributes, I would rest assured that it's only a matter of time before it sheds its ugly skin and something better emerges from within, a natural consequence of loving the journey more than the destination itself - inevitable metamorphosis to something greater.
No matter what you do or say, there will always be people who hold a different view. It might always happen that you were in the wrong or that you could have done better. Anyone could take away the joy of your creation. However, no one can take away the hours you've spent crafting it, no one can take away the hours you've spent studying and learning in the process, no one can take away the times when you've felt the pride-inducing adrenaline rush when you faced a challenge that was out of your league, were stubborn enough not to give up, and actually did it. No one can take away any of that, any of the things that should make you proud. That's what real craftsmanship is - taking pride in what you do with all your heart and being too stubborn to give up on the currently impossible, it is an act of self expression that transcends simple interest and mindless action.
Benchmarked with picobench(https://github.com/iboB/picobench)
lwlog(synchronous) vs spdlog(synchronous)
===============================================================================
Name (baseline is *) | Dim | Total ms | ns/op |Baseline| Ops/second
===============================================================================
lwlog_bench * | 8 | 0.652 | 81512 | - | 12268.1
spdlog_bench | 8 | 4.844 | 605500 | 7.428 | 1651.5
lwlog_bench * | 64 | 5.347 | 83540 | - | 11970.2
spdlog_bench | 64 | 46.576 | 727746 | 8.711 | 1374.1
lwlog_bench * | 512 | 53.725 | 104931 | - | 9530.1
spdlog_bench | 512 | 135.479 | 264606 | 2.522 | 3779.2
lwlog_bench * | 4096 | 451.722 | 110283 | - | 9067.5
spdlog_bench | 4096 | 1205.387 | 294283 | 2.668 | 3398.1
lwlog_bench * | 8192 | 923.731 | 112760 | - | 8868.4
spdlog_bench | 8192 | 2334.964 | 285029 | 2.528 | 3508.4
===============================================================================
lwlog(synchronous, buffered) vs spdlog(synchronous)
===============================================================================
Name (baseline is *) | Dim | Total ms | ns/op |Baseline| Ops/second
===============================================================================
lwlog_bench * | 8 | 0.016 | 2012 | - | 496894.4
spdlog_bench | 8 | 5.144 | 642950 |319.478 | 1555.3
lwlog_bench * | 64 | 0.078 | 1218 | - | 820512.8
spdlog_bench | 64 | 19.179 | 299673 |245.886 | 3337.0
lwlog_bench * | 512 | 0.629 | 1228 | - | 813731.7
spdlog_bench | 512 | 180.569 | 352673 |286.982 | 2835.5
lwlog_bench * | 4096 | 4.961 | 1211 | - | 825640.0
spdlog_bench | 4096 | 1230.367 | 300382 |248.008 | 3329.1
lwlog_bench * | 8192 | 11.767 | 1436 | - | 696160.6
spdlog_bench | 8192 | 2793.686 | 341026 |237.409 | 2932.3
===============================================================================
lwlog(asynchronous, blocking) vs spdlog(asynchronous, blocking)
===============================================================================
Name (baseline is *) | Dim | Total ms | ns/op |Baseline| Ops/second
===============================================================================
lwlog_bench * | 8 | 0.000 | 50 | - | 20000000.0
spdlog_bench | 8 | 0.006 | 812 | 16.250 | 1230769.2
lwlog_bench * | 64 | 0.002 | 34 | - | 29090909.1
spdlog_bench | 64 | 0.016 | 243 | 7.091 | 4102564.1
lwlog_bench * | 512 | 0.017 | 33 | - | 30295858.0
spdlog_bench | 512 | 0.069 | 133 | 4.059 | 7463556.9
lwlog_bench * | 4096 | 4.290 | 1047 | - | 954756.3
spdlog_bench | 4096 | 2316.282 | 565498 |539.913 | 1768.4
lwlog_bench * | 8192 | 9.852 | 1202 | - | 831481.0
spdlog_bench | 8192 | 2050.576 | 250314 |208.132 | 3995.0
===============================================================================
lwlog(asynchronous, nonblocking) vs spdlog(asynchronous, nonblocking)
===============================================================================
Name (baseline is *) | Dim | Total ms | ns/op |Baseline| Ops/second
===============================================================================
lwlog_bench * | 8 | 0.000 | 37 | - | 26666666.7
spdlog_bench | 8 | 0.006 | 775 | 20.667 | 1290322.6
lwlog_bench * | 64 | 0.002 | 32 | - | 30476190.5
spdlog_bench | 64 | 0.028 | 434 | 13.238 | 2302158.3
lwlog_bench * | 512 | 0.016 | 31 | - | 32000000.0
spdlog_bench | 512 | 0.103 | 201 | 6.438 | 4970873.8
lwlog_bench * | 4096 | 0.180 | 43 | - | 22730299.7
spdlog_bench | 4096 | 0.673 | 164 | 3.737 | 6082566.1
lwlog_bench * | 8192 | 0.426 | 52 | - | 19230046.9
spdlog_bench | 8192 | 1.036 | 126 | 2.431 | 7911154.0
===============================================================================
Logger
└── Sink
└── Record
The architecture of lwlog is very simple, it's divided into three main modules - the logger, the sinks, and the record.
Module | Description
------------ | -------------
Record | An object that encapsulates the data that will be logged, including the message, logging level, metadata (current line, file, and function), timepoint, and execution context (current thread ID and process ID).
Sink | An object that sends(sinks) data to an output destination. Usually, the data could be handled by a writer object, or you can directly handle the output in the sink_it() function without using a writer.
Logger | An object that manages a
$ claude mcp add lwlog \
-- python -m otcore.mcp_server <graph>