High-Performance C++ Logging Library
Ultra-fast, flexible, and feature-rich logging for modern C++ applications
- Performance
- Key Features
- Quick Start
- Architecture
- Advanced Usage
- Logging Macros
- Supported Types
- Configuration Options
- Extending ALog
- Requirements
- License
| Metric | Value |
|---|---|
| Throughput | 85 ns per log record |
| Records per ms | ~11,700 |
| Async mode | Non-blocking with optional sorting |
- 85 nanoseconds per log record — one of the fastest C++ loggers available
- Asynchronous mode with optional chronological sorting
- Zero external dependencies for maximum performance
Every log record automatically captures:
- Timestamps (elapsed time from application start)
- Severity level (Verbose, Debug, Info, Warning, Error, Fatal)
- Source location (file, function, line)
- Module name, Thread ID, Thread name
LOGD << "Simple logging";
LOGE_IF(errorFlag) << "Conditional error!";
LOGI << "Container: " << std::vector{1, 2, 3};
LOGW << "Error!" << THROW; // Log and throw exception- Sinks: Console (with color output), File, FileRotated, Baical, Pipeline, Custom
- Filters: By severity, module, file, substring, or custom logic
- Formatters: Default (full, with optional date & time) or Minimal (text-only)
- Converters: Encoding, compression, encryption
Option 1: FetchContent (Recommended)
include(FetchContent)
FetchContent_Declare(alog
GIT_REPOSITORY https://github.com/ihor-drachuk/alog.git
GIT_TAG master
)
FetchContent_MakeAvailable(alog)
target_link_libraries(YourProject PRIVATE alog)Option 2: Submodule
add_subdirectory(3rd-party/alog)
target_link_libraries(YourProject PRIVATE alog)#include <alog/logger.h>
int main() {
SIMPLE_SETUP_ALOG; // One-line setup
LOGMD << "Debug message";
LOGMI << "Info message";
LOGMW << "Warning message";
LOGME << "Error message";
return 0;
}Output:
[260328_120000] [ 0.000] T#0 [Debug] [::main:5] Debug message
[260328_120000] [ 0.000] T#0 [Info ] [::main:6] Info message
[260328_120000] [ 0.000] T#0 [Warn ] [::main:7] Warning message
[260328_120000] [ 0.000] T#0 [Error] [::main:8] Error message
#include <alog/logger.h>
DEFINE_ALOGGER_MODULE_NS(NetworkManager);
void connect() {
LOGD << "Connecting to server...";
LOGI << "Connection established";
}Output:
[260328_120000] [ 0.001] T#0 [Debug] [NetworkManager ] [::connect:5] Connecting to server...
[260328_120000] [ 0.002] T#0 [Info ] [NetworkManager ] [::connect:6] Connection established
ALog Pipeline
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌───────────┐ ┌────────┐ ┌───────────┐ ┌─────────────┐ ┌───────────┐ ┌───────────┐ │
│ │ LOG Macro │──►│ Record │──►│ Formatter │──►│ Converter(s)│──►│ Filter(s) │──►│ Sinks │ │
│ └───────────┘ └────────┘ └─────┬─────┘ └──────┬──────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Default │ │ Attention │ │ Severity │ │ Console │ │
│ │ Minimal │ └───────────┘ │ Module │ │ File │ │
│ └───────────┘ │ File │ │FileRotated│ │
│ │ ... │ │ Pipeline │ │
│ └───────────┘ │ ... │ │
│ └───────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
| Component | Purpose | Examples |
|---|---|---|
| Sinks | Output destinations | Console (colored), File, FileRotated, Baical, Pipeline |
| Filters | Control which logs pass | Severity, Module, File, Substring, Chain, Custom |
| Formatters | Format log output | Default (full info, date & time), Minimal (text only) |
| Converters | Post-process output | Encoding, line endings, compression |
#include <alog/all.h>
DEFINE_ALOGGER_MODULE_NS(Main);
int main() {
ALog::DefaultLogger logger;
logger->setMode(ALog::Logger::LoggerMode::AsynchronousSort);
logger->pipeline().sinks().add(
std::make_shared<ALog::Sinks::File>("app.log")
);
logger.markReady();
LOGD << "This goes to both console and file";
return 0;
}// Only log Warning and above
logger->pipeline().filters().set(
std::make_shared<ALog::Filters::Severity>(ALog::Severity::Warning)
);// Only pass logs containing "network" (case-insensitive)
logger->pipeline().filters().set(
std::make_shared<ALog::Filters::Substring>("network", true, false)
);auto filters = ALog::Filters::Chain::create({
// Always pass Warning+
std::make_shared<ALog::Filters::Severity>(
ALog::Severity::Warning,
ALog::IFilter::PassOrUndefined
),
// Exclude noisy module
std::make_shared<ALog::Filters::Module>(
"NoisyModule", false,
ALog::IFilter::RejectOrUndefined
),
// Default: reject
std::make_shared<ALog::Filters::Always>(false)
});
logger->pipeline().filters().set(filters);// Warnings+ → stderr, others → stdout
auto pipelineStdout = std::make_shared<ALog::Sinks::Pipeline>();
pipelineStdout->filters().set(
std::make_shared<ALog::Filters::Severity>(
ALog::Severity::Warning, ALog::IFilter::Default, ALog::Less
)
);
pipelineStdout->sinks().set(
std::make_shared<ALog::Sinks::Console>(ALog::Sinks::Console::Stream::StdOut)
);
auto pipelineStderr = std::make_shared<ALog::Sinks::Pipeline>();
pipelineStderr->filters().set(
std::make_shared<ALog::Filters::Severity>(
ALog::Severity::Warning, ALog::IFilter::Default, ALog::GreaterEqual
)
);
pipelineStderr->sinks().set(
std::make_shared<ALog::Sinks::Console>(ALog::Sinks::Console::Stream::StdErr)
);
logger->pipeline().sinks().set({pipelineStdout, pipelineStderr});| Macro | Description |
|---|---|
LOGV / LOGMV |
Verbose |
LOGD / LOGMD |
Debug |
LOGI / LOGMI |
Info |
LOGW / LOGMW |
Warning |
LOGE / LOGME |
Error |
LOGF / LOGMF |
Fatal |
Note: Use
LOG*when module is defined viaDEFINE_ALOGGER_MODULE_NS, useLOGM*otherwise.
LOGD_IF(condition) << "Only logged if condition is true";
LOGE_IF(error) << "Error occurred!";| Flag | Description |
|---|---|
FLUSH |
Force immediate flush |
THROW |
Log message and throw exception |
ABORT |
Log message and call std::abort() |
BUFFER(ptr, size) |
Log raw binary buffer |
SEPARATORS / NSEPS |
Enable/disable auto-separators |
AUTO_QUOTES / NO_AUTO_QUOTES |
Enable/disable auto-quoting |
LOGE << "Critical failure!" << ABORT;
LOGD << "Buffer content: " << BUFFER(data, size);LOG_ASSERT(condition) << "Assertion failed info";
LOG_ASSERT_D(condition) << "Debug-only assertion";
LOG_ASSERT_THROW(condition) << "Throws on failure";ALog automatically formats common types:
- STL Containers:
vector,map,set,list,deque, etc. (requires<alog/containers/all.h>) - Smart Pointers:
unique_ptr,shared_ptr,weak_ptr - Chrono:
std::chrono::duration,std::chrono::time_point - Optionals:
std::optional,std::expected - Qt Types (when Qt available):
QString,QPoint,QJsonObject,QFuture, etc. - Raw Buffers: Via
BUFFER(ptr, size)flag - Custom Types: Implement
operator<<
#include <alog/containers/all.h> // Required for container support
LOGI << std::vector{1, 2, 3};
// Output: {Container; Size: 3; Data = 1, 2, 3}
LOGI << std::map<std::string, int>{{"a", 1}, {"b", 2}};
// Output: {Container; Size: 2; Data = ("a", 1), ("b", 2)}| Mode | Description |
|---|---|
Synchronous |
Blocking, immediate output (best for debugging) |
Asynchronous |
Non-blocking, background processing |
AsynchronousSort |
Non-blocking with chronological sorting |
logger->setMode(ALog::Logger::LoggerMode::AsynchronousSort);
logger->setAutoflush(false); // Batch writes for performanceThe Default formatter supports configurable flags:
| Flag | Default | Description |
|---|---|---|
DateTime |
ON | Include absolute date & time ([260328_120000]) |
LocalTimestamp |
ON | Include elapsed time from start ([ 0.014]) |
// Elapsed time only, no date & time
logger->pipeline().formatter().set(
std::make_shared<ALog::Formatters::Default>(ALog::Formatters::Default::Flag::LocalTimestamp)
);Console sinks support colored output based on severity level:
auto sink = std::make_shared<ALog::Sinks::Console>(
ALog::Sinks::Console::Stream::StdOut,
ALog::Sinks::Console::ColorMode::Auto // Auto (default), Force, Disable
);| Option | Default | Description |
|---|---|---|
ALOG_ENABLE_TESTS |
OFF | Build test suite |
ALOG_ENABLE_BENCHMARK |
OFF | Build benchmarks |
ALOG_CXX_STANDARD |
17 | C++ standard (17, 20, 23) |
ALOG_ENABLE_DEF_SEPARATORS |
OFF | Auto-separators between values |
ALOG_ENABLE_DEF_AUTO_QUOTES |
ON | Auto-quote strings |
class MySink : public ALog::ISink {
public:
void write(const ALog::Buffer& buffer, const ALog::Record& record) override {
// Send to your destination
}
void flush() override { }
};
logger->pipeline().sinks().add(std::make_shared<MySink>());class MyFilter : public ALog::IFilter {
protected:
ALog::I::optional_bool canPassImpl(const ALog::Record& record) const override {
// Return true/false/undefined
return record.severity >= ALog::Severity::Warning;
}
};- Compiler: C++17 or later (GCC, Clang, MSVC, Apple Clang)
- Build System: CMake 3.16+
- Platforms: Windows, Linux, macOS
- Dependencies: None (Qt integration optional)
MIT License — see License.txt for details.
Copyright (c) 2018-2026 Ihor Drachuk
Ihor Drachuk — ihor-drachuk-libs@pm.me