![]() |
LogIt++
Header-only, macro-first C++ logging library
|
This page is a design and feature comparison, not a universal ranking. It answers a practical question: when does LogIt++ fit better than a smaller formatted-string logger, a general event framework, or a diagnostic macro utility?
The comparison was checked on 2026-09-15 against these upstream releases:
| Project | Release checked | Primary documentation |
|---|---|---|
| LogIt++ | v1.0.2 | project documentation |
| spdlog | v1.17.0 | README, async logging |
| Quill | v13.0.0 | project documentation |
| Boost.Log | Boost 1.92.0 | Boost.Log documentation |
| glog | v0.7.1 | glog documentation |
| IceCream-Cpp | v1.0.0 | project README |
Upstream projects evolve independently. Re-check the release and linked documentation before using this page as a procurement or performance claim.
LogIt++ is designed around a diagnostic record rather than only a finished string. A normal macro call can keep values and argument names available to formatters, memory/storage backends, callbacks, and telemetry exporters. The same macro-first surface also covers conditional logging, throttling, scope timers, tags, MDC/NDC context, and targeted logger routing.
This makes LogIt++ a good fit when logging is part of an application's diagnostic data flow. It is a less obvious fit when the only requirement is the smallest possible formatted-string call on a hot path.
The table describes the primary distribution and documented API of each project, not everything that can be built through third-party adapters. Built in means the checked release documents the capability directly. Different model means that a similar outcome exists, but the abstraction is not equivalent. Extension means that an adapter, custom sink, or application code is normally required. A dash means that the capability is not a primary goal of the checked project, not that it is impossible to implement.
| Capability | LogIt++ | spdlog | Quill | Boost.Log | glog | IceCream-Cpp |
|---|---|---|---|---|---|---|
| Macro-first instrumentation | Built in | Built-in severity macros | Built in macros | Built-in macros over a record/stream model | Built in macros | Core feature |
| Structured records / attributes | Built in LogRecord and values | Formatted messages plus MDC (synchronous logging only); different record model | Built-in named-value logging, JSON output, tags, and MDC; different record model | Built in attribute/event model | Extension / message-centric | Diagnostic values, not a sink record |
| Capture source argument names | Built in | — | Built in via LOGV_* | — | — | Core feature |
{fmt}-style formatting | Built in when LOGIT_WITH_FMT=ON | Built in | Built in | Extension / pre-formatting | Extension / pre-formatting | — |
printf-style logging | Built in | Extension / pre-formatting | Extension / pre-formatting | Extension / pre-formatting | Low-level RAW_LOG only (stderr-only) | — |
| Stream-style logging | Built in | Extension / pre-formatting | Extension / pre-formatting | Built in | Built in | Human-readable diagnostic output |
| Conditional logging helpers | Built in | No dedicated helper; use an application condition | No dedicated helper; use an application condition | Filters and predicates; no equivalent call-site macro | Built in via LOG_IF | Configuration helpers, not a logging framework |
| Rate-limited logging helpers | Built in | No dedicated macro family | Built in via LOG_*_LIMIT and LOGV_*_LIMIT | Extension / custom filter | Built in via LOG_EVERY_N, LOG_FIRST_N, and related macros | — |
| Asynchronous queue | Built in | Built in | Core design | Built in via asynchronous sink frontends | Not the primary model | — |
| Configurable overflow/backpressure | Built in (Block, DropNewest, DropOldest) | Built in overflow policies | Built-in bounded/unbounded and blocking/dropping queue modes | Built in via bounded async sink queue strategies (drop_on_overflow, block_on_overflow) | — | — |
| Rotating file sink | Built in | Built in | Built in via RotatingFileSink | Built in sink types | Built-in file rollover/cleanup; different model | — |
| In-memory history and read-back | Built in for selected backends | Built-in backtrace buffer; no equivalent read-back API | Built-in backtrace logging; no equivalent read-back API | Extension / custom sink | — | — |
| Live log subscriptions | Built in for selected backends | Built-in callback sink; different model | Extension / custom sink | Extension / custom sink | — | — |
| Embedded queryable structured storage | Built in via optional MDBX backend | Extension | Extension | Extension | — | — |
| OTLP / OpenTelemetry log export | Built in optional backend | Extension / adapter | Extension / custom sink | Extension / adapter | Extension / adapter | — |
| Prometheus metrics | Built in optional backends | Extension / adapter | Built in via PrometheusSink | Extension / adapter | Extension / adapter | — |
| Header-only integration | Built in | Supported mode | CMake/library integration | Compiled Boost component | CMake/library integration | Header-oriented utility |
The word “built in” is intentionally narrow. For example, all of these projects can be connected to other sinks or telemetry systems by application code; that does not make the integration part of the primary distribution.
LogIt++ deliberately provides a large, regular macro surface:
The first call can retain the names and values of host and port, depending on the selected macro and build options. That is different from passing one already formatted string to a sink. It is convenient for diagnostics, but it also does more work than a minimal formatted-string call.
spdlog, Quill, and glog also provide useful macro families, but their primary abstractions remain logger calls, formatted messages, or severity/check macros. Boost.Log provides logging macros over its record, attribute, filter, and sink model rather than a single broad macro facade. IceCream-Cpp is the closest comparison as a dedicated introspection utility; Quill also captures source variable names through its LOGV_* logging macros.
IceCream-Cpp is a diagnostic printing/introspection utility. It is valuable when a developer wants a short call that displays an expression and its value:
It does not aim to provide LogIt++-style sinks, asynchronous queues, file rotation, retention/read-back, subscriptions, OTLP, or Prometheus backends. The meaningful comparison is therefore the ergonomics of source-level diagnostics and argument-name capture, not “which logger has more sinks”. IceCream-Cpp can also be used alongside a real logger.
LogIt++ offers synchronous and asynchronous modes, global or dedicated executors, queue capacity, and explicit overflow policies. The deque and MPSC implementations intentionally document a semantic difference: in MPSC mode DropOldest rejects the incoming task to preserve the order of already accepted work.
spdlog and Quill are closer comparisons for asynchronous throughput and queue configuration. Their options, worker topology, and overflow semantics are not interchangeable with LogIt++, so a benchmark must hold the workload and delivery contract constant. Boost.Log provides asynchronous sink frontends, including bounded FIFO queues with drop-on-overflow and block-on-overflow strategies, through a more general sink configuration model. glog and IceCream-Cpp are not primary comparisons for this queue design.
Choose LogIt++ when the log record itself is useful after the logging call:
MemoryLogger supports snapshots, readers, and subscribers;FileLogger supports persisted-file enumeration and text read-back;MdbxLogger retains structured records for later querying;Boost.Log is the closest architectural comparison for an extensible record, attribute, filter, and sink pipeline. spdlog is usually simpler to adopt for formatted messages and high-throughput sinks. Quill combines that performance focus with named-value macros, JSON output, tags, and MDC through its own record model. glog is focused on application diagnostics and severity/check macros. These are trade-offs in scope, not a claim that one design is universally better.
The repository currently has a reproducible prepared-message/direct-dispatch pipeline adapter for LogIt++ and spdlog, not for every project in the feature table. The historical fixture below is therefore a legacy LogIt++/spdlog pipeline snapshot, not a ranking of all six projects. It does not measure the full public LOGIT_INFO(...) macro path; in particular, it omits argument-name parsing and args_array construction. The LogIt++ adapter constructs its LogRecord and copies the message into std::string during the timed call, while spdlog receives a prepared string_view; those call contracts are intentionally documented rather than presented as identical.
| Mode | Sink | LogIt++ p50 | LogIt++ throughput | spdlog p50 | spdlog throughput |
|---|---|---|---|---|---|
| Sync | Null | 119 ns | 2,127,704 msg/s | 86 ns | 5,803,783 msg/s |
| Sync | File | 130 ns | 1,035,690 msg/s | 87 ns | 1,593,987 msg/s |
| Async | Null | 20,916 ns | 1,846,272 msg/s | 1,248,779 ns | 1,303,573 msg/s |
| Async | File | 255,323 ns | 651,384 msg/s | 5,001,140 ns | 1,153,976 msg/s |
Snapshot conditions: Release build, four producers, 200-byte messages, LOGIT_BENCH_TOTAL=10000, and the fixture recorded on 2025-12-05. The timed LogIt++ adapter constructs a LogRecord and owns a message copy, while the spdlog adapter receives a prepared string_view. Async values also include enqueue, worker wake-up/scheduling, and sink work.
The CSV is a legacy fixture: its spdlog version, compiler/toolchain, harness commit, queue capacity, and async drain protocol were not recorded. Do not use it as a current numeric comparison; regenerate a versioned fixture after the benchmark protocol changes.
See docs/benchmarks.md for the methodology and bench/results/latency-2025-12-05-10k.csv for the complete fixture. The harness does not currently measure allocations per message, binary size, compile time, or comparable Quill/Boost.Log/glog scenarios; those numbers are intentionally not invented here.
Choose LogIt++ with its trade-offs in mind:
Choose LogIt++ when:
Consider spdlog when:
Consider Quill when:
Consider Boost.Log when:
Consider glog when:
The upstream google/glog repository was archived and made read-only as of the 2026-09-15 check; account for that lifecycle status before adopting it as a new dependency.
Consider IceCream-Cpp when:
The version and source links at the top of this page are the authoritative starting points for the feature comparison. For LogIt++ behavior, prefer the linked project guides, generated API reference, examples, and benchmark fixture in this repository. Re-run benchmarks on the target compiler, operating system, hardware, sink, queue configuration, and workload before making a performance decision.