Become a member!

LoggerPro 2.0 - Framework di Logging Asincrono Moderno per Delphi con Builder Pattern

🌐
Questo articolo è disponibile anche in altre lingue:
🇬🇧 English  •  🇪🇸 Español

TL;DR: LoggerPro 2.0 introduce una potente API Builder pattern per il logging Delphi. Usa LoggerProBuilder.WriteToFile.Done.WriteToConsole.Done.Build per configurare gli appender in modo fluent. Le nuove funzionalità includono logging contestuale con WithProperty(), logging delle eccezioni con stack trace, supporto Windows Event Log e Shutdown() esplicito per il cleanup delle risorse. Cerchi LoggerPro 1.x? Vedi la guida legacy.

Logo LoggerPro 2.0

Cos’è LoggerPro 2.0?

LoggerPro 2.0 è l’ultima major release del framework di logging asincrono più completo per Delphi. Questa versione introduce un’API Builder pattern ispirata a Serilog, rendendo la configurazione del logger più intuitiva e mantenibile.

Cerchi la documentazione di LoggerPro 1.x? Clicca qui per la guida legacy

Funzionalità Principali nella 2.0

Funzionalità Descrizione
API Builder Pattern Configurazione fluent stile Serilog con metodi WriteTo*
20+ Appender Integrati File, Console, HTTP, ElasticSearch, Syslog, Database e altro
Logging Contestuale WithProperty(), WithDefaultTag(), WithDefaultContext()
Logging Eccezioni LogException() con formatter di stack trace pluggabile
Gate Livello Minimo Filtro globale prima dell’accodamento messaggi (zero overhead)
Windows Event Log Supporto nativo per app e Windows Services
Shutdown Esplicito Metodo Shutdown() per cleanup deterministico
Thread Safety Migliorato Logging sicuro anche durante la distruzione
Livello Log FATAL Nuovo livello di severità per fallimenti critici

Quick Start con l’API Builder

uses
  LoggerPro,
  LoggerPro.Builder;

var
  Log: ILogWriter;
begin
  Log := LoggerProBuilder
    .WriteToFile
      .WithLogsFolder('logs')
      .WithMaxBackupFiles(5)
      .WithMaxFileSizeInKB(10000)
      .Done
    .WriteToConsole
      .Done
    .Build;

  Log.Info('Applicazione avviata', 'main');
  Log.Debug('Info di debug', 'debug');

  // Logging contestuale
  Log.WithProperty('user_id', 42)
     .WithProperty('session', 'abc123')
     .Info('Utente loggato', 'auth');

  // Logging eccezioni
  try
    // ... codice ...
  except
    on E: Exception do
      Log.LogException(E, 'Operazione fallita', 'error');
  end;

  // Shutdown esplicito (opzionale ma raccomandato)
  Log.Shutdown;
end;

Builder Pattern: Metodi WriteTo*

LoggerPro 2.0 usa un builder pattern ispirato a Serilog. Ogni appender ha un metodo WriteTo* dedicato:

Log := LoggerProBuilder
  // Appender file con configurazione
  .WriteToFile
    .WithLogsFolder('logs')
    .WithFileBaseName('myapp')
    .WithMaxBackupFiles(10)
    .WithMaxFileSizeInKB(5000)
    .WithEncoding(TEncoding.UTF8)
    .Done

  // Appender console
  .WriteToConsole
    .WithRenderer(TLogItemRendererNoTag.Create)
    .Done

  // Appender HTTP
  .WriteToHTTP
    .WithURL('https://logs.example.com/api/logs')
    .WithTimeout(30)
    .WithRetryCount(3)
    .Done

  // Appender generico
  .WriteToAppender(TMyCustomAppender.Create)

  // Impostazioni globali
  .WithMinimumLevel(TLogType.Warning)  // Solo Warning+ loggati
  .WithDefaultTag('MYAPP')
  .WithStackTraceFormatter(MyStackTraceFunc)

  .Build;

Logging Contestuale

LoggerPro 2.0 introduce potenti funzionalità di logging contestuale:

WithProperty (Contesto Ad-hoc)

// Singolo log con contesto
Log.WithProperty('order_id', 12345)
   .WithProperty('amount', 99.99)
   .Info('Ordine processato', 'orders');

// Output: [INFO] Ordine processato {order_id=12345, amount=99.99}

WithDefaultTag (Sub-logger)

var
  OrderLog: ILogWriter;
begin
  OrderLog := Log.WithDefaultTag('ORDERS');
  OrderLog.Info('Elaborazione avviata');   // tag = 'ORDERS'
  OrderLog.Info('Articolo validato');      // tag = 'ORDERS'
  OrderLog.Warn('Stock basso');            // tag = 'ORDERS'
