慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

D
Docker
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - Franky
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
博客园 - 聂微东
S
SegmentFault 最新的问题
量子位
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Domain-Based C++ Logging With Nova
Kleetus MacT · 2026-05-24 · via DEV Community

Kleetus MacTavish

Introducing Nova - A Deterministic C++ Logging Library With Domain-Based Routing

Repository: https://github.com/kmac-13/nova/
Benchmarks: https://github.com/kmac-13/nova/blob/main/docs/BENCHMARKS.md

I am pleased to announce the initial release of Nova - a modern C++ logging library focused on deterministic behavior, compile-time configurability, and flexible domain-based routing for systems ranging from hosted platforms down to bare-metal and safety-critical environments.

Why Another Logging Library?

There are already several quality C++ logging libraries available. However, most logging libraries organize routing and filtering around severity levels and rely on global logger configuration or runtime string-based logging categories. Engineers are often forced to encode subsystem behavior into a limited set of severity levels while also considering which thresholds will be enabled in production. This also leads to situations where enabling debug logging for one subsystem effectively requires enabling debug logging across unrelated areas of the application.

Nova instead treats logging domains as compile-time types, allowing logging configuration and routing to directly reflect application structure rather than forcing subsystems into global severity categories.

Domains can represent subsystems, modules, interfaces, classes, libraries, or any other domain-specific concept, and each domain can be independently enabled, disabled, or routed without reliance on shared global configuration. Because domains are independent types rather than shared string identifiers, libraries can define their own logging domains without interfering with application or third-party logging configuration.

  • type-defined logging domains - log against subsystems, modules, classes, libraries, or any other concept
  • compile-time elimination of disabled domains - language-guaranteed in C++17, optimiser-dependent in C++11/14
  • compile-time routing - avoids reliance on global logger registries or shared runtime configuration

Additional goals of the library include:

  • simple pipeline and extensible API
  • deterministic behavior - no heap, no exceptions, no RTTI
  • support for platforms ranging from hosted systems down to bare-metal
  • fast enough for demanding real-time and multithreaded workloads

Nova also includes Flare, an async-signal-safe crash and forensic logging component that writes structured diagnostic records directly to disk from signal handlers - without heap allocation, locks, or non-signal-safe C++ runtime features.

Example

#include <nova.h>

// define a domain (can be any type)
struct MotionPlanner {};  

// configure the domain with a name (MOTION), enabled state (true), and clock type (steadyNanosecs)
NOVA_LOGGER_TRAITS( MotionPlanner, MOTION, true, kmac::nova::TimestampHelper::steadyNanosecs );

int main()
{
    // configure motion planner sink as mpSink
    ...

    // bind the mpSink to the MotionPlanner logging domain
    kmac::nova::ScopedConfigurator config;
    config.bind< MotionPlanner >( &mpSink );

    // log
    NOVA_LOG( MotionPlanner ) << "Planning trajectory...";
}

Enter fullscreen mode Exit fullscreen mode

Here we can see that the MotionPlanner domain is defined, the traits for the domain are configured, a target sink is bound to the domain, and logging is performed. In this example, the domain is a simple, empty struct, but a domain can be any type, including interface, abstract, or concrete classes. A domain can even be a specific class, and logging can be limited to the scope of that class.

Using types as logging domains enables compile-time routing, strong subsystem separation, and per-domain configuration and enablement. Disabled domains can be eliminated entirely by the compiler, and type names prevent the silent runtime failures that string-based routing can introduce.

Additionally, per-domain control means that enabling verbose logging for one subsystem has no effect on any other - there is no shared severity threshold to raise or lower across the entire application just to see detailed output from a single area.

Performance

Nova has been benchmarked against several popular C++ logging libraries, including Quill and spdlog, using:

  • multiple thread counts
  • fixed queue sizes
  • sustained throughput scenarios
  • guaranteed-delivery latency tests
  • both real file sinks and counting sinks to isolate I/O overhead

The benchmarks intentionally normalize queue sizing and backend threading models to avoid structurally advantaging any particular library configuration.

Results varied by workload, but several patterns consistently emerged:

  • Nova performed particularly well in guaranteed-delivery scenarios and bounded-memory configurations
  • Nova's synchronized sink significantly outperformed comparable synchronous configurations from other libraries
  • Nova's async backend (using a no-I/O counting sink) demonstrated competitive throughput across thread counts while maintaining zero per-record heap allocation throughout
  • Quill achieved extremely high front-end enqueue throughput, but with substantial drop rates under sustained overload conditions
  • spdlog async showed performance degradation under heavy multi-threaded workloads

While Nova does not always achieve the highest theoretical front-end enqueue rate, it performed extremely competitively across a broad range of realistic workloads, especially where deterministic behavior and bounded memory usage are important.

Full benchmark methodology and raw benchmark data are available in the repository.

Design Philosophy

Principle Description
Domain-based routing Logging should reflect application structure rather than forcing subsystems into global severity categories
Deterministic behavior No heap allocation, exceptions, or RTTI by design - heap usage is explicitly documented where it exists (such as in a small number of convenience sinks) and avoided everywhere else across Nova core, Nova Extras, and Flare
Explicit tradeoffs Buffer and queue sizes, synchronous vs asynchronous delivery, blocking, and fan-out behavior should be visible and configurable
Compile-time configuration Logging configuration should be resolved at compile time whenever practical
Production-oriented design Optimize for sustained, realistic workloads and operational predictability
Modern C++ Use modern language features without introducing unnecessary complexity or heavy dependencies
Performance-conscious design Logging overhead should remain predictable and low, especially in latency-sensitive and multi-threaded systems

Current Status & Feedback

The initial release is now available at the repository linked above. I am still actively working on improving the library with additional features such as:

  • additional sinks/backends
  • packaging and integration polish
  • binary logging

I would appreciate feedback on any aspects of Nova (e.g. integration experience, cross-platform/compiler issues, feature requests). If you try Nova in a project, I’d love to hear how it performs and where it can improve.

Thanks for reading.