Quill: High-Performance Asynchronous C++ Logging Library

Odysseas - Aug 28 - - Dev Community

Introduction

Efficient logging is crucial for application performance and debugging. Logging is an essential part of any software system, but it can often become a performance bottleneck, especially in low-latency applications. Quill addresses this challenge by offering an asynchronous, cross-platform logging solution that minimizes the impact on your application's hot path.

Performance Focus

Quill is a feature-rich logging library built with performance in mind. Its design aims to provide faster logging capabilities compared to many traditional logging libraries.

Thread-Local Lock-Free Ring Buffer:

Each thread is equipped with its own lock-free ring buffer, facilitating efficient, contention-free logging. This architecture eliminates inter-thread synchronization for log writes, drastically reducing overhead.

Compile-Time Metadata Generation:

Quill generates essential log metadata—such as file name, line number, and format string—at compile time. By shifting this workload to compile time, runtime performance is significantly enhanced.

Binary Log Message Serialization:

Instead of formatting log messages on-the-fly, Quill serializes argument data in binary form directly into the ring buffer. This approach minimizes processing on the critical path of application threads.

Asynchronous Backend Processing:

A dedicated backend thread retrieves binary data from the ring buffers, formats the log messages, and outputs them to the designated sinks (e.g., files, console).

This architecture enables Quill to deliver high performance by reducing work in application threads, capitalizing on compile-time optimizations, and leveraging asynchronous processing.

Example Usage

Here's a basic example of how to use Quill in your C++ application:

#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/sinks/ConsoleSink.h"
#include <string_view>

int main()
{
  quill::Backend::start();

  quill::Logger* logger = quill::Frontend::create_or_get_logger(
    "root", quill::Frontend::create_or_get_sink<quill::ConsoleSink>("sink_id_1"));

  LOG_INFO(logger, "Hello from {}!", std::string_view{"Quill"});
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can try it on Compiler Explorer

Get Involved

To dive deeper into Quill or contribute to the project, visit the GitHub repository or the Documentation page.

.
Terabox Video Player