end;

WithDefaultContext (Contesto Persistente)

var
  RequestLog: ILogWriter;
begin
  RequestLog := Log.WithDefaultContext([
    LogParam.S('request_id', 'req-123'),
    LogParam.S('client_ip', '192.168.1.100')
  ]);

  RequestLog.Info('Richiesta ricevuta');    // include request_id, client_ip
  RequestLog.Info('Elaborazione');          // include request_id, client_ip
  RequestLog.Info('Risposta inviata');      // include request_id, client_ip
end;

Logging delle Eccezioni

LoggerPro 2.0 aggiunge logging dedicato delle eccezioni con supporto opzionale per stack trace:

try
  // Codice che può sollevare eccezioni
except
  on E: Exception do
  begin
    Log.LogException(E);                           // Base
    Log.LogException(E, 'Query database fallita'); // Con messaggio
    Log.LogException(E, 'Query fallita', 'db');    // Con messaggio e tag
  end;
end;

Formatter Stack Trace

Integra con JCL, madExcept, EurekaLog o qualsiasi libreria di stack trace:

Log := LoggerProBuilder
  .WithStackTraceFormatter(
    function(E: Exception): string
    begin
      Result := JclLastExceptStackListToString;  // esempio JCL
    end)
  .WriteToFile.Done
  .Build;

Filtro Livello Minimo

Filtra i messaggi globalmente prima che vengano accodati (zero overhead per i messaggi filtrati):

Log := LoggerProBuilder
  .WithMinimumLevel(TLogType.Warning)  // Debug e Info filtrati
  .WriteToFile.Done
  .Build;

Log.Debug('Non loggato');   // Filtrato - nessun TLogItem creato
Log.Info('Non loggato');    // Filtrato - nessun TLogItem creato
Log.Warn('Loggato');        // OK
Log.Error('Loggato');       // OK

Metodo Shutdown

LoggerPro 2.0 introduce Shutdown() esplicito per cleanup deterministico:

procedure TMyApp.Finalize;
begin
  Log.Shutdown;  // Flush di tutti i log pendenti, stop del thread
  Log := nil;    // Rilascia il riferimento
end;

Comportamenti chiave:

  • Idempotente: Sicuro da chiamare più volte
  • Esegue il flush di tutti i messaggi pendenti
  • Termina il thread del logger
  • Dopo lo shutdown, le chiamate di log sono ignorate silenziosamente (Release) o Assert (Debug)

Retrocompatibilità

LoggerPro 2.0 è completamente retrocompatibile con il codice 1.x. Il Builder pattern e le nuove funzionalità sono aggiunte, non sostituzioni.

Il tuo codice esistente continua a funzionare:

// Questo codice 1.x funziona perfettamente nella 2.0
uses LoggerPro, LoggerPro.FileAppender, LoggerPro.ConsoleAppender;

Log := BuildLogWriter([
  TLoggerProFileAppender.Create(5, 1024, 'logs'),
  TLoggerProConsoleAppender.Create
]);
Log.Info('Messaggio', 'tag');

Nuova alternativa Builder 2.0 (raccomandata per nuovi progetti):

uses LoggerPro, LoggerPro.Builder;

Log := LoggerProBuilder
  .WriteToFile
    .WithLogsFolder('logs')
    .WithMaxBackupFiles(5)
    .WithMaxFileSizeInKB(1024)
    .Done
  .WriteToConsole.Done
  .WithDefaultTag('tag')
  .Build;

Log.Info('Messaggio');  // Usa il tag di default
Funzionalità Stile Classico (funziona ancora) Stile Builder (nuovo)
Crea logger BuildLogWriter([...]) LoggerProBuilder...Build
Appender file TLoggerProFileAppender.Create(...) .WriteToFile.With*().Done
Parametro tag Esplicito in ogni chiamata Opzionale con WithDefaultTag()
Shutdown Automatico alla distruzione Log.Shutdown (raccomandato)

Nota: Mentre BuildLogWriter() e la creazione diretta degli appender continuano a funzionare, il Builder pattern è l’approccio raccomandato per i nuovi progetti. Fornisce migliore discoverability, configurazione più pulita e accesso alle nuove funzionalità come WithMinimumLevel() e WithStackTraceFormatter().

Appender Disponibili

Tutti gli appender sono disponibili via Builder con configurazione fluent:

Appender File

Metodo Builder Descrizione
.WriteToFile File rolling con limiti di dimensione/numero e nomi file basati su tag
.WriteToJSONLFile Formato JSON Lines per aggregazione log (ELK, Splunk)
.WriteToTimeRotatingFile Rotazione basata sul tempo (oraria, giornaliera, ecc.)

Appender Console & Debug

