LoggerPro 2.0 - Modern Async Logging Framework for Delphi with Builder Pattern
TL;DR: LoggerPro 2.0 introduces a powerful Builder pattern API for Delphi logging. Use
LoggerProBuilder.WriteToFile.Done.WriteToConsole.Done.Buildto configure appenders fluently. New features include contextual logging withWithProperty(), exception logging with stack traces, Windows Event Log support, and explicitShutdown()for resource cleanup. Looking for LoggerPro 1.x? See the legacy guide.
What is LoggerPro 2.0?
LoggerPro 2.0 is the latest major release of the most comprehensive async logging framework for Delphi. This version introduces a Builder pattern API inspired by Serilog, making logger configuration more intuitive and maintainable.
Looking for LoggerPro 1.x documentation? Click here for the legacy guide
Key Features in 2.0
| Feature | Description |
|---|---|
| Builder Pattern API | Fluent Serilog-style configuration with WriteTo* methods |
| 20+ Built-in Appenders | File, Console, HTTP, ElasticSearch, Syslog, Database, and more |
| Contextual Logging | WithProperty(), WithDefaultTag(), WithDefaultContext() |
| Exception Logging | LogException() with pluggable stack trace formatter |
| Minimum Level Gate | Global filtering before message queuing (zero overhead) |
| Windows Event Log | Native support for apps and Windows Services |
| Explicit Shutdown | Shutdown() method for deterministic cleanup |
| Improved Thread Safety | Safe logging even during destruction |
| FATAL Log Level | New severity level for critical failures |
Quick Start with Builder API
uses
LoggerPro,
LoggerPro.Builder;
var
Log: ILogWriter;
begin
Log := LoggerProBuilder
.WriteToFile
.WithLogsFolder('logs')
.WithMaxBackupFiles(5)
.WithMaxFileSizeInKB(10000)
.Done
.WriteToConsole
.Done
.Build;
Log.Info('Application started', 'main');
Log.Debug('Debug info', 'debug');
// Contextual logging
Log.WithProperty('user_id', 42)
.WithProperty('session', 'abc123')
.Info('User logged in', 'auth');
// Exception logging
try
// ... code ...
except
on E: Exception do
Log.LogException(E, 'Operation failed', 'error');
end;
// Explicit shutdown (optional but recommended)
Log.Shutdown;
end;
Builder Pattern: WriteTo* Methods
LoggerPro 2.0 uses a Serilog-inspired builder pattern. Each appender has a dedicated WriteTo* method:
Log := LoggerProBuilder
// File appender with configuration
.WriteToFile
.WithLogsFolder('logs')
.WithFileBaseName('myapp')
.WithMaxBackupFiles(10)
.WithMaxFileSizeInKB(5000)
.WithEncoding(TEncoding.UTF8)
.Done
// Console appender
.WriteToConsole
.WithRenderer(TLogItemRendererNoTag.Create)
.Done
// HTTP appender
.WriteToHTTP
.WithURL('https://logs.example.com/api/logs')
.WithTimeout(30)
.WithRetryCount(3)
.Done
// Generic appender
.WriteToAppender(TMyCustomAppender.Create)
// Global settings
.WithMinimumLevel(TLogType.Warning) // Only Warning+ logged
.WithDefaultTag('MYAPP')
.WithStackTraceFormatter(MyStackTraceFunc)
.Build;
Contextual Logging
LoggerPro 2.0 introduces powerful contextual logging features:
WithProperty (Ad-hoc Context)
// Single log with context
Log.WithProperty('order_id', 12345)
.WithProperty('amount', 99.99)
.Info('Order processed', 'orders');
// Output: [INFO] Order processed {order_id=12345, amount=99.99}
WithDefaultTag (Sub-logger)
var
OrderLog: ILogWriter;
begin
OrderLog := Log.WithDefaultTag('ORDERS');
OrderLog.Info('Processing started'); // tag = 'ORDERS'
OrderLog.Info('Item validated'); // tag = 'ORDERS'
OrderLog.Warn('Stock low'); // tag = 'ORDERS'
end;
WithDefaultContext (Persistent Context)
var
RequestLog: ILogWriter;
begin
RequestLog := Log.WithDefaultContext([
LogParam.S('request_id', 'req-123'),
LogParam.S('client_ip', '192.168.1.100')
]);
RequestLog.Info('Request received'); // includes request_id, client_ip
RequestLog.Info('Processing'); // includes request_id, client_ip
RequestLog.Info('Response sent'); // includes request_id, client_ip
end;
Exception Logging
LoggerPro 2.0 adds dedicated exception logging with optional stack trace support:
try
// Code that may raise exception
except
on E: Exception do
begin
Log.LogException(E); // Basic
Log.LogException(E, 'Database query failed'); // With message
Log.LogException(E, 'Query failed', 'db'); // With message and tag
end;
end;
Stack Trace Formatter
Integrate with JCL, madExcept, EurekaLog, or any stack trace library:
Log := LoggerProBuilder
.WithStackTraceFormatter(
function(E: Exception): string
begin
Result := JclLastExceptStackListToString; // JCL example
end)
.WriteToFile.Done
.Build;
Minimum Level Filtering
Filter messages globally before they’re queued (zero overhead for filtered messages):
Log := LoggerProBuilder
.WithMinimumLevel(TLogType.Warning) // Debug and Info filtered
.WriteToFile.Done
.Build;
Log.Debug('Not logged'); // Filtered - no TLogItem created
Log.Info('Not logged'); // Filtered - no TLogItem created
Log.Warn('Logged'); // OK
Log.Error('Logged'); // OK
Shutdown Method
LoggerPro 2.0 introduces explicit Shutdown() for deterministic cleanup:
procedure TMyApp.Finalize;
begin
Log.Shutdown; // Flush all pending logs, stop thread
Log := nil; // Release reference
end;
Key behaviors:
- Idempotent: Safe to call multiple times
- Flushes all pending messages
- Terminates logger thread
- After shutdown, log calls are silently ignored (Release) or Assert (Debug)
Backward Compatibility
LoggerPro 2.0 is fully backward compatible with 1.x code. The Builder pattern and new features are additions, not replacements.
Your existing code continues to work:
// This 1.x code still works perfectly in 2.0
uses LoggerPro, LoggerPro.FileAppender, LoggerPro.ConsoleAppender;
Log := BuildLogWriter([
TLoggerProFileAppender.Create(5, 1024, 'logs'),
TLoggerProConsoleAppender.Create
]);
Log.Info('Message', 'tag');
New 2.0 Builder alternative (recommended for new projects):
uses LoggerPro, LoggerPro.Builder;
Log := LoggerProBuilder
.WriteToFile
.WithLogsFolder('logs')
.WithMaxBackupFiles(5)
.WithMaxFileSizeInKB(1024)
.Done
.WriteToConsole.Done
.WithDefaultTag('tag')
.Build;
Log.Info('Message'); // Uses default tag
| Feature | Classic Style (still works) | Builder Style (new) |
|---|---|---|
| Create logger | BuildLogWriter([...]) |
LoggerProBuilder...Build |
| File appender | TLoggerProFileAppender.Create(...) |
.WriteToFile.With*().Done |
| Tag parameter | Explicit in each call | Optional with WithDefaultTag() |
| Shutdown | Automatic on destroy | Log.Shutdown (recommended) |
Note: While
BuildLogWriter()and direct appender creation continue to work, the Builder pattern is the recommended approach for new projects. It provides better discoverability, cleaner configuration, and access to new features likeWithMinimumLevel()andWithStackTraceFormatter().
Available Appenders
All appenders are available via Builder with fluent configuration:
File Appenders
| Builder Method | Description |
|---|---|
.WriteToFile |
Rolling file with size/count limits and tag-based filenames |
.WriteToJSONLFile |
JSON Lines format for log aggregation (ELK, Splunk) |
.WriteToTimeRotatingFile |
Time-based rotation (hourly, daily, etc.) |
Console & Debug Appenders
| Builder Method | Description |
|---|---|
.WriteToConsole |
Colored console output (Windows) |
.WriteToSimpleConsole |
Basic console (cross-platform, Linux/macOS) |
.WriteToOutputDebugString |
Windows OutputDebugString (IDE debug output) |
Network Appenders
| Builder Method | Description |
|---|---|
.WriteToHTTP |
HTTP/HTTPS REST endpoint with retry support |
.WriteToElasticSearch |
Direct ElasticSearch integration |
.WriteToUDPSyslog |
UDP Syslog (RFC 5424) |
VCL Appenders (Windows only)
| Builder Method | Description |
|---|---|
.WriteToVCLMemo(Memo1) |
TMemo component |
.WriteToVCLListBox(ListBox1) |
TListBox component |
.WriteToVCLListView(ListView1) |
TListView component |
Windows-Specific Appenders
| Builder Method | Description |
|---|---|
.WriteToWindowsEventLog |
Windows Event Log (regular applications) |
.WriteToWindowsEventLogForService(Self) |
Windows Event Log (Windows Services via TService) |
Database & Memory Appenders
| Builder Method | Description |
|---|---|
.WriteToFireDAC |
Database logging via FireDAC stored procedure |
.WriteToMemory |
In-memory ring buffer for testing/debugging |
Callback Appenders
| Builder Method | Description |
|---|---|
.WriteToCallback |
Custom callback receiving full TLogItem |
.WriteToSimpleCallback |
Custom callback receiving rendered message string |
Advanced
| Builder Method | Description |
|---|---|
.WriteToFilteredAppender(appender) |
Wrap any appender with a custom filter function |
.WriteToAppender(appender) |
Add any pre-configured ILogAppender instance |
Example: Multiple Appenders
Log := LoggerProBuilder
// File with JSON Lines format
.WriteToJSONLFile
.WithLogsFolder('logs')
.WithMaxBackupFiles(10)
.Done
// ElasticSearch
.WriteToElasticSearch
.WithHost('localhost')
.WithPort(9200)
.WithIndex('myapp-logs')
.Done
// Syslog
.WriteToUDPSyslog
.WithHost('syslog.example.com')
.WithApplication('MyApp')
.Done
// Console for development
.WriteToConsole.Done
.Build;
Using Appenders Without Builder Support
Some specialized appenders (Redis, Email, NSQ, etc.) can be added via .WriteToAppender():
uses LoggerPro.RedisAppender, LoggerPro.EmailAppender;
Log := LoggerProBuilder
.WriteToAppender(TLoggerProRedisAppender.Create('localhost', 6379))
.WriteToAppender(TLoggerProEmailAppender.Create(...))
.Build;
Windows Event Log Integration
LoggerPro 2.0 supports Windows Event Log for both regular applications and Windows Services:
Regular Applications
Log := LoggerProBuilder
.WriteToWindowsEventLog
.WithSourceName('MyApplication')
.WithLogLevel(TLogType.Warning) // Only warnings and errors
.Done
.Build;
Windows Services
For Windows Services, use the TService instance for proper integration:
// In your TService descendant
procedure TMyService.ServiceCreate(Sender: TObject);
begin
FLog := LoggerProBuilder
.WriteToWindowsEventLogForService(Self) // Pass the TService instance
.Done
.WriteToFile
.WithLogsFolder('C:\ProgramData\MyService\Logs')
.Done
.Build;
end;
This uses TService.LogMessage internally, ensuring proper Windows Service event logging.
Log Levels
Log.Debug('Detailed debug information'); // TLogType.Debug
Log.Info('General information'); // TLogType.Info
Log.Warn('Warning conditions'); // TLogType.Warning
Log.Error('Error conditions'); // TLogType.Error
Log.Fatal('Critical failures'); // TLogType.Fatal (new in 2.0)
Delphi Version Compatibility
| Delphi Version | Supported |
|---|---|
| Delphi 13 Florence | Yes |
| Delphi 12 Athens | Yes |
| Delphi 11 Alexandria | Yes |
| Delphi 10.4 Sydney | Yes |
| Delphi 10.3 Rio | Yes |
| Delphi 10.2 Tokyo | Yes (+ Linux) |
| Delphi 10.1 Berlin | Yes |
| Delphi 10 Seattle | Yes |
Installation
Option 1: Download Release (Recommended)
Download the latest stable release from GitHub:
- Extract the ZIP to a folder (e.g.,
C:\Libraries\LoggerPro) - In Delphi IDE, go to Tools > Options > Language > Delphi > Library
- Add this path to Library Path for your target platform:
C:\Libraries\LoggerPro(main units)C:\Libraries\LoggerPro\contrib(optional, only needed for Redis and Email appenders)
- Add
uses LoggerPro, LoggerPro.Builder;to your code
All releases are available at github.com/danieleteti/loggerpro/releases
Option 2: Delphinus Package Manager
Search for “LoggerPro” in the Delphinus package manager and install.
Option 3: Clone Repository (Contributors Only)
Clone the repository only if you want to test unreleased features or contribute to the project:
git clone https://github.com/danieleteti/loggerpro.git
Then add the root folder and contrib subfolder to your Library Path as described above.
Note: The
masterbranch may contain unstable code. For production use, always prefer Option 1.
Related Projects
| Project | Description |
|---|---|
| DMVCFramework | REST API framework with built-in LoggerPro integration |
| DelphiRedisClient | Redis client for TLoggerProRedisAppender |
Links
- GitHub: github.com/danieleteti/loggerpro
- Legacy 1.x Guide: LoggerPro 1.x Documentation
- Support: Facebook Group
FAQ
What is new in LoggerPro 2.0?
LoggerPro 2.0 introduces: Builder pattern API, contextual logging with WithProperty(), exception logging with stack traces, minimum level filtering, explicit Shutdown() method, and improved thread safety.
Is LoggerPro 2.0 backward compatible?
Yes, LoggerPro 2.0 is fully backward compatible. Your existing 1.x code using BuildLogWriter() continues to work without any changes. The new Builder pattern API is an addition, not a replacement. You can adopt new features incrementally.
Do I need to migrate my existing code?
No migration is required. Your 1.x code works as-is in 2.0. When you’re ready, you can optionally adopt the new Builder API for new code or during refactoring.
How do I add context to my logs?
Use Log.WithProperty('key', value).Info('message') for ad-hoc context, or Log.WithDefaultContext([...]) for persistent context across multiple calls.
Should I call Shutdown()?
Yes, call Log.Shutdown in your application’s finalization to ensure all pending logs are written before exit. It’s safe to call multiple times.
What is the difference between WithProperty and WithDefaultContext?
WithProperty() adds context to a single log call (fluent, chainable). WithDefaultContext() creates a sub-logger that automatically includes the context in all subsequent log calls.
How do I log to multiple destinations?
Use the Builder to add multiple appenders:
Log := LoggerProBuilder
.WriteToFile.Done
.WriteToConsole.Done
.WriteToAppender(TLoggerProRedisAppender.Create(...))
.Build;
Does LoggerPro support async logging?
Yes, all LoggerPro appenders are asynchronous by default. Logging calls return immediately while a background thread processes the log queue.
Is LoggerPro thread-safe?
Yes, LoggerPro is fully thread-safe. Multiple threads can log simultaneously without synchronization. The internal queue uses lock-free algorithms for high performance.
What Delphi versions are supported?
LoggerPro 2.0 supports Delphi 10 Seattle through Delphi 13 Florence. Linux support is available from Delphi 10.2 Tokyo.
How do I filter logs by level?
Use WithMinimumLevel() in the Builder to set a global filter. Messages below the minimum level are discarded before queuing (zero overhead).
Can I use LoggerPro in a DLL?
Yes, but call Log.Shutdown before unloading the DLL to ensure the logger thread terminates cleanly. This is especially important for ISAPI DLLs.
How do I log to Windows Event Log?
Use .WriteToWindowsEventLog for regular applications or .WriteToWindowsEventLogForService(Self) for Windows Services:
// Regular application
Log := LoggerProBuilder
.WriteToWindowsEventLog
.WithSourceName('MyApp')
.Done
.Build;
// Windows Service
Log := LoggerProBuilder
.WriteToWindowsEventLogForService(Self)
.Done
.Build;
What appenders have native Builder support?
All major appenders: File, JSONL File, Time Rotating File, Console, Simple Console, OutputDebugString, HTTP, ElasticSearch, UDP Syslog, FireDAC (database), Memory, Callback, VCL (Memo, ListBox, ListView), and Windows Event Log. Other appenders (Redis, Email, NSQ) can be added via .WriteToAppender().
LoggerPro 2.0 - Modern async logging for Delphi with Builder pattern. Contextual logging. Exception handling. 20+ appenders. Cross-platform. Open-source.
Comments
comments powered by Disqus