|
16 | 16 |
|
17 | 17 | ```cpp |
18 | 18 | #include "include/logger.hpp" |
19 | | -#include "include/logger_config.hpp" |
20 | 19 | #include <memory> |
21 | 20 |
|
22 | 21 | int main() { |
23 | | - auto log = c_log::logger_from_config("logger.json"); |
24 | | - log->info("startup").kv("user", "alice").kv("run", 1); |
25 | | -} |
26 | | -``` |
27 | | - |
28 | | -// logger.json example: |
29 | | -``` |
30 | | -{ |
31 | | - "mode": "async", // "sync" or "async" |
32 | | - "level": "info" // "trace", "debug", ... |
| 22 | + c_log::Logger log; // Async by default, writes to console |
| 23 | + log.info("startup").kv("user", "alice").kv("run", 1); |
33 | 24 | } |
34 | 25 | ``` |
35 | 26 |
|
36 | 27 | > [!IMPORTANT] |
37 | 28 | > Allow the `Logger` object to remain in scope until all events are logged. The logger flushes automatically when it is destroyed (typically when going out of scope). |
38 | 29 |
|
39 | 30 | ## Installation |
40 | | -Add the `include/` directory to the project's include paths. The only requirements are a compiler supporting at least C++17 and the bundled nlohmann/json. No external dependencies are needed. |
| 31 | +Add the `include/` directory to the project's include paths. The only requirement is a compiler supporting at least C++17. No external dependencies are needed. |
41 | 32 |
|
42 | 33 | > [!CAUTION] |
43 | 34 | > When compiling on Windows, ensure the compiler supports at least C++17. Consult [CI status](https://github.com/mbn-code/cLog/actions) for verified environments. |
44 | 35 |
|
45 | 36 | ## Benchmarks |
46 | 37 |
|
47 | | -The graph below presents the average time (in microseconds) to log a single entry under different modes and sinks (lower is better): |
48 | | - |
49 | | -<p align="center"> |
50 | | - <img src="./benchmarks/benchmark.png" alt="cLog benchmarks bar graph" width="500"> |
51 | | -</p> |
52 | | - |
53 | | -_Benchmark run on a modern Linux machine (100,000 logs per variant, see `benchmarks/benchmark_logger.cpp`). |
54 | | -Benchmarks were performed locally on an AMD Ryzen 9 9800X3D with 32GB DDR5-6000 CL30 RAM._ |
55 | | - |
56 | | -> **Note:** These results reflect a recent optimization. All cLog logging modes are now below 0.5μs per log entry, greatly improving over previous results (which ranged from 1.0–1.2μs per log). |
57 | | -
|
58 | | -**Benchmark Comparison with Other Popular Logging Libraries** |
| 38 | +The table below presents the average time (in microseconds) to log a single entry under different modes and sinks (lower is better): |
59 | 39 |
|
60 | | -| Logger | Mode | Threads | Output | Time per Log (μs) | Logs/sec (approx) | Source | |
61 | | -|--------------|-----------|----------|------------|-------------------|---------------------|-----------------------------| |
62 | | -| **cLog** | sync | 1 | File | 0.40 | 2,500,000 | This repo, Ryzen 9800X3D | |
63 | | -| **cLog** | async | 1 | File | 0.47 | 2,130,000 | This repo, Ryzen 9800X3D | |
64 | | -| **cLog** | sync | 1 | Console | 0.35 | 2,860,000 | This repo, Ryzen 9800X3D | |
65 | | -| **cLog** | async | 1 | Console | 0.41 | 2,440,000 | This repo, Ryzen 9800X3D | |
66 | | -| **spdlog** | sync | 1 | File | 0.17 | 5,770,000 | [spdlog README](https://github.com/gabime/spdlog#benchmarks) | |
67 | | -| **spdlog** | async | 10 | File | 0.37 | 2,700,000 | [spdlog README](https://github.com/gabime/spdlog#benchmarks) | |
68 | | -| **spdlog** | sync | 10 | File | 0.60 | 1,660,000 | [spdlog README](https://github.com/gabime/spdlog#benchmarks) | |
| 40 | +| Logger | Mode | Threads | Output | Time per Log (μs) | Source | |
| 41 | +|--------------|-----------|----------|------------|-------------------|-----------------------------| |
| 42 | +| **cLog** | sync | 1 | File | 0.76 | MacBook Pro (M1 Pro) | |
| 43 | +| **cLog** | async | 1 | File | 0.23 | MacBook Pro (M1 Pro) | |
| 44 | +| **cLog** | sync | 1 | Console | 0.63 | MacBook Pro (M1 Pro) | |
| 45 | +| **cLog** | async | 1 | Console | 0.22 | MacBook Pro (M1 Pro) | |
69 | 46 |
|
70 | | -<sub>Numbers for spdlog are for Ubuntu 64-bit, i7-4770 3.4GHz. cLog benchmarks were run with 100,000 logs per variant on a modern Linux system. 'Logs/sec' values are approximate, calculated as 1,000,000 / μs-per-log (higher is better).</sub> |
| 47 | +> **Note:** Benchmarks were performed locally on a MacBook Pro (M1 Pro). The `async` mode leverages a lock-free ring buffer and a background worker thread, minimizing latency for the logging thread. |
71 | 48 |
|
72 | 49 | **Performance Context:** |
73 | | -- spdlog is recognized for leading performance in minimal-formatting settings. |
74 | | -- cLog offers performance within a small multiple of spdlog. For most high-throughput applications, sub-2μs throughput is suitable for demanding scenarios. |
75 | | -- Structured logging and a modern, expressive API are provided out of the box. |
| 50 | +- **cLog** provides high-throughput structured logging with minimal overhead. |
| 51 | +- By removing heavy dependencies and optimizing the JSON serialization path, cLog achieves sub-microsecond latency even in synchronous mode. |
| 52 | +- For optimal multi-threaded performance, asynchronous mode is recommended. |
76 | 53 |
|
77 | 54 | --- |
78 | 55 |
|
79 | 56 | --- |
80 | 57 |
|
81 | 58 | ## Features |
82 | | -- Asynchronous and synchronous operation modes (`Logger::Mode`) |
83 | | -- Safe, automatic background flushing and shutdown |
84 | | -- Console and file sinks included |
85 | | -- Fully structured JSON output |
86 | | -- Chainable API: `info().kv().kv()` and all standard log levels (`debug()`, `warn()`, `error()`, etc.) |
87 | | -- Race-free, lossless, and cross-platform operation |
| 59 | +- **Zero External Dependencies:** No need for `nlohmann/json` or any other library. Just standard C++17. |
| 60 | +- **Lightweight & Fast:** Custom, zero-allocation optimized JSON serializer. |
| 61 | +- **Asynchronous & Synchronous:** Flexible operation modes (`Logger::Mode`). |
| 62 | +- **Chainable API:** `info().kv().kv()` style. |
| 63 | +- **Safe:** Automatic background flushing and lossless shutdown. |
| 64 | +- **Cross-Platform:** Works on Linux, macOS, and Windows. |
88 | 65 |
|
89 | 66 | > [!TIP] |
90 | 67 | > For optimal multi-threaded performance, asynchronous mode is recommended. |
@@ -119,7 +96,7 @@ log.add_sink(std::make_unique<MySink>()); |
119 | 96 | - [x] CI/test coverage (Linux/Ubuntu) |
120 | 97 | - [ ] More flexible external sink/plugin system |
121 | 98 | - [ ] Windows and Mac CI |
122 | | -- [x] Simple config file support (JSON, see examples/logger.json, logger_config.hpp) |
| 99 | +- [x] Simple structured logging (JSON) without external deps |
123 | 100 |
|
124 | 101 | ## License |
125 | 102 | MIT - see [LICENSE](LICENSE) |
|
0 commit comments