From 9bf7357ca8c1ef4cb794c0b0f9f7437ded45f449 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Mon, 14 Sep 2026 00:25:51 +0300 Subject: [PATCH 1/3] docs: add roadmap checklist and architecture decisions Separate delivered, planned, and intentionally deferred work in the maintained roadmap. Add an ADR template and accepted records for the public header boundary, executor ownership, immutable registry snapshots, TimeShield compatibility, and benchmark methodology, and link them from the documentation map. --- Doxyfile | 4 +- README-RU.md | 2 + README.md | 2 + docs/adr/0000-template.md | 24 ++++++ .../0001-aggregate-first-public-headers.md | 31 +++++++ docs/adr/0002-async-executor-model.md | 25 ++++++ docs/adr/0003-immutable-registry-snapshots.md | 25 ++++++ docs/adr/0004-timeshield-compatibility.md | 25 ++++++ docs/adr/0005-benchmark-methodology.md | 27 +++++++ docs/adr/README.md | 30 +++++++ docs/future-plans.md | 81 +++++++++++++++++++ docs/mainpage.dox | 1 + docs/quickstart.md | 5 ++ 13 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0000-template.md create mode 100644 docs/adr/0001-aggregate-first-public-headers.md create mode 100644 docs/adr/0002-async-executor-model.md create mode 100644 docs/adr/0003-immutable-registry-snapshots.md create mode 100644 docs/adr/0004-timeshield-compatibility.md create mode 100644 docs/adr/0005-benchmark-methodology.md create mode 100644 docs/adr/README.md create mode 100644 docs/future-plans.md diff --git a/Doxyfile b/Doxyfile index 4715b0d..bd8d0af 100644 --- a/Doxyfile +++ b/Doxyfile @@ -962,7 +962,9 @@ INPUT = ./include \ ./docs/OtlpHttpLogger.md \ ./docs/PrometheusLogger.md \ ./docs/TaskExecutor.md \ - ./docs/backpressure.md + ./docs/backpressure.md \ + ./docs/future-plans.md \ + ./docs/adr/README.md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/README-RU.md b/README-RU.md index 8a4ff05..a94128c 100644 --- a/README-RU.md +++ b/README-RU.md @@ -61,6 +61,8 @@ scope-замер. - [`docs/PrometheusLogger.md`](docs/PrometheusLogger.md) — payload/server-бэкенды, registry, scrape и ограничения. - [`docs/TaskExecutor.md`](docs/TaskExecutor.md) — варианты очереди, политики переполнения, hot resize и lifecycle. - [`docs/backpressure.md`](docs/backpressure.md) — настройка очереди и счётчики отброшенных задач. +- [`docs/future-plans.md`](docs/future-plans.md) — чеклист roadmap с разделением готовых, планируемых и отложенных задач. +- [`docs/adr/README.md`](docs/adr/README.md) — архитектурные решения, границы публичного API и записи о совместимости. ## Примеры макросов diff --git a/README.md b/README.md index f41aaa5..9553ac4 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ Detailed guides and documentation map: - [`docs/PrometheusLogger.md`](docs/PrometheusLogger.md) — payload/server backends, registry metrics, scrape configuration, and limitations. - [`docs/TaskExecutor.md`](docs/TaskExecutor.md) — queue variants, overflow policies, hot resize, and lifecycle guarantees. - [`docs/backpressure.md`](docs/backpressure.md) — application-facing queue tuning and drop counters. +- [`docs/future-plans.md`](docs/future-plans.md) — checked roadmap separating delivered, planned, and deferred work. +- [`docs/adr/README.md`](docs/adr/README.md) — architecture decisions, public-boundary rationale, and compatibility records. ## Macro Examples diff --git a/docs/adr/0000-template.md b/docs/adr/0000-template.md new file mode 100644 index 0000000..42c08e0 --- /dev/null +++ b/docs/adr/0000-template.md @@ -0,0 +1,24 @@ +# ADR NNNN: Short decision title + +- Status: Proposed +- Date: YYYY-MM-DD + +## Context + +What problem, constraint, or repeated failure mode requires a decision? + +## Decision + +State the chosen approach and its public contract precisely. + +## Consequences + +Describe benefits, costs, compatibility impact, and operational trade-offs. + +## Alternatives considered + +List the credible alternatives and why they were not selected. + +## References + +Link the implementation, tests, documentation, issues, or superseding ADRs. diff --git a/docs/adr/0001-aggregate-first-public-headers.md b/docs/adr/0001-aggregate-first-public-headers.md new file mode 100644 index 0000000..2666675 --- /dev/null +++ b/docs/adr/0001-aggregate-first-public-headers.md @@ -0,0 +1,31 @@ +# ADR 0001: Aggregate-first public headers and API boundary + +- Status: Accepted +- Date: 2026-09-14 + +## Context + +The library has many historical leaf headers, including +`logit/log_macros.hpp`. Treating every header as independently includable made +include order accidental and made internal implementation details look public. + +## Decision + +`` is the supported application entry point. The module umbrellas +``, ``, and `` are +supported focused entry points. Leaf headers are standalone only when their +documentation and include-contract test explicitly say so. `logit/log_macros.hpp` +is an aggregate-owned implementation header and has no standalone-inclusion +guarantee. Public aliases, including `logit::QueuePolicy`, are consumed through +the umbrella or the relevant module umbrella. + +## Consequences + +The include contract is predictable and can evolve without promising every +historical file as an API boundary. Documentation and tests must use the +nearest supported umbrella, while implementation headers remain free to change. + +## Alternatives considered + +Making every leaf header self-contained would increase compile cost and freeze +implementation structure without adding value for normal application code. diff --git a/docs/adr/0002-async-executor-model.md b/docs/adr/0002-async-executor-model.md new file mode 100644 index 0000000..2884e75 --- /dev/null +++ b/docs/adr/0002-async-executor-model.md @@ -0,0 +1,25 @@ +# ADR 0002: Shared and dedicated asynchronous executors + +- Status: Accepted +- Date: 2026-09-14 + +## Context + +Using one shared asynchronous executor is efficient for the default case, but +a slow backend can delay unrelated backends. A separate worker per backend +improves isolation at the cost of a thread and queue per opted-in backend. + +## Decision + +The shared `TaskExecutor` remains the default. Backends that support it expose +`Config::use_dedicated_executor`; when enabled for an asynchronous backend, it +owns a `SingleThreadExecutor` with its own queue, policy, wait, and shutdown +lifecycle. Platform-specific backends that cannot provide this behavior keep +their documented limitations. + +## Consequences + +Applications can choose throughput/resource sharing or isolation per backend. +The feature is already tested for lifecycle, mixed shared/dedicated operation, +and macro configuration. Changing the default is a separate compatibility and +resource-usage decision. diff --git a/docs/adr/0003-immutable-registry-snapshots.md b/docs/adr/0003-immutable-registry-snapshots.md new file mode 100644 index 0000000..002db7b --- /dev/null +++ b/docs/adr/0003-immutable-registry-snapshots.md @@ -0,0 +1,25 @@ +# ADR 0003: Immutable logger registry snapshots + +- Status: Accepted +- Date: 2026-09-14 + +## Context + +Copying the mutable logger registry under a read lock on every log call made +the normal dispatch path pay synchronization and allocation costs. Logger +registration and removal are infrequent compared with logging. + +## Decision + +Publish an immutable copy-on-write strategy-list snapshot on registry changes. +The hot path reads it with an atomic `shared_ptr` load. Mutable `enabled` and +`single_mode` state is atomic. The per-strategy execution mutex remains around +formatter/backend invocation because custom formatters and backends do not +have a universal concurrent-invocation contract. + +## Consequences + +Normal dispatch avoids the registry mutex and temporary vector copy while +preserving safe lifetime and mutation semantics. A future lock-elision path +requires an explicit capability contract and separate regression coverage; a +benchmark sink alone is not evidence that arbitrary backends are thread-safe. diff --git a/docs/adr/0004-timeshield-compatibility.md b/docs/adr/0004-timeshield-compatibility.md new file mode 100644 index 0000000..776f277 --- /dev/null +++ b/docs/adr/0004-timeshield-compatibility.md @@ -0,0 +1,25 @@ +# ADR 0004: TimeShield compatibility and dependency reuse + +- Status: Accepted +- Date: 2026-09-14 + +## Context + +The current TimeShield release is `v2.0.0`, whose CMake package uses +`SameMinorVersion` compatibility. Consumers may provide dependency targets +from a parent project or sibling build instead of installing another package +configuration. + +## Decision + +Pin the bundled submodule to the `v2.0.0` release and request +`TimeShield 2.0.0`, which expresses the supported `2.0.x` line. Before package +discovery, reuse an existing `time_shield::time_shield` target; installed +dependency discovery follows the same target-reuse rule for optional packages. + +## Consequences + +Build-tree and installed-package consumers remain composable, while the +minimum supported TimeShield API is explicit. Moving to another minor line or +changing the compatibility policy requires a new compatibility review and +release note. diff --git a/docs/adr/0005-benchmark-methodology.md b/docs/adr/0005-benchmark-methodology.md new file mode 100644 index 0000000..7205164 --- /dev/null +++ b/docs/adr/0005-benchmark-methodology.md @@ -0,0 +1,27 @@ +# ADR 0005: Benchmark evidence and comparison methodology + +- Status: Accepted +- Date: 2026-09-14 + +## Context + +Prepared records, the public macro path, formatted output, and external +library adapters measure different work. Mixing them into one number produces +misleading claims, and short CI runners are not a substitute for a fixed +publication machine. + +## Decision + +Keep separate scenarios for prepared-record dispatch, the real public +`LOGIT_INFO(...)` path, formatting, and external-library comparisons. The +public macro smoke benchmark may use a passthrough formatter when it is +explicitly documented as record-construction/dispatch coverage. Report +absolute timings only with compiler, platform, commit, queue, producer, and +flush settings; treat CI runs as regression smoke unless the environment is +fixed. + +## Consequences + +Benchmark documentation remains comparable and honest across changes. New +scenarios require their own workload contract and should not silently replace +historical measurements. diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..71cb586 --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,30 @@ +# Architecture Decision Records + +Architecture Decision Records (ADRs) capture decisions that should remain +discoverable after the implementation or the original discussion changes. +They complement the roadmap: the roadmap says **what is next**, while an ADR +explains **why the current boundary or trade-off exists**. + +## Statuses + +- **Proposed** — under discussion; do not treat it as a public contract. +- **Accepted** — the current implementation and documentation should follow it. +- **Superseded** — replaced by a newer ADR; retain it for historical context. +- **Rejected** — considered and intentionally not adopted. + +## Creating an ADR + +1. Copy [`0000-template.md`](0000-template.md) to the next zero-padded number. +2. Use a short, stable title and set the status/date. +3. Describe the context, decision, consequences, and rejected alternatives. +4. Update the implementation and user-facing documentation in the same change + when the decision changes a public contract. +5. Link a superseding ADR instead of rewriting an accepted historical record. + +## Accepted decisions + +- [0001 — Aggregate-first public headers and API boundary](0001-aggregate-first-public-headers.md) +- [0002 — Shared and dedicated asynchronous executors](0002-async-executor-model.md) +- [0003 — Immutable logger registry snapshots](0003-immutable-registry-snapshots.md) +- [0004 — TimeShield compatibility and dependency reuse](0004-timeshield-compatibility.md) +- [0005 — Benchmark evidence and comparison methodology](0005-benchmark-methodology.md) diff --git a/docs/future-plans.md b/docs/future-plans.md new file mode 100644 index 0000000..8481aab --- /dev/null +++ b/docs/future-plans.md @@ -0,0 +1,81 @@ +# Roadmap and delivery checklist — LogIt++ + +This file is the maintained roadmap, not a changelog. It deliberately separates +delivered capabilities from planned work and from ideas that are intentionally +delegated to user-defined `ILogger` implementations. + +Legend: + +- `[x]` delivered and covered by code/docs/tests; +- `[~]` available, but opt-in or platform-limited; +- `[ ]` planned work; +- `[-]` intentionally deferred, with no current commitment to implement it in + the core library. + +## Delivered + +- [x] Public aggregate-first header policy: `` is the supported + application entry point; module umbrellas and leaf-header contracts are + documented. +- [x] Public `logit::QueuePolicy` API and queue policy macros. +- [x] Immutable copy-on-write logger registry snapshots on the production hot + path, with atomic logger state and the existing execution mutex retained for + formatter/backend safety. +- [~] Dedicated per-backend worker threads via + `Config::use_dedicated_executor=true`. The default remains the shared + `TaskExecutor`; unsupported platform backends keep their documented + limitations. +- [x] Queue capacity, overflow policies, drop counters, resize behavior, and + flush/shutdown coverage. +- [x] MDC/NDC context, structured records, stored-log readers/subscribers, and + runtime log-level controls. +- [x] TimeShield `2.0.x` compatibility (minimum `2.0.0`) and dependency-target + reuse for build-tree and installed-package consumers. +- [x] Benchmark methodology and regression infrastructure: prepared-record hot + path A/B, public `LOGIT_INFO(...)` smoke benchmark, queue/CSV validation, + delayed-sink flush regression, and CI coverage. +- [x] Doxygen generation, GitHub Pages publication, header/layout smoke tests, + and the comparison guide for spdlog, Quill, Boost.Log, glog, and IceCream-Cpp. + +## Next planned work + +- [ ] **Release 1.0.2** — prepare changelog/release notes, verify package + overlays, generate the non-`-dev` documentation, tag the release, and verify + the published Pages site. +- [ ] **Binary logging research** — choose a versioned binary record format, + define compatibility/versioning rules, and prototype a reader before adding + a production backend. +- [ ] **Transparent compressed-file reads** — make `read_log_file()` and + `read_log_files()` read `.gz`/`.zst` entries when the corresponding feature is + enabled, with platform-specific tests. +- [ ] **Configuration loading** — design a versioned JSON/properties mapping to + the existing backend configuration. Treat file watching/hot reload as a + follow-up, not part of the first configuration API. +- [ ] **Extended filtering** — evaluate source/file, message, tag/MDC, and + range filters; define their cost and ordering before adding public API. +- [ ] **Benchmark follow-up** — add a genuinely formatted public-macro scenario, + a versioned fixture containing compiler/toolchain/commit/queue/flush metadata, + and a broader 1/4/16/32-producer matrix. Keep publication numbers tied to a + fixed machine and toolchain. +- [ ] **Concurrency fast-path research** — only after documenting a formal + thread-safety capability for formatters/backends. Do not remove `exec_mx` + based on benchmark results alone. + +## Intentionally deferred + +- [-] **Database/SQLite appender** — currently better implemented as a custom + `ILogger`; revisit if a common portable schema and maintenance owner emerge. +- [-] **Telnet/TCP appender** — application-specific transport and access + policy; implement as a custom backend unless a supported protocol is agreed. +- [-] **Main-thread GUI appender** — event-loop integration is framework and + platform specific; revisit when LogIt++ ships a GUI viewer. + +## How to update this document + +Move an item to `[x]` only when the implementation, tests, and user-facing +documentation agree. Use an ADR in [`docs/adr/`](adr/) for architectural +decisions or compatibility changes; keep this file focused on status and next +steps. Record measurements with their environment instead of turning one local +run into a universal performance claim. + +Last reviewed: 2026-09-14. diff --git a/docs/mainpage.dox b/docs/mainpage.dox index 21366c5..cf6d5ad 100644 --- a/docs/mainpage.dox +++ b/docs/mainpage.dox @@ -31,6 +31,7 @@ int main() { - \ref benchmarks — benchmark methodology and historical snapshot. - \ref api_reference — detailed macro, formatting, configuration, and extension reference. - \ref comparison — comparison with other C++ logging libraries and trade-offs. +- Architecture decisions — the source repository's [`docs/adr/`](https://github.com/LimiNode/log-it-cpp/tree/main/docs/adr) records the rationale for public boundaries, executors, snapshots, and compatibility. \section feature_summary Feature summary diff --git a/docs/quickstart.md b/docs/quickstart.md index d238f35..2075768 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -40,6 +40,11 @@ dependency requirements are described in the [`Backend matrix`](backends.html). the historical snapshot disclaimer. - **Choosing a logging library** — [`Comparison with other C++ logging libraries`](comparison.html), including trade-offs and the scope of the comparison. +- **Architecture decisions** — [`Architecture Decision Records`](https://github.com/LimiNode/log-it-cpp/tree/main/docs/adr), + including public API boundaries, executor ownership, snapshots, and + dependency compatibility. +- **Roadmap** — [`delivery checklist`](https://github.com/LimiNode/log-it-cpp/blob/main/docs/future-plans.md), + separating delivered, planned, and intentionally deferred work. - **Examples** — browse the `examples/` directory in the source repository; each optional example states the feature macro it requires. From d92c329be0636218a7919da3329e757c2b3ec576 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Mon, 14 Sep 2026 00:34:30 +0300 Subject: [PATCH 2/3] fix(docs): include all ADR files in Doxygen Feed the complete docs/adr directory to Doxygen so README links resolve for current and future records. Clarify the registry snapshot ADR in terms of registry mutations and reconfiguration rather than an unavailable remove API. --- Doxyfile | 2 +- docs/adr/0003-immutable-registry-snapshots.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index bd8d0af..2c871b0 100644 --- a/Doxyfile +++ b/Doxyfile @@ -964,7 +964,7 @@ INPUT = ./include \ ./docs/TaskExecutor.md \ ./docs/backpressure.md \ ./docs/future-plans.md \ - ./docs/adr/README.md + ./docs/adr # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/docs/adr/0003-immutable-registry-snapshots.md b/docs/adr/0003-immutable-registry-snapshots.md index 002db7b..89d11a9 100644 --- a/docs/adr/0003-immutable-registry-snapshots.md +++ b/docs/adr/0003-immutable-registry-snapshots.md @@ -7,7 +7,7 @@ Copying the mutable logger registry under a read lock on every log call made the normal dispatch path pay synchronization and allocation costs. Logger -registration and removal are infrequent compared with logging. +registry mutations and reconfiguration are infrequent compared with logging. ## Decision From 7b25aafeff04acf81e7d7cf009ad6b7fe2dd71c9 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Mon, 14 Sep 2026 00:35:49 +0300 Subject: [PATCH 3/3] fix(docs): avoid broken roadmap ADR link Use the repository ADR index URL from the generated roadmap page so Doxygen link validation does not treat the source directory as a missing local HTML target. --- docs/future-plans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/future-plans.md b/docs/future-plans.md index 8481aab..b1b895e 100644 --- a/docs/future-plans.md +++ b/docs/future-plans.md @@ -73,7 +73,7 @@ Legend: ## How to update this document Move an item to `[x]` only when the implementation, tests, and user-facing -documentation agree. Use an ADR in [`docs/adr/`](adr/) for architectural +documentation agree. Use an ADR in [`docs/adr`](https://github.com/LimiNode/log-it-cpp/tree/main/docs/adr) for architectural decisions or compatibility changes; keep this file focused on status and next steps. Record measurements with their environment instead of turning one local run into a universal performance claim.