MCPcopy Create free account
hub / github.com/ChristianPanov/lwlog

github.com/ChristianPanov/lwlog @v1.5.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.5.0 ↗ · + Follow
267 symbols 402 edges 56 files 0 documented · 0% updated 19d agov1.5.0 · 2025-12-25★ 3475 open issues

Browse by type

Functions 174 Types & classes 93
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Windows Linux macOS\ Codacy Badge CodeFactor\ SonarCloud\ Quality Gate Status Bugs Code Smells Vulnerabilities\ Security Rating Maintainability Rating Technical Debt

Very fast C++17 logging library

Install

git clone --recursive https://github.com/ChristianPanov/lwlog

Installing the CMake Package

cmake -B <Build Directory> -S <Directory of CMakeLists.txt> -DCMAKE_INSTALL_PREFIX=<Installation Directory>
cmake --build <Build Directory> --target install --config <Debug/Release>

Linking lwlog to your project with CMake

find_package(lwlog_lib HINTS <Installation Directory>/lib/cmake)

target_link_libraries(MyExe PRIVATE lwlog::lwlog_lib)

Supported Platforms and Compilers

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

The Most Important Question - Why Yet Another Logging Library?

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.

Design Highlights

  • Zero Allocation Log Call: lwlog eliminates dynamic memory allocations during log calls by using a pre-allocated static buffer for string formatting. This improves performance by avoiding frequent heap allocations and reducing memory fragmentation—especially important for high-frequency logging in resource-constrained or real-time environments.
  • Performance: lwlog offers very fast logging capabilities, both in synchronous and asynchronous modes, ensuring minimal impact on your application’s performance.
  • Extensibility: Adding new types of sinks and loggers is straightforward, providing flexibility to adapt the library to your specific needs. Check out how to create your own sink for a practical example
  • Configurability: lwlog uses policy classes which you can just plug in based on your needs.
  • Ease of Use: lwlog tries to follow a philosophy of intuitiveness. As the author, I am biased, so I can only hope the API is as intuitive as I see it in my eyes. Convenient easy-to-use predefined types(convenience aliases) are made for simplicity without too much configuration. Most of the time, you will be just fine with using the predefined types.
  • Code Base: The code is crafted with clarity, elegance, and readability in mind, hoping it is structured enough to prove relatively easy for developers to understand, modify, extend, and learn from.

Features

Benchmarks

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
===============================================================================

Logical Architecture

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

Core symbols most depended-on inside this repo

Shape

Method 159
Class 88
Function 15
Enum 5

Languages

C++100%

Modules by API surface

lwlog/include/details/pattern/formatters.h62 symbols
lwlog/include/logger_impl.h18 symbols
Sandbox/Benchmark.h17 symbols
lwlog/include/details/pattern/pattern_impl.h11 symbols
lwlog/include/details/memory_buffer_impl.h11 symbols
lwlog/include/policy/concurrency_policy.h10 symbols
lwlog/include/details/source_meta_impl.h7 symbols
lwlog/include/buffer_limits.h7 symbols
lwlog/include/policy/log_policy.h6 symbols
lwlog/include/details/pattern/sgr_encoder_impl.h6 symbols
lwlog/include/details/pattern/alignment_formatter_impl.h6 symbols
lwlog/include/details/bounded_queue/bounded_queue_impl.h6 symbols

For agents

$ claude mcp add lwlog \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page