Become a member!

LoggerPro 2.0 - Modern Async Logging Framework for Delphi with Builder Pattern

🌐
This article is also available in other languages:
🇮🇹 Italiano  •  🇪🇸 Español

TL;DR: LoggerPro 2.0 introduces a powerful Builder pattern API for Delphi logging. Use LoggerProBuilder.WriteToFile.Done.WriteToConsole.Done.Build to configure appenders fluently. New features include contextual logging with WithProperty(), exception logging with stack traces, Windows Event Log support, and explicit Shutdown() for resource cleanup. Looking for LoggerPro 1.x? See the legacy guide.

LoggerPro 2.0 Logo

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 like WithMinimumLevel() and WithStackTraceFormatter().

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

Download the latest stable release from GitHub:

Download LoggerPro 2.0.0

  1. Extract the ZIP to a folder (e.g., C:\Libraries\LoggerPro)
  2. In Delphi IDE, go to Tools > Options > Language > Delphi > Library
  3. 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)
  4. 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 master branch may contain unstable code. For production use, always prefer Option 1.


Project Description
DMVCFramework REST API framework with built-in LoggerPro integration
DelphiRedisClient Redis client for TLoggerProRedisAppender

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