|
Logger System 0.1.3
High-performance C++20 thread-safe logging system with asynchronous capabilities
|
This guide enumerates the most common runtime problems people hit when adopting logger_system, the symptoms to look for, and the recommended fixes. For configuration questions consult Frequently Asked Questions; for end-to-end walkthroughs see the tutorials linked from the project main page.
logger::metrics() are non-zero.logger::stop() (or the destructor was skipped because of std::abort / _exit).logger::stop() during shutdown. It flushes the queue and joins the worker thread. Wrap your service entry point in an RAII guard if your shutdown path is non-trivial.critical_writer for events that must never be lost. It blocks the producer when the queue is full instead of dropping silently.dropped_total > 0.logger->add_writer() succeeds but no file appears on disk.metrics().last_error reports permission_denied or path_not_found.failed to open file: /var/log/app.log to stderr.~/logs/app.log) which the file writer does not perform.create_parents was not enabled.chown it to the service user. The CMake install rules can do this for you./var/log/myapp/app.log) instead of relying on the working directory or shell expansion.ls -lZ (SELinux) or aa-status (AppArmor) and add a policy exception for the log directory.rotating_file_writer, ensure the rotation root has enough inodes and free space; rotation will fail silently if rename(2) cannot complete.metrics().queue_depth is consistently near capacity.dropped_total (or the analogous counter for your queue policy) is growing.try_enqueue returning false.encrypted_writer with a large key buffer) is the bottleneck.metrics().writer_latency_ns to identify the slow stage.batch_writer between buffered and the core writer to amortize syscalls.set_level for noisy modules or adopting per-component loggers.critical_writer for must-have entries and accept blocking back-pressure on the producer.metrics().writes_per_second is low.std::format, to_string, or mutex::lock near the top.format() allocates strings on the hot path.thread_safe_writer wrapping an already-thread-safe core writer, doubling the lock cost.-O0) hides decorator inlining.log_structured() for hot paths; it avoids constructing intermediate strings.thread_safe_writer layers. All built-in core writers are already thread-safe.-O2 -DNDEBUG) for benchmarking.LOGGER_USE_THREAD_SYSTEM, confirm the thread pool has enough workers and is not contending with the rest of the application.cmake --preset release -DBUILD_BENCHMARKS=ON then ./build/benchmarks/logger_bench) on the target hardware to obtain a realistic baseline.no matching function for call).build() multiple times on the same writer_builder instance.start() on a chain that contains an async_writer.async_writer with buffered_writer (the buffer flushes on the caller thread, defeating async).std::unique_ptr) with shared ownership (std::shared_ptr).encrypted_writer after key rotation.writer_builder per chain. Builders are single-use.logger::start() after add_writer() so the propagation reaches every async layer. If you build a chain manually, downcast and call async_writer::start() directly.get_name() of the root writer to verify the chain matches what you intended: secure_key_storage so rotation events propagate atomically; never copy raw key bytes between writer instances.If none of the above fits your symptoms:
logger::enable_self_diagnostics(true). This routes logger_system's own warnings to stderr.