Metodo Builder Descrizione
.WriteToConsole Output console colorato (Windows)
.WriteToSimpleConsole Console base (cross-platform, Linux/macOS)
.WriteToOutputDebugString Windows OutputDebugString (output debug IDE)

Appender di Rete

Metodo Builder Descrizione
.WriteToHTTP Endpoint HTTP/HTTPS REST con supporto retry
.WriteToElasticSearch Integrazione diretta ElasticSearch
.WriteToUDPSyslog UDP Syslog (RFC 5424)

Appender VCL (Solo Windows)

Metodo Builder Descrizione
.WriteToVCLMemo(Memo1) Componente TMemo
.WriteToVCLListBox(ListBox1) Componente TListBox
.WriteToVCLListView(ListView1) Componente TListView

Appender Specifici Windows

Metodo Builder Descrizione
.WriteToWindowsEventLog Windows Event Log (applicazioni normali)
.WriteToWindowsEventLogForService(Self) Windows Event Log (Windows Services via TService)

Appender Database & Memoria

Metodo Builder Descrizione
.WriteToFireDAC Logging su database via stored procedure FireDAC
.WriteToMemory Ring buffer in memoria per test/debug

Appender Callback

Metodo Builder Descrizione
.WriteToCallback Callback custom che riceve il TLogItem completo
.WriteToSimpleCallback Callback custom che riceve la stringa del messaggio renderizzato

Avanzati

Metodo Builder Descrizione
.WriteToFilteredAppender(appender) Wrappa qualsiasi appender con una funzione filtro custom
.WriteToAppender(appender) Aggiungi qualsiasi istanza ILogAppender pre-configurata

Esempio: Appender Multipli

Log := LoggerProBuilder
  // File con formato JSON Lines
  .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 per sviluppo
  .WriteToConsole.Done
  .Build;

Usare Appender Senza Supporto Builder

Alcuni appender specializzati (Redis, Email, NSQ, ecc.) possono essere aggiunti via .WriteToAppender():

uses LoggerPro.RedisAppender, LoggerPro.EmailAppender;

Log := LoggerProBuilder
  .WriteToAppender(TLoggerProRedisAppender.Create('localhost', 6379))
  .WriteToAppender(TLoggerProEmailAppender.Create(...))
  .Build;

Integrazione Windows Event Log

LoggerPro 2.0 supporta Windows Event Log sia per applicazioni normali che per Windows Services:

Applicazioni Normali

Log := LoggerProBuilder
  .WriteToWindowsEventLog
    .WithSourceName('MyApplication')
    .WithLogLevel(TLogType.Warning)  // Solo warning e errori
    .Done
  .Build;

Windows Services

Per Windows Services, usa l’istanza TService per una corretta integrazione:

// Nel tuo discendente di TService
procedure TMyService.ServiceCreate(Sender: TObject);
begin
  FLog := LoggerProBuilder
    .WriteToWindowsEventLogForService(Self)  // Passa l'istanza TService
      .Done
    .WriteToFile
      .WithLogsFolder('C:\ProgramData\MyService\Logs')
      .Done
    .Build;
end;

Questo usa internamente TService.LogMessage, assicurando un corretto logging eventi per Windows Service.

Livelli di Log

Log.Debug('Informazioni di debug dettagliate');  // TLogType.Debug
Log.Info('Informazioni generali');               // TLogType.Info
Log.Warn('Condizioni di warning');               // TLogType.Warning
Log.Error('Condizioni di errore');               // TLogType.Error
Log.Fatal('Fallimenti critici');                 // TLogType.Fatal (nuovo nella 2.0)

Compatibilità Versioni Delphi

Versione Delphi Supportata
Delphi 13 Florence
Delphi 12 Athens
Delphi 11 Alexandria
Delphi 10.4 Sydney
Delphi 10.3 Rio
Delphi 10.2 Tokyo Sì (+ Linux)
Delphi 10.1 Berlin
Delphi 10 Seattle

Installazione

Opzione 1: Scarica la Release (Raccomandata)

Scarica l’ultima release stabile da GitHub:

Scarica LoggerPro 2.0.0

  1. Estrai lo ZIP in una cartella (es. C:\Libraries\LoggerPro)
  2. Nell’IDE Delphi, vai su Tools > Options > Language > Delphi > Library
  3. Aggiungi questo percorso al Library Path per la tua piattaforma target:
    • C:\Libraries\LoggerPro (unit principali)
    • C:\Libraries\LoggerPro\contrib (opzionale, necessario solo per appender Redis e Email)
  4. Aggiungi uses LoggerPro, LoggerPro.Builder; al tuo codice

Tutte le release sono disponibili su github.com/danieleteti/loggerpro/releases

Opzione 2: Delphinus Package Manager

Cerca “LoggerPro” nel package manager Delphinus e installa.

Opzione 3: Clona il Repository (Solo Contributori)

Clona il repository solo se vuoi testare funzionalità non ancora rilasciate o contribuire al progetto:

git clone https://github.com/danieleteti/loggerpro.git

Poi aggiungi la cartella root e la sottocartella contrib al tuo Library Path come descritto sopra.

Nota: Il branch master può contenere codice instabile. Per uso in produzione, preferisci sempre l’Opzione 1.


Progetti Correlati

Progetto Descrizione
DMVCFramework Framework REST API con integrazione LoggerPro integrata
DelphiRedisClient Client Redis per TLoggerProRedisAppender

FAQ

Cosa c’è di nuovo in LoggerPro 2.0?

LoggerPro 2.0 introduce: API Builder pattern, logging contestuale con WithProperty(), logging delle eccezioni con stack trace, filtro livello minimo, metodo Shutdown() esplicito e thread safety migliorato.

LoggerPro 2.0 è retrocompatibile?

Sì, LoggerPro 2.0 è completamente retrocompatibile. Il tuo codice 1.x esistente che usa BuildLogWriter() continua a funzionare senza modifiche. La nuova API Builder pattern è un’aggiunta, non una sostituzione. Puoi adottare le nuove funzionalità incrementalmente.

Devo migrare il mio codice esistente?

No, non è richiesta nessuna migrazione. Il tuo codice 1.x funziona così com’è nella 2.0. Quando sei pronto, puoi opzionalmente adottare la nuova API Builder per nuovo codice o durante il refactoring.

Come aggiungo contesto ai miei log?

Usa Log.WithProperty('chiave', valore).Info('messaggio') per contesto ad-hoc, o Log.WithDefaultContext([...]) per contesto persistente su più chiamate.

Devo chiamare Shutdown()?

Sì, chiama Log.Shutdown nella finalization della tua applicazione per assicurarti che tutti i log pendenti vengano scritti prima dell’uscita. È sicuro chiamarlo più volte.

Qual è la differenza tra WithProperty e WithDefaultContext?

WithProperty() aggiunge contesto a una singola chiamata di log (fluent, concatenabile). WithDefaultContext() crea un sub-logger che include automaticamente il contesto in tutte le chiamate di log successive.

Come loggo su destinazioni multiple?

Usa il Builder per aggiungere appender multipli:

Log := LoggerProBuilder
  .WriteToFile.Done
  .WriteToConsole.Done
  .WriteToAppender(TLoggerProRedisAppender.Create(...))
  .Build;

LoggerPro supporta il logging asincrono?

Sì, tutti gli appender di LoggerPro sono asincroni di default. Le chiamate di logging ritornano immediatamente mentre un thread in background processa la coda dei log.

LoggerPro è thread-safe?

Sì, LoggerPro è completamente thread-safe. Thread multipli possono loggare simultaneamente senza sincronizzazione. La coda interna usa algoritmi lock-free per alte performance.

Quali versioni di Delphi sono supportate?

LoggerPro 2.0 supporta da Delphi 10 Seattle a Delphi 13 Florence. Il supporto Linux è disponibile da Delphi 10.2 Tokyo.

Come filtro i log per livello?

Usa WithMinimumLevel() nel Builder per impostare un filtro globale. I messaggi sotto il livello minimo vengono scartati prima dell’accodamento (zero overhead).

Posso usare LoggerPro in una DLL?

Sì, ma chiama Log.Shutdown prima di scaricare la DLL per assicurarti che il thread del logger termini correttamente. Questo è particolarmente importante per le DLL ISAPI.

Come loggo su Windows Event Log?

Usa .WriteToWindowsEventLog per applicazioni normali o .WriteToWindowsEventLogForService(Self) per Windows Services:

// Applicazione normale
Log := LoggerProBuilder
  .WriteToWindowsEventLog
    .WithSourceName('MyApp')
    .Done
  .Build;

// Windows Service
Log := LoggerProBuilder
  .WriteToWindowsEventLogForService(Self)
    .Done
  .Build;

Quali appender hanno supporto Builder nativo?

Tutti gli appender principali: File, JSONL File, Time Rotating File, Console, Simple Console, OutputDebugString, HTTP, ElasticSearch, UDP Syslog, FireDAC (database), Memory, Callback, VCL (Memo, ListBox, ListView) e Windows Event Log. Altri appender (Redis, Email, NSQ) possono essere aggiunti via .WriteToAppender().


LoggerPro 2.0 - Logging asincrono moderno per Delphi con Builder pattern. Logging contestuale. Gestione eccezioni. 20+ appender. Cross-platform. Open-source.

Comments

comments powered by Disqus