LoggerPro 2.1 - Der offizielle Leitfaden
TL;DR: LoggerPro 2.1 ist das asynchrone, thread-sichere Logging-Framework für Delphi. Es behält die Fluent-Builder-Pattern-API aus 2.0 und ergänzt externe Konfiguration per JSON (
LoggerProFromJSONFileoderLoggerProFromJSONString), ExeWatch Cloud-Observability, einen spezifikationskonformen LogFmt-Renderer, einen FileBySource-Appender für mandantenspezifische Logs, UTF-8-Konsolenausgabe für Docker, DLL-sichere Initialisierung, ElasticSearch-Authentifizierung und mehr. Drop-in-Upgrade von 2.0, Apache-2.0-lizenziert, lauffähig von Delphi 10.2 Tokyo bis Delphi 13 Florence, auf Windows / Linux / macOS / Android / iOS. LoggerPro 2.0 Dokumentation → · LoggerPro 1.x Dokumentation →
Auf einen Blick
| Name | LoggerPro |
| Version | 2.1.0 (April 2026) |
| Sprache | Delphi / Object Pascal |
| Minimum Delphi | 10.2 Tokyo · Getestet bis 13 Florence |
| Plattformen | Windows, Linux, macOS, Android, iOS |
| Lizenz | Apache 2.0 (kostenlos für kommerzielle Nutzung) |
| Autor | Daniele Teti |
| Repository | github.com/danieleteti/loggerpro |
| Installation | BOSS · ZIP-Release |
| Kategorie | Asynchron · Thread-sicher · Steckbar · Strukturiertes Logging |
| Nächste Äquivalente | Serilog (.NET), NLog (.NET), log4j / Logback (Java) |
Was ist LoggerPro?
LoggerPro ist das asynchrone, thread-sichere, steckbare Logging-Framework für Delphi / Object Pascal - das nächstliegende Delphi-Äquivalent zu Serilog (.NET), NLog (.NET) oder log4j / Logback (Java). Es bietet eine Fluent-Builder-API, strukturierten Schlüssel-Wert-Kontext, steckbare Stack-Trace-Formatter, über 20 eingebaute Appender (Datei, Konsole, HTTP, ExeWatch-Cloud-Observability, Grafana Loki via LogFmt, ElasticSearch, UDP-Syslog, Windows Event Log, Datenbank, VCL und mehr) und läuft plattformübergreifend auf Windows, Linux, macOS, Android und iOS. LoggerPro ist Apache-2.0-lizenziert, wird seit 2010 aktiv gepflegt und ist in Tausenden produktiver Delphi-Anwendungen im Einsatz.
Version 2.1 (April 2026) ist die aktuelle stabile Version. Sie baut auf der in 2.0 eingeführten Fluent-Builder-Pattern-API auf und ergänzt eine erstklassige ExeWatch-Integration für End-to-End-Cloud-Observability sowie Funktionen für moderne Deployment-Ziele - Docker-Container, Cloud-Log-Aggregatoren (Grafana Loki, Elastic, Datadog), Mehrmandanten-Anwendungen und Delphi-DLLs - bei voller Rückwärtskompatibilität.
Neuerungen in 2.1
| Feature | Nutzen |
|---|---|
| JSON-Konfiguration | Logger zum Deployment-Zeitpunkt umformen - LoggerProFromJSONFile('loggerpro.json'). Strikte Feldvalidierung, Diagnosen bei unbekannten Typen |
| HTML-Live-Log-Viewer | Eigenständige .html-Datei mit klebender Filterleiste, levelbasierter Einfärbung, clientseitiger Suche, CSV-/JSON-Export und Live-Tailing im Browser |
| ExeWatch-Integration | Erstklassiger Cloud-Observability-Appender für ExeWatch - imperative, fluente oder JSON-basierte Konfiguration |
| Plug-in-Appender-Pattern | Optionale Backends (ExeWatch, WindowsEventLog, ElasticSearch) registrieren sich automatisch aus der eigenen Unit - nur die uses-Klausel ergänzen |
Runtime-MinimumLevel |
ILogWriter.MinimumLevel ist jetzt eine erstklassige Property - globales Gate zur Laufzeit ändern |
| Webhook-Appender | Umbenannt von HTTPAppender; API-Key-Authentifizierung ergänzt (Header oder Query-String) |
| LogFmt-Renderer | Spezifikationskonforme key=value-Ausgabe; grep-freundlich, Loki-kompatibel, einzeilige Datensätze |
| FileBySource-Appender | Quellenspezifische (mandanten-, kundenspezifische) Unterordner mit Tages-+Größenrotation |
| UTF-8-Konsolenausgabe | Korrekte Unicode-Ausgabe in Docker-Containern und Windows-Konsolen (WithUTF8Output) |
| DLL-sichere Initialisierung | Behebt den Windows-Loader-Lock-Deadlock bei Nutzung von LoggerPro aus einer DLL |
| ElasticSearch-Auth | Basic Auth, API Key und Bearer-Token-Unterstützung |
| UDP-Syslog Lokalzeit | WithUseLocalTime(True)-Option am Syslog-Appender |
GetCurrentLogFileName |
Aktiven Log-Datei-Pfad abrufen - nützlich für Upload, E-Mail, Neustart |
Upgrade von 2.0? Weitgehend Drop-in-Ersatz. Eine Breaking Change:
WriteToHTTPwurde inWriteToWebhookumbenannt (ein Suchen-und-Ersetzen reicht). Alles Übrige ist additiv.
Schnellstart mit der Builder-API
uses
LoggerPro,
LoggerPro.Builder;
var
Log: ILogWriter;
begin
Log := LoggerProBuilder
.WithDefaultTag('MYAPP')
.WriteToFile
.WithLogsFolder('logs')
.WithMaxBackupFiles(5)
.WithMaxFileSizeInKB(10000)
.Done
.WriteToConsole
.Done
.Build;
Log.Info('Application started');
Log.Debug('Processing item %d', [42], 'WORKER');
Log.Error('Connection failed', 'DATABASE');
// 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 before exit
Log.Shutdown;
end;
JSON-Konfiguration
Neu in 2.1. Liefern Sie Ihre Anwendung mit einer loggerpro.json neben der
EXE aus und gestalten Sie den Logger zum Deployment-Zeitpunkt um, ohne neu
zu bauen. Betreiber können Backends wechseln, Log-Level anpassen oder
Appender hinzufügen bzw. entfernen, ohne den Quellcode anzufassen.
Schema auf einen Blick
{
"configVersion": 1,
"minimumLevel": "Debug",
"defaultMinimumLevel": "Warning",
"defaultTag": "myapp",
"appenders": [
{ "type": "Console", "colors": true, "colorScheme": "Midnight" },
{ "type": "File", "logsFolder": "logs", "maxBackupFiles": 5,
"minimumLevel": "Debug" },
{ "type": "HTMLFile", "logsFolder": "logs", "title": "MyApp" }
]
}
Das globale Gate lässt alles durch (minimumLevel: Debug). Jeder
Appender ohne eigenes minimumLevel übernimmt den Vorlagewert
Warning - Console und HTMLFile erben ihn beide. Der File-Appender
zieht ihn aus und schreibt den kompletten Audit-Trail auf Debug.
defaultMinimumLevel unter minimumLevel zu setzen wäre ein
No-op: das globale Gate hätte diese Nachrichten bereits verworfen,
bevor sie einen Appender erreichen.
Root-Felder:
| Feld | Typ | Zweck |
|---|---|---|
configVersion |
integer | Schema-Version. Fehlt = neueste. Höher als die Version der Bibliothek = harter Fehler. |
minimumLevel |
string | Globales Pre-Queue-Gate. "Debug" / "Info" / "Warning" / "Error" / "Fatal". Nachrichten unterhalb dieser Severity landen nie in der Queue - null Overhead für gefilterte Aufrufe. |
defaultMinimumLevel |
string | Vorlagewert, den jeder Appender als sein eigenes minimumLevel benutzt, wenn der Eintrag keines angibt. Selbst kein Gate - füllt zur Parse-Zeit nur die Appender-Schwelle vor. |
defaultTag |
string | Standard-Tag für Aufrufe wie Log.Info('msg') ohne Tag-Argument. |
appenders |
array | Pflichtfeld. Ein Objekt pro Appender, jeweils mit "type" und typspezifischen Feldern. |
Gemeinsame Felder pro Appender:
| Feld | Hinweise |
|---|---|
type |
Pflicht. Groß-/Kleinschreibung wird ignoriert, Abgleich gegen registrierte Typnamen. |
minimumLevel |
Optional. Minimale Severity, die dieser Appender emittiert. Nachrichten darunter werden von DIESEM Appender still verworfen (andere Appender sehen sie weiter). Gleicher Wertebereich wie Root-minimumLevel. Default ist defaultMinimumLevel (oder Debug, falls auch dieses fehlt). Einen Wert unter dem Root-minimumLevel zu setzen ist ein No-op: diese Nachrichten erreichen den Appender nicht, weil sie das Pre-Queue-Gate nicht passiert haben. |
Typspezifische Felder werden im Abschnitt jedes Appenders in diesem Guide aufgelistet; Tippfehler werden abgefangen (siehe Fehlerdiagnose unten).
Die drei Konzepte, sauber getrennt. Jeder Log-Aufruf trägt seine eigene Severity -
Log.Infoist Info,Log.Errorist Error, usw. WederminimumLevelnochdefaultMinimumLeveländern das; sie entscheiden nur wer was sieht. Das Root-minimumLevelist ein Pre-Queue-Filter (kostenlos: dasTLogItemwird für Nachrichten darunter gar nicht erst erzeugt). Das Per-Appender-minimumLevelist ein Emit-Gate (auf dem Worker-Thread des Appenders ausgewertet - entscheidet, ob DIESER Appender die Nachricht schreibt). Das Root-defaultMinimumLevelist ein Schreib-Zeit-Default für das Per-Appender-Gate, kein Laufzeit-Filter - es erlaubt dir zu sagen “jeder Appender startet bei Warning, außer er sagt etwas anderes”, ohne das Feld in jedem Eintrag zu wiederholen.
Was Pflicht ist, was Defaults hat
Das absolute Minimum ist ein einzelner Array-Eintrag:
{ "appenders": [ { "type": "Console" } ] }
Das war’s. Alles andere ist entweder optional oder wird abgeleitet. Der
appenders-Schlüssel auf Root-Ebene ist Pflicht (er darf ein leeres
Array sein, um einen No-op-Logger zu bauen, muss aber vorhanden sein).
Jeder Eintrag muss einen "type" haben; jedes andere Feld ist optional.
Default-Werte, wenn ein Feld ausgelassen wird:
| Feld | Wenn fehlend | Hinweise |
|---|---|---|
Root configVersion |
Wird als neueste bekannte Schema-Version behandelt (aktuell 1). |
Ein höherer Wert ist ein harter Fehler (Vorwärtskompatibilitäts-Schutz). |
Root minimumLevel |
Debug - alles passiert das globale Pre-Queue-Gate. |
Nachrichten unterhalb dieser Severity werden vor dem Enqueue gefiltert (null Overhead). |
Root defaultMinimumLevel |
Debug |
Wird als Default-minimumLevel jedes Appenders verwendet, der keines festlegt. |
Root defaultTag |
"main" |
Für Aufrufe ohne Tag-Argument (z. B. Log.Info('msg')). |
Appender minimumLevel |
defaultMinimumLevel (oder Debug, falls dieses ebenfalls fehlt). |
Der Appender emittiert nur Nachrichten ab dieser Severity. |
| Typspezifische Appender-Felder | Jeder Appender bringt eigene Defaults mit (siehe jeweiliger Abschnitt). | Z. B. Files logsFolder nutzt standardmäßig das EXE-Verzeichnis; Console nutzt standardmäßig Farben mit dem Midnight-Schema (mit "colorScheme": null oder "colors": false deaktivierbar). |
Minimale, einsatzbereite JSONs
In eine rotierende Datei loggen (das einfachste Deployment). Nimmt
das EXE-Verzeichnis als logsFolder und den EXE-Namen als Basis-Dateinamen;
5 Backups à 1 MB.
{
"appenders": [
{ "type": "File" }
]
}
Dateien woanders ablegen und mehr Historie behalten:
{
"appenders": [
{
"type": "File",
"logsFolder": "C:/ProgramData/MyApp/logs",
"fileBaseName": "myapp",
"maxBackupFiles": 30,
"maxFileSizeInKB": 5000
}
]
}
In die farbige Konsole loggen. Farben sind standardmäßig an, mit dem professionellen Midnight-Schema - ein Eintrags-Array reicht:
{
"appenders": [
{ "type": "Console" }
]
}
Schema per Name überschreiben (Groß-/Kleinschreibung egal) oder Farben komplett abschalten:
// Pick a different scheme
{ "appenders": [ { "type": "Console", "colorScheme": "Nord" } ] }
// Opt out: explicit null...
{ "appenders": [ { "type": "Console", "colorScheme": null } ] }
// ...or explicit empty string
{ "appenders": [ { "type": "Console", "colorScheme": "" } ] }
// ...or explicit colors:false
{ "appenders": [ { "type": "Console", "colors": false } ] }
Alle drei Opt-out-Varianten liefern reinen Text, ohne ANSI. Zusätzlich degradiert jedes farbige Schema automatisch zu reinem Text, wenn stdout in eine Datei umgeleitet oder in einen anderen Prozess gepipet wird - Sie bekommen nie versehentlich Escape-Codes in Ihren Log-Dateien.
Die eingebauten Farbschemata
Elf Schemata kommen mit LoggerPro. Alle halten sich an denselben
Paletten-Vertrag (Farbe pro Level + farbiger Tag, Metadaten, Kontext-
Schlüssel und -Werte), sie heben nur unterschiedliche Teile hervor.
Schemanamen sind in JSON case-insensitiv; die Screenshots unten sind
zur Referenz - starten Sie samples/03b_console_with_colors_appender,
um jedes Schema mit denselben Seed-Nachrichten im eigenen Terminal zu
sehen.
| Schema | Beschreibung |
|---|---|
| Default | Gin-inspirierte Vordergrund-Baseline; Level-Farbe pro Schweregrad. |
| Monochrome | Kein ANSI - reiner Text. Wird automatisch aktiv, wenn stdout umgeleitet/gepipet wird. |
| GinBadge | Default-Töne plus farbiges Hintergrund-“Badge” für das Level. |
| GinMinimal | Alles gedämpftes Grau, nur das Level-Wort behält Farbe. |
| GinVibrant | Satter Regenbogen - jedes Feld in einer eigenen auffälligen Farbe. |
| Midnight | Magenta Prefix/Tag, grüne Keys, Cyan-Werte. JSON-Default - liest sich gut auf hellen wie dunklen Terminals. |
| Nord | Frost-Theme mit kühlen arktischen Blau-/Cyantönen, gelbe Warnungen, rotes Fatal. |
| Matrix | Alles grün; Levels als Hintergrund-Badges. |
| Amber | 80er-Jahre-Amber-CRT-Monitor - Gelb-/Orangefamilie, Rot nur für Fehler. |
| Ocean | Geschichtete Blau- und Cyantöne - Teal-Tag, leuchtend-cyane Werte. |
| Cyberpunk | Neon-Magenta Prefix, Cyan-Tag, gelbe Werte; lebendige Level-Badges. |
Auswahl aus JSON. Einfach per Name referenzieren:
// A calm palette for a dev console
{ "appenders": [ { "type": "Console", "colors": true, "colorScheme": "Nord" } ] }
// Level badges - fastest level scanning
{ "appenders": [ { "type": "Console", "colors": true, "colorScheme": "GinBadge" } ] }
// Plain text, no ANSI - useful in tests or when piping to a file
{ "appenders": [ { "type": "Console", "colors": true, "colorScheme": "Monochrome" } ] }
Auswahl aus Code:
uses LoggerPro, LoggerPro.Builder;
Log := LoggerProBuilder
.WriteToConsole
.WithColorScheme(LogColorSchemes.Midnight) // or .Nord / .Matrix / ...
.Done
.Build;
Eigenes Schema. Jedes Schema ist ein TLogColorScheme-Record -
Sie können Ihres ausgehend von einem Preset bauen und die relevanten
Felder überschreiben:
var lScheme: TLogColorScheme;
begin
lScheme := LogColorSchemes.Midnight;
lScheme.TagColor := FORE_YELLOW;
lScheme.LevelColor[TLogType.Info] := STYLE_BRIGHT + FORE_WHITE;
Log := LoggerProBuilder
.WriteToConsole.WithColorScheme(lScheme).Done
.Build;
end;
Automatische Abwärtskompatibilität. Wird stdout in eine Datei
umgeleitet oder in einen anderen Prozess gepipet, degradiert der
Renderer automatisch zu reinem Text (entspricht Monochrome). Sie
bekommen nie versehentlich Escape-Codes in Ihren Log-Dateien.
Weitere optionale Felder:
{
"appenders": [
{
"type": "Console",
"colors": true,
"colorScheme": "Nord",
"prefix": "MYAPP", // shows as [MYAPP] before each line
"utf8Output": true // safe output in Docker / Windows consoles
}
]
}
Beide kombiniert für ein typisches Dev-Setup - farbige Konsole plus rotierte Datei mit getrennten Levels:
{
"minimumLevel": "Debug",
"appenders": [
{ "type": "Console", "colors": true, "colorScheme": "Midnight" },
{ "type": "File", "logsFolder": "logs", "minimumLevel": "Info" }
]
}
Einstiegspunkte
Zwei globale Funktionen in der LoggerPro-Unit - die eine liefert einen
einsatzbereiten ILogWriter, die andere den nicht finalisierten
ILoggerProBuilder, sodass Aufrufer weiter verketten können:
uses LoggerPro;
// 1. Pure JSON → ILogWriter (simplest, covers most cases)
Log := LoggerProFromJSONFile('loggerpro.json');
// 1b. Pure JSON from an embedded resource or a hand-assembled string
Log := LoggerProFromJSONString(MyEmbeddedConfig);
uses LoggerPro, LoggerPro.Builder;
// 2. JSON base + more appenders from code (the "mixed" pattern)
Log := LoggerProBuilderFromJSONFile('loggerpro.json')
.WriteToCallback
.WithCallback(MyProc)
.Done
.Build; // you call .Build yourself
Beide Funktionen werfen bei Problemen mit der Datei
ELoggerProConfigError - siehe Fehlerdiagnose unten für die genauen
Meldungen.
Dateikonfiguration mit Laufzeit-Appendern mischen
Manche Appender lassen sich nicht in JSON beschreiben, weil sie eine
Laufzeit-Objektreferenz benötigen, die nicht in eine Konfigurationsdatei
passt: einen Callback, ein TStrings, eine VCL-Komponente, eine lebendige
TFDConnection. Das Pattern ist immer das gleiche:
- Den JSON-beschreibbaren Teil mit
LoggerProBuilderFromJSONFileladen. - Die Extras auf dem zurückgegebenen Builder anketten.
- Selbst
.Buildaufrufen.
Beispiel 1 - JSON-Basis + UI-Callback für eine Statusleiste.
uses
LoggerPro, LoggerPro.Builder;
Log := LoggerProBuilderFromJSONFile('loggerpro.json')
.WriteToCallback
.WithCallback(
procedure(const aLogItem: TLogItem; const aFormattedMessage: string)
begin
// The callback appender marshals to the main thread for us.
StatusBar1.SimpleText := aFormattedMessage;
end)
.WithSynchronizeToMainThread(True)
.Done
.Build;
Beispiel 2 - JSON-Basis + VCL-TListView-Spiegel. Der Benutzer
konfiguriert Datei/Konsole via JSON; die GUI-Live-Tail bleibt im Code.
uses
LoggerPro, LoggerPro.Builder;
procedure TMainForm.FormCreate(Sender: TObject);
begin
FLog := LoggerProBuilderFromJSONFile('loggerpro.json')
.WriteToVCLListView(ListViewLogs)
.WithMaxLogLines(1000)
.Done
.Build;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
FLog.Shutdown; // before the form - and the ListView - are freed
FLog := nil;
end;
Beispiel 3 - JSON-Basis + FMX-TMemo. TMemo.Lines ist ein
TStrings, daher deckt der plattformübergreifende WriteToStrings-
Appender FMX, VCL und alles ab, was ein TStrings bereitstellt.
FLog := LoggerProBuilderFromJSONFile('loggerpro.json')
.WriteToStrings(MemoLog.Lines)
.WithMaxLogLines(500)
.WithClearOnStartup(True)
.Done
.Build;
Beispiel 4 - JSON-Basis + Datenbank-Appender. Die JSON steuert
Konsole/Datei/HTML; die DB-Verbindung bleibt im Code, weil
TFDConnection nicht serialisierbar ist.
uses
LoggerPro, LoggerPro.Builder, LoggerPro.DBAppender.FireDAC;
FLog := LoggerProBuilderFromJSONFile('loggerpro.json')
.WriteToFireDAC
.WithConnectionDefName('MAIN_DB')
.WithStoredProcName('sp_insert_log')
.WithMinimumLevel(TLogType.Warning) // DB only gets Warning+
.Done
.Build;
Szenarien und Sonderfälle
Das Per-Appender-minimumLevel ist unabhängig vom Root-
minimumLevel. Das Root-Gate entscheidet, ob eine Nachricht
überhaupt in die Queue kommt; das Gate des einzelnen Appenders
entscheidet, ob dieser Appender die Nachricht schreibt. Eine
Nachricht unter dem Root-minimumLevel erreicht keinen Appender;
eine Nachricht, die das Root-Gate passiert, aber unter dem
minimumLevel eines Appenders liegt, wird von diesem Appender
verworfen, während die übrigen sie trotzdem erhalten.
{
"minimumLevel": "Debug",
"appenders": [
{ "type": "Console", "minimumLevel": "Debug" },
{ "type": "File", "logsFolder": "logs", "minimumLevel": "Info" },
{ "type": "Webhook", "url": "https://ops/alerts",
"minimumLevel": "Error" }
]
}
Ergebnis: Entwickler sehen alles auf der Konsole, die Log-Datei behält
Info+, der Webhook feuert nur bei Fehlern.
Ein leeres appenders-Array ist erlaubt - Sie erhalten einen
“Schwarzes-Loch”-Logger, nützlich für Integrationstests:
{ "configVersion": 1, "appenders": [] }
Effektiv deaktiviertes Logging ist einfach ein globales Gate hoch genug, dass nichts mehr durchkommt:
{ "configVersion": 1, "minimumLevel": "Fatal", "appenders": [] }
Oder im Code die Runtime-Property auf einem bereits gebauten Writer
umschalten: Log.MinimumLevel := TLogType.Fatal;
Plug-in-Appender (ExeWatch, WindowsEventLog, ElasticSearch
und jeder Drittanbieter-Appender, der derselben Konvention folgt)
brauchen ihre Unit in uses. Vergessen erzeugt eine präzise
Fehlermeldung (siehe unten).
Optionale JSON-Quelle. Binden Sie eine Standard-JSON in Ressourcen ein und überschreiben Sie sie per On-Disk-Datei, wenn vorhanden:
uses System.IOUtils;
if TFile.Exists('loggerpro.json') then
Log := LoggerProFromJSONFile('loggerpro.json')
else
Log := LoggerProFromJSONString(LoadDefaultConfigFromResources);
Fehlerdiagnose
Der Parser ist bewusst strikt - Fehlkonfigurationen scheitern laut
statt still halb zu funktionieren. Alle Fehler erscheinen als
ELoggerProConfigError (deklariert in LoggerPro.pas, sodass ein
einzelnes uses LoggerPro; ausreicht, um sie zu fangen).
Unbekanntes Feld (Tippfehler-Erkennung):
appenders[0] (type=Console): unknown field "colour".
Valid fields: minimumLevel, colors, colorScheme, prefix, utf8Output.
Unbekannter Appender-Typ (fehlendes uses):
appenders[1]: unknown type "ExeWatch".
Currently registered types: console, elasticsearch, file, filebysource,
htmlfile, jsonlfile, memory, outputdebugstring, simpleconsole,
timerotatingfile, udpsyslog, webhook.
If you want "ExeWatch", make sure the unit that registers it is in your
`uses` clause (typically LoggerPro.ExeWatchAppender) - optional
appenders self-register from their initialization section, so simply
including the unit is enough. For custom factories use
TLoggerProConfig.RegisterAppenderType.
Schema-Version zu neu:
configVersion 2 is newer than supported (max 1). Update LoggerPro.
Ungültiger Enum-Wert:
appenders[0] (type=Console): invalid colorScheme "NEON".
Valid values: Default, Monochrome, GinBadge, GinMinimal, GinVibrant,
Midnight, Nord, Matrix, Amber, Ocean, Cyberpunk.
Fehlende Datei oder fehlerhaftes JSON werfen ebenfalls
ELoggerProConfigError, mit Dateipfad bzw. Parser-Diagnose.
Kontrollierter Fallback
Für Erstlauf- oder Fehlkonfigurationsszenarien fangen Sie den Fehler und bauen im Code einen defensiven Default, damit die Anwendung weiter loggt statt abzustürzen:
uses LoggerPro, LoggerPro.Builder;
function BuildLoggerSafe(const aConfigPath: string): ILogWriter;
begin
try
Result := LoggerProFromJSONFile(aConfigPath);
except
on E: ELoggerProConfigError do
begin
Result := LoggerProBuilder
.WriteToConsole.Done
.WithMinimumLevel(TLogType.Info)
.Build;
Result.Warn(
Format('Config fallback: %s', [E.Message]),
'CONFIG');
end;
end;
end;
Die Warnung landet im Fallback-Logger selbst, sodass Betreiber das Problem beim nächsten Ausgabe-Tail bemerken.
Eigene Appender-Typen
LoggerPro.Config ist eine Typ-Registry; Ihre eigenen Appender
können sich genauso einklinken wie die eingebauten:
uses LoggerPro, LoggerPro.Config;
procedure MyCustomFactory(const aBuilder: ILoggerProBuilder;
const aConfig: TJSONObject);
begin
aBuilder.WriteToAppender(TMyCustomAppender.Create(
aConfig.GetValue('endpoint').Value));
end;
initialization
TLoggerProConfig.RegisterAppenderType(
'MyCustom',
MyCustomFactory,
['minimumLevel', 'endpoint']); // closed set of allowed fields
Ab dann funktioniert { "type": "MyCustom", "endpoint": "..." }, und
Tippfehler in Feldnamen lösen dieselbe strikte Diagnose aus wie bei
den eingebauten.
Beispiele: samples/240_config_simple, 241_config_advanced,
242_config_fallback.
Plug-in-Appender (Auto-Register-Pattern)
Appender, die externe Systeme anbinden - ExeWatch, WindowsEventLog, ElasticSearch - bleiben AUSSERHALB des Kern-Runtime-Pakets. Das hält den Kern abhängigkeitsfrei und verhindert, dass optionale SDKs (wie der ExeWatch-Client) von jedem LoggerPro-Nutzer benötigt werden.
Funktionsweise: jede optionale Appender-Unit registriert ihre
eigene JSON-Factory aus ihrer initialization-Sektion. Die Unit in
die uses-Klausel irgendeines Moduls Ihres Projekts zu packen, reicht
aus, um ihren "type"-Wert in loggerpro.json zu aktivieren.
// main.dpr
uses
LoggerPro,
LoggerPro.ExeWatchAppender, // enables "type": "ExeWatch"
LoggerPro.WindowsEventLogAppender, // enables "type": "WindowsEventLog"
LoggerPro.ElasticSearchAppender; // enables "type": "ElasticSearch"
begin
Log := LoggerProFromJSONFile('loggerpro.json');
end.
Verweist eine JSON-Datei auf einen Appender, dessen Unit nicht in
uses steht, nennt die Fehlermeldung genau, welche Unit zu ergänzen ist.
LogFmt-Ausgabe (strukturiert, grep-freundlich)
LogFmt ist ein zeilenorientiertes strukturiertes Log-Format,
populär gemacht durch Heroku und Brandur Leach. Jede Log-Zeile ist
eine Folge von key=value-Paaren, durch einzelne Leerzeichen getrennt.
Werte stehen nackt, wenn sicher, sonst in doppelten Anführungszeichen
mit \"- und \\-Escapes. Der Sweet Spot zwischen menschenlesbaren
Text-Logs und maschinen-parsbarem JSON.
Beispielausgabe
time=2026-04-18T12:30:45.123Z threadid=7932 type=INFO msg="order placed" tag=ORDERS order_id=42 amount=99.95 paid=true
Aktivieren
Den TLogItemRendererLogFmt-Renderer über den Builder in jeden
Appender stecken:
uses
LoggerPro, LoggerPro.Builder, LoggerPro.Renderers;
Log := LoggerProBuilder
.WriteToConsole
.WithRenderer(TLogItemRendererLogFmt.Create)
.Done
.WriteToFile
.WithRenderer(TLogItemRendererLogFmt.Create)
.Done
.Build;
Log.Info('order placed', 'ORDERS', [
LogParam.I('order_id', 42),
LogParam.F('amount', 99.95),
LogParam.B('paid', True)
]);
Oder global als Default-Renderer setzen:
LoggerPro.Renderers.gDefaultLogItemRenderer := TLogItemRendererLogFmt;
Warum LogFmt
- Lesbar im Terminal: einzeilige Datensätze, kein nachgelagerter Müll.
- Trivial greppable:
grep 'order_id=42'funktioniert einfach. - Streaming-freundlich: jede Zeile ist selbsthaltend - keine mehrzeiligen JSON-Objekte aus Container-stdout zusammenzusetzen.
- Günstig zu produzieren: kein Escape-lastiger JSON-Serializer im heißen Pfad.
- Tooling: nativ geparst von
humanlog,lnav, Grafana Loki, Vector, Fluent Bit, Promtail, Filebeat.
Spezifikationstreue
LoggerPros LogFmt-Renderer:
- Setzt Werte mit Leerzeichen,
",=,\oder Steuerzeichen in Anführungszeichen. - Escapet
"als\",\als\\,\n\r\tals literale Escape-Sequenzen. - Nicht druckbare Steuerbytes werden zu
\uNNNN. - Bereinigt Kontext-Keys auf
[a-zA-Z0-9_.-](ungültige Zeichen werden zu_). - Floats verwenden immer
.als Dezimaltrennzeichen (locale-unabhängig). - Booleans als nackte
true/false.
Das heißt, die Ausgabe ist sicher, zeilenweise durch grep, awk,
jq -R, Lokis logfmt-Parser etc. zu streamen, ohne Korruption.
LogFmt-Logs unter Windows abfragen
1. ripgrep (rg) - universeller Filter
Installation:
# Option A: winget (Windows 10/11)
winget install BurntSushi.ripgrep.MSVC
# Option B: Scoop
scoop install ripgrep
# Option C: download ripgrep-*.zip from GitHub releases, unzip, put rg.exe on PATH
Nutzung:
# All errors
rg "type=ERROR" logs\myapp*.log
# One specific order, any log level
rg "order_id=42\b" logs\myapp*.log
# Errors for a given user in the last file only
rg "type=ERROR.*user_id=7" (Get-ChildItem logs\myapp*.log | Sort LastWriteTime -Desc | Select -First 1).FullName
# Count errors per tag
rg -o "tag=\S+" logs\myapp*.log | Group-Object | Sort Count -Desc
2. humanlog - logfmt-bewusster Pretty-Printer & Filter
humanlog ist ein Go-Binary,
das LogFmt (und JSON) nativ versteht: es koloriert Levels, richtet
Spalten aus, parst Timestamps und erlaubt Filter mit einer Mini-
Ausdruckssprache. Deutlich angenehmer als rg, wenn Sie Logs lesen
und nicht nur greppen.
Installation:
# Download humanlog_<version>_windows_amd64.zip from GitHub releases, unzip, put
# humanlog.exe on PATH. Or via Scoop:
scoop bucket add extras
scoop install humanlog
Nutzung:
# Pretty-print a static log file
Get-Content logs\myapp.20260418.log | humanlog
# Pipe directly from your Delphi app's stdout (console appender + logfmt)
.\MyApp.exe | humanlog
# Filter: only errors (mini-expression language)
Get-Content logs\*.log | humanlog --skip "type!=ERROR"
# Keep only matching records
Get-Content logs\*.log | humanlog --keep "tag=ORDERS and type=ERROR"
# Hide noisy context keys
Get-Content logs\*.log | humanlog --ignore "threadid,time"
Live-Tail (tail -f-Stil)
PowerShells Get-Content -Wait ist der Baustein für Live-Tailing
unter Windows:
Get-Content logs\myapp.20260418.log -Wait -Tail 20
Beachten Sie, dass Get-Content -Wait den Original-Datei-Handle
überwacht und LoggerPros Tages-/Größenrotation nicht mitverfolgt.
Fortgeschrittene Techniken (Re-Tail-Schleifen, Prozess-stdout-Piping,
Encoding-Fallstricke) finden Sie im
Blog.
Ohne Installation: Select-String
Wenn Sie auf einer Produktionsmaschine nichts installieren dürfen, ist
Select-String auf jeder Windows-Installation vorhanden:
# Errors for tag ORDERS
Select-String -Path logs\myapp*.log -Pattern "type=ERROR.*tag=ORDERS"
# Context block around a match (2 lines before/after)
Select-String -Path logs\*.log -Pattern "order_id=42\b" -Context 2,2
Jenseits von grep-artigen Tools
Sobald Sie viele Dateien, mehrere Hosts oder >GB/Tag an Logs haben, hören Sie mit dem Greppen auf und beginnen mit dem Shippen:
-
Grafana Loki + Promtail - LogQL mit nativem
| logfmt-Parser:{app="myapp"} | logfmt | type="ERROR" | order_id="42" -
Vector (einzelne
.exe, konfigurationsgetrieben) - mit demlogfmt-Codec parsen, an Elastic, Clickhouse, Datadog, S3 etc. liefern. -
Fluent Bit (einzelne
.exe) - ähnlich, leichtgewichtig.
LogFmt vs. JSONL - wann welches
LoggerPro unterstützt auch JSONL (ein JSON-Objekt pro Zeile) via
TLoggerProJSONLFileAppender. Faustregel:
- LogFmt → Entwicklungsmaschinen, Container-stdout, greppable Produktions-Logs, niedriges/mittleres Volumen, flacher Kontext.
- JSONL → verschachtelte Strukturen, Analytics-Pipelines, Elastic/Datadog/OpenObserve-Ingest, hohes Volumen, striktes Schema.
Beide Renderer teilen dieselbe LogParam.S/I/F/B/D-Kontext-API, Sie
können also zwischen ihnen wechseln, ohne Anwendungscode zu ändern.
FileBySource-Appender
Neu in 2.1. Organisiert Logs in quellenspezifischen Unterordnern - perfekt für Mehrmandanten-Anwendungen, in denen jeder Kunde, jedes Gerät oder jedes Konto einen eigenen Log-Stream bekommt. Der Quellen-Schlüssel stammt aus dem Log-Kontext.
uses
LoggerPro.Builder;
Log := LoggerProBuilder
.WriteToFileBySource
.WithLogsFolder('logs')
.WithMaxFileSizeInKB(5000)
.WithRetainDays(30)
.WithDefaultSource('default')
.Done
.Build;
// Source comes from the context
Log.Info('Order placed', 'ORDERS', [
LogParam.S('source', 'ClientA'),
LogParam.I('order_id', 42)
]);
// → logs/ClientA/ClientA.ORDERS.20260418.00.log
Die Rotation ist Tag + Größe: eine neue Datei wird bei Tageswechsel
geöffnet und wenn die aktuelle Datei WithMaxFileSizeInKB überschreitet.
Dateien älter als WithRetainDays werden beim Start und bei jedem
Tageswechsel automatisch gelöscht.
HTML-Live-Log-Viewer
Neu in 2.1. Eine eigenständige HTML-Log-Datei, die Sie in jedem Browser
öffnen können - kein Server, keine externen Assets, eine .html pro
Rotation. Nützlich, um Benutzern, QA oder Support ein kompaktes
Troubleshooting-Artefakt zu übergeben.
uses LoggerPro, LoggerPro.Builder;
Log := LoggerProBuilder
.WriteToHTMLFile
.WithLogsFolder('logs')
.WithFileBaseName('myapp')
.WithTitle('MyApp - Operations Log')
.WithMaxFileSizeInKB(1000)
.WithMaxBackupFiles(10)
.Done
.Build;
Die erzeugte Seite enthält:
- Klebende Filterleiste - Checkboxen pro Level und ein Volltextsuchfeld.
- Zeileneinfärbung - WARNING / ERROR / FATAL tragen einen dezenten Hintergrundton, sodass Anomalien beim Scrollen auffallen.
- Kontext-Rendering - strukturierter
LogParam-Kontext wird als key=value-Paare in einer sekundären Zeile angezeigt, über dieselben Filter-Controls ein-/ausblendbar. - CSV-/JSON-Export - aktuell sichtbare Zeilen herunterladen.
- Live-Tail - solange die Datei geschrieben wird, aktualisiert sich die Seite alle 3 Sekunden automatisch und scrollt immer ans Ende.
- LIVE-/FINALIZED-Erkennung - die Seite weiß, ob die Log-Datei noch geschrieben wird oder geschlossen wurde, und stoppt den Auto-Reload, sobald sie finalisiert ist.
Beispiel: samples/230_html_file_appender. Auch als JSON-Config
"type": "HTMLFile" verfügbar.
UTF-8-Konsolenausgabe (Docker / Windows)
Standardmäßig konvertiert Delphis Writeln in die System-Locale-Kodierung,
was Nicht-ASCII-Zeichen in Docker-Containern (POSIX/C-Locale) und auf
Windows-Konsolen (CP 437/1252) entstellt. Aktivieren Sie WithUTF8Output,
um UTF-8-Bytes direkt nach stdout zu schreiben:
Log := LoggerProBuilder
.WriteToConsole
.WithUTF8Output
.Done
.Build;
// Also available for the plain (no-color) console appender
Log := LoggerProBuilder
.WriteToSimpleConsole
.WithUTF8Output
.Done
.Build;
Das ist besonders nützlich, wenn Delphi-Anwendungen in Docker-Containern laufen oder Unicode-Text (CJK, Kyrillisch, Emoji usw.) auf Windows geloggt wird.
DLL-sichere Initialisierung
LoggerPro 2.1 funktioniert korrekt in DLLs, die via LoadLibrary oder
P/Invoke geladen werden. Die Logger-Thread-Initialisierung erkennt den
DLL-Kontext und vermeidet den Windows-Loader-Lock-Deadlock, der frühere
Versionen betraf.
library MyPlugin;
uses
LoggerPro, LoggerPro.Builder;
var
GLog: ILogWriter;
begin
// Safe during DLL_PROCESS_ATTACH
GLog := LoggerProBuilder
.WriteToFile.Done
.Build;
GLog.Info('DLL loaded successfully');
end.
Hinweis: Rufen Sie
GLog.Shutdownvor dem Entladen der DLL auf, falls Sie sicherstellen möchten, dass Nachrichten in der Queue übertragen werden.
Kontextuelles Logging
LoggerPros Kontext-Logging-Funktionen erlauben es Ihnen, jeden Log-Aufruf mit strukturierten Schlüssel-Wert-Paaren anzureichern, ohne sich zu wiederholen.
WithProperty (Ad-hoc-Kontext)
Log.WithProperty('order_id', 12345)
.WithProperty('amount', 99.99)
.Info('Order processed', 'orders');
WithDefaultTag (Sub-Logger)
var
OrderLog: ILogWriter;
begin
OrderLog := Log.WithDefaultTag('ORDERS');
OrderLog.Info('Processing started'); // tag = 'ORDERS'
OrderLog.Warn('Stock low'); // tag = 'ORDERS'
end;
WithDefaultContext (persistenter Kontext)
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('Response sent'); // includes request_id, client_ip
end;
Strukturierter Kontext inline
Log.Info('Order completed', 'ORDERS', [
LogParam.I('order_id', 12345),
LogParam.S('customer', 'John Doe'),
LogParam.F('total', 299.99),
LogParam.B('paid', True)
]);
Exception-Logging
try
// Code that may raise
except
on E: Exception do
begin
Log.LogException(E);
Log.LogException(E, 'Database query failed');
Log.LogException(E, 'Query failed', 'db');
end;
end;
Stack-Trace-Formatter
Integrieren Sie mit JCL, madExcept, EurekaLog oder einer beliebigen Stack-Trace-Bibliothek:
Log := LoggerProBuilder
.WithStackTraceFormatter(
function(E: Exception): string
begin
Result := JclLastExceptStackListToString;
end)
.WriteToFile.Done
.Build;
Minimum-Level-Filterung
Nachrichten global vor der Queue-Einreihung filtern - Null-Overhead für gefilterte Nachrichten:
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
Neu in 2.1: das Gate ist eine erstklassige Property auf ILogWriter,
sodass Sie es zur Laufzeit ohne Cast ändern können:
Log.MinimumLevel := TLogType.Fatal; // effectively mute
// Later
Log.MinimumLevel := TLogType.Debug; // re-enable everything
ElasticSearch mit Authentifizierung
Neu in 2.1. Der ElasticSearch-Appender unterstützt jetzt alle drei gängigen Auth-Mechanismen:
// Basic Auth
Log := LoggerProBuilder
.WriteToElasticSearch
.WithURL('https://elastic.example.com:9200/logs/_doc')
.WithBasicAuth('username', 'password')
.Done
.Build;
// API Key
Log := LoggerProBuilder
.WriteToElasticSearch
.WithHost('https://elastic.example.com')
.WithPort(9200)
.WithIndex('app-logs')
.WithAPIKey('your-api-key-here')
.Done
.Build;
// Bearer Token (JWT, OAuth2)
Log := LoggerProBuilder
.WriteToElasticSearch
.WithURL('https://elastic.example.com:9200/logs/_doc')
.WithBearerToken('your-jwt-token')
.Done
.Build;
ExeWatch-Integration (Cloud-Observability)
Was ist ExeWatch. ExeWatch ist ein Cloud-Observability-Service für Desktop- und Backend-Anwendungen: es sammelt Logs, Exceptions, Breadcrumbs, Benutzeridentität, Geräteinfo und eigene Metriken und stellt ein Dashboard bereit, um Vorfälle in der Produktion zu untersuchen, ohne Log-Dateien herumzuschicken.
Warum ein dedizierter Appender. ExeWatch liefert ein eigenes
Delphi-SDK (ExeWatchSDKv1.pas). Der LoggerPro-Bridge - Unit
LoggerPro.ExeWatchAppender - wandelt jeden
Log.Info / Warn / Error / Fatal / LogException-Aufruf in den
entsprechenden SDK-Aufruf um, sodass Sie die LoggerPro-API behalten
und transparent die ExeWatch-Pipeline gewinnen. Sie ist nicht Teil
des LoggerPro-Runtime-Pakets, sodass Projekte, die ExeWatch nicht
nutzen, nichts bezahlen.
Bridge aktivieren. Fügen Sie den SDK-Ordner zum Projekt-Suchpfad
hinzu (das Sample nutzt C:\dev\exewatchsamples\DelphiCommons) und
ziehen Sie die Bridge-Unit:
uses
LoggerPro,
LoggerPro.Builder,
LoggerPro.ExeWatchAppender;
Das SDK wird beim Setup des Appenders automatisch initialisiert - Sie
müssen InitializeExeWatch NICHT selbst aufrufen, und der Appender
stört ein bereits von anderem Code initialisiertes SDK nicht.
Vier Wege der Verdrahtung
1. Fluent-Builder - alles im Code; passt, wenn API-Key, Customer-ID und Version Literale sind oder aus einfachen globalen Variablen kommen. Verketten wie bei jedem eingebauten Appender:
Log := WithExeWatch(LoggerProBuilder)
.WithAPIKey('ew_win_xxxxxx')
.WithCustomerId('Acme Corp')
.WithAppVersion('2.3.1')
.WithAnonymizeDeviceId(False) // True = per-install ID (GDPR-friendly)
.Done
.WriteToConsole.WithColors.Done // mirror to the console too
.Build;
2. Fluent-Kette auf JSON-Basis - kombiniert eine loggerpro.json
mit codeseitiger ExeWatch-Konfiguration. Die Basisdatei trägt das
Konsole-/Datei-/HTML-Setup; die SDK-Secrets bleiben im Code, von wo
sie aus einem Vault, einer Umgebungsvariable oder einem License-Server
geladen werden können:
uses
LoggerPro, LoggerPro.Builder, LoggerPro.ExeWatchAppender;
Log := WithExeWatch(
LoggerProBuilderFromJSONFile('loggerpro.json'))
.WithAPIKey(LoadFromVault('ew_api_key'))
.WithCustomerId(CurrentTenant)
.WithAppVersion(GetFileVersion)
.Done
.Build;
3. Imperativ (geringster Widerstand, wenn Werte aus Konfigurationsobjekten kommen):
Log := LoggerProBuilder
.WriteToAppender(NewExeWatchAppender(
'ew_win_xxxxxx', 'Acme Corp', '2.3.1'))
.Build;
4. Reine JSON-Konfiguration (dank des Auto-Register-Patterns kein zusätzlicher Registrierungsaufruf nötig):
{
"configVersion": 1,
"appenders": [
{ "type": "Console" },
{
"type": "ExeWatch",
"apiKey": "ew_win_xxxxxx",
"customerId": "Acme Corp",
"appVersion": "2.3.1",
"anonymizeDeviceId": false
}
]
}
uses LoggerPro, LoggerPro.ExeWatchAppender;
Log := LoggerProFromJSONFile('loggerpro.json');
Level-Abbildung
TLogType |
ExeWatch SDK Severity |
|---|---|
Debug |
EW.Debug |
Info |
EW.Info |
Warning |
EW.Warning |
Error |
EW.Error |
Fatal |
EW.Fatal |
Der Log-Tag wird als SDK-Tag weitergereicht. Strukturierter
LogParam-Kontext wird in den formatierten Nachrichtentext
zusammengefaltet - wenn Sie die reicheren SDK-Funktionen
(Breadcrumbs, Timings, Benutzeridentität, Gauges) nutzen möchten,
rufen Sie EW.AddBreadcrumb / EW.SetUser / EW.StartTiming direkt
neben LoggerPro auf. Die beiden Schichten koexistieren frei.
Shutdown
Log.Shutdown leert die LoggerPro-Queue und ruft anschließend
EW.Flush auf, sodass jedes clientseitig in die Queue gestellte
Ereignis vor dem Prozessende übertragen wird. Das SDK-eigene
Finalization-Handling erledigt den Rest.
Beispiel: samples/260_exewatch_appender.
UDP-Syslog (RFC 5424) mit Lokalzeit
Neue WithUseLocalTime-Option - RFC 5424 verlangt UTC, viele
On-Prem-Syslog-Server erwarten jedoch Lokalzeit.
Log := LoggerProBuilder
.WriteToUDPSyslog
.WithHost('syslog.example.com')
.WithPort(514)
.WithApplication('MyApp')
.WithUseLocalTime(True) // default: False (UTC)
.Done
.Build;
Aktuellen Log-Dateinamen abrufen
Neu in 2.1. Nützlich zum Hochladen, E-Mail-Versand oder Anhängen einer Log-Datei auf Anfrage.
uses LoggerPro, LoggerPro.Builder, LoggerPro.FileAppender;
var
lAppender: TLoggerProSimpleFileAppender;
Log: ILogWriter;
begin
lAppender := TLoggerProSimpleFileAppender.Create;
Log := LoggerProBuilder
.WriteToAppender(lAppender)
.Build;
Log.Info('Message');
UploadLogFile(lAppender.GetCurrentLogFileName);
end;
Für TLoggerProFileAppender (eine Datei pro Tag):
var
lAppender: TLoggerProFileAppender;
begin
lAppender := TLoggerProFileAppender.Create;
// Get file for a specific tag
lFileName := lAppender.GetCurrentLogFileName('ORDERS');
// Or all current log files
lAllFiles := lAppender.GetAllCurrentLogFileNames;
end;
Shutdown
Rufen Sie Shutdown in der Finalization Ihrer Anwendung auf, um zu
garantieren, dass alle ausstehenden Logs geschrieben werden:
procedure TMyApp.Finalize;
begin
Log.Shutdown; // Flush queue, stop thread
Log := nil;
end;
Zentrale Verhaltensweisen:
- Idempotent: mehrfacher Aufruf ist sicher.
- Leert alle ausstehenden Nachrichten.
- Beendet den Logger-Thread.
- Nach Shutdown werden Log-Aufrufe still ignoriert (Release) oder werfen Assert (Debug).
Eingebaute Appender
LoggerPro 2.1 liefert über 20 Appender mit. Alle sind asynchron, thread-sicher und per Builder konfigurierbar.
File-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| FileAppender | WriteToFile |
Eine Datei pro Tag mit größenbasierter Rotation. Default: 5 Backups, 1 MB max. Unterstützt zeitbasierte Rotation. |
| SimpleFileAppender | WriteToFile |
Alle Logs in einer Datei (keine Tag-Trennung). Gleiche Rotationsoptionen. |
| JSONLFileAppender | WriteToJSONLFile |
Ein JSON-Objekt pro Zeile. Ideal für Log-Aggregatoren. |
| TimeRotatingFileAppender | WriteToTimeRotatingFile |
Neue Datei bei jedem Zeitintervall (stündlich/täglich/wöchentlich/monatlich). |
| FileByFolderAppender | (direkt) | Organisiert Logs in Tages-Unterordnern (Logs/20260418/app.00.log). |
| FileBySourceAppender (neu) | WriteToFileBySource |
Quellenspezifische Unterordner mit Tages-+Größenrotation und Tages-Retention. |
| HTMLFileAppender (neu) | WriteToHTMLFile |
Eigenständige .html zum Durchsuchen im Browser mit Filterleiste, Level-Einfärbung, CSV-/JSON-Export und Live-Tail. |
Console-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| ConsoleAppender | WriteToConsole |
Plattformübergreifend mit Farben (Windows API / ANSI). Erzeugt unter Windows automatisch eine Konsole für GUI-Apps. WithUTF8Output für Docker/Unicode. |
| SimpleConsoleAppender | WriteToSimpleConsole |
Einfaches Writeln, keine Farben. Läuft überall. WithUTF8Output verfügbar. |
Remote-/Netzwerk-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| ExeWatchAppender (steckbar) | WithExeWatch(builder) |
Erstklassige Cloud-Observability via ExeWatch. Registriert sich selbst in JSON. |
| WebhookAppender (umbenannt) | WriteToWebhook |
HTTP-POST an REST-Endpunkte. Timeout, eigene Header, API-Key-Auth (Header oder Query-String). |
| ElasticSearchAppender (steckbar) | WriteToElasticSearch |
Sendet Logs an ElasticSearch 6.4+. Unterstützt Basic Auth, API Key, Bearer Token. Registriert sich selbst in JSON. |
| UDPSyslogAppender | WriteToUDPSyslog |
RFC 5424 UDP-Syslog. Lokalzeit oder UTC. |
| EMailAppender | (direkt) | SMTP (via Indy TIdSMTP). |
| NSQAppender | (direkt) | Veröffentlicht Logs in NSQ verteilter Message-Queue. |
| RedisAppender | (contrib) | Speichert Logs in Redis-Listen. |
UI-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| StringsAppender | WriteToStrings |
Hängt an jedes TStrings an (TMemo.Lines, TStringList). Plattformübergreifend. |
| VCLMemoAppender | WriteToVCLMemo |
VCL TMemo. Nur Windows. |
| VCLListBoxAppender | WriteToVCLListBox |
VCL TListBox. Nur Windows. |
| VCLListViewAppender | WriteToVCLListView |
Mehrspaltiges VCL TListView. Nur Windows. |
System-/Debug-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| OutputDebugStringAppender | WriteToOutputDebugString |
Windows OutputDebugString. |
| WindowsEventLogAppender (steckbar) | WriteToWindowsEventLog |
Windows Event Log (Anwendungen und Dienste). Registriert sich selbst in JSON. |
| MemoryAppender | WriteToMemory |
Thread-sicherer Ringpuffer. |
| CallbackAppender | WriteToCallback |
Ruft Ihren Callback pro Log-Item auf. |
Datenbank-Appender
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| FireDACAppender | WriteToFireDAC |
Datenbank-Logging via FireDAC-Stored-Procedure. |
| ADOAppender | (direkt) | Datenbank-Logging via ADO-Stored-Procedure. |
Filter / Proxy
| Appender | Builder-Methode | Beschreibung |
|---|---|---|
| FilterProxy | WriteToFilteredAppender |
Wrappt jeden Appender mit einer eigenen Filterfunktion. |
Als (direkt) markierte Appender werden via
BuildLogWriter([appender])oder.WriteToAppender(appender)genutzt.
Windows-Event-Log-Integration
Reguläre Anwendungen
Log := LoggerProBuilder
.WriteToWindowsEventLog
.WithSourceName('MyApplication')
.WithMinimumLevel(TLogType.Warning)
.Done
.Build;
Windows-Dienste
procedure TMyService.ServiceCreate(Sender: TObject);
begin
FLog := LoggerProBuilder
.WriteToWindowsEventLogForService(Self)
.Done
.WriteToFile
.WithLogsFolder('C:\ProgramData\MyService\Logs')
.Done
.Build;
end;
Log-Level
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
Delphi-Versions-Kompatibilität
| LoggerPro-Version | Minimum Delphi | Hinweise |
|---|---|---|
| 2.1.x (aktuell) | Delphi 10.2 Tokyo | Volle Kompatibilität ab 10.2+ |
| 2.0.x | Delphi 10.3 Rio | Vorherige Anleitung |
| 1.x (legacy) | Delphi 10 Seattle | Legacy-Anleitung |
Getestet auf: Delphi 13 Florence, 12 Athens, 11 Alexandria, 10.4 Sydney, 10.3 Rio.
Plattformen: Windows (32/64-Bit), Linux, macOS, Android, iOS.
Installation
Option 1: Release herunterladen (empfohlen)
- Entpacken Sie die ZIP in einen Ordner (z. B.
C:\Libraries\LoggerPro). - In Delphi: Tools > Options > Language > Delphi > Library.
- Zum Library Path für Ihre Ziel-Plattform hinzufügen:
C:\Libraries\LoggerPro(Hauptunits)C:\Libraries\LoggerPro\contrib(optional: Redis- und E-Mail-Appender)
uses LoggerPro, LoggerPro.Builder;in Ihrem Code.
Alle Releases: github.com/danieleteti/loggerpro/releases
Option 2: BOSS
BOSS ist ein Open-Source-Paketmanager für Delphi und Lazarus.
boss init # skip if you already have a boss.json
boss install github.com/danieleteti/loggerpro
BOSS lädt LoggerPro in modules/ herunter und aktualisiert den
Projekt-Suchpfad. Committen Sie boss.json und boss-lock.json;
modules/ in .gitignore aufnehmen.
Option 3: Repository klonen (nur Contributor)
git clone https://github.com/danieleteti/loggerpro.git
Fügen Sie den Root-Ordner und contrib zu Ihrem Library-Path hinzu.
Nur nutzen, wenn Sie unveröffentlichte Features testen oder beitragen
möchten; der master-Branch kann instabil sein.
Verwandte Projekte
| Projekt | Beschreibung |
|---|---|
| DMVCFramework | REST-API-Framework mit integrierter LoggerPro-Integration |
| DelphiRedisClient | Redis-Client für TLoggerProRedisAppender |
Links
- GitHub: github.com/danieleteti/loggerpro
- LoggerPro 2.0 Dokumentation: /loggerpro_2_0/
- Legacy 1.x Anleitung: /loggerpro_1_3/
- Support: Facebook-Gruppe
FAQ
Was ist neu in LoggerPro 2.1?
JSON-Konfiguration (LoggerProFromJSONFile), ein eigenständiger
HTML-Log-Viewer, eine erstklassige
ExeWatch-Cloud-Observability-Integration,
ein spezifikationskonformer LogFmt-Renderer, ein
FileBySource-Appender für mandantenspezifische Logs,
UTF-8-Konsolenausgabe für Docker, DLL-sichere Initialisierung,
ElasticSearch-Authentifizierung (Basic/APIKey/Bearer),
UDP-Syslog-Lokalzeit und eine GetCurrentLogFileName-API auf
File-Appendern.
Ist LoggerPro 2.1 rückwärtskompatibel zu 2.0?
Ja, es ist ein Drop-in-Upgrade. Keine Code-Änderungen nötig. Alle
2.0-Builder-Methoden und alle 1.x-BuildLogWriter-Patterns funktionieren
weiterhin.
Wie gebe ich LogFmt aus?
Renderer einstecken: .WriteToConsole.WithRenderer(TLogItemRendererLogFmt.Create).Done.
Siehe Abschnitt LogFmt-Ausgabe.
Wie frage ich LogFmt-Logs unter Windows ab?
Installieren Sie ripgrep (einzelne .exe, winget install BurntSushi.ripgrep.MSVC)
für schnelle Regex-Filterung oder humanlog für farbige Pretty-Print-
Ausgabe. Kombinieren Sie mit Get-Content -Wait für Live-Tailing. Siehe
Abschnitt LogFmt-Logs unter Windows abfragen.
Kann LoggerPro in einer DLL genutzt werden?
Ja, 2.1 erkennt den DLL-Kontext und vermeidet den Windows-Loader-Lock-
Deadlock. Rufen Sie Shutdown vor dem Entladen der DLL auf.
Wie erhalte ich korrekte UTF-8-Ausgabe in Docker?
Nutzen Sie .WriteToConsole.WithUTF8Output.Done. Schreibt UTF-8-Bytes
direkt nach stdout und umgeht Delphis Locale-Konvertierung.
Wie füge ich Logs Kontext hinzu?
Nutzen Sie Log.WithProperty('key', value).Info('msg') für Ad-hoc-
Kontext oder Log.WithDefaultContext([...]) für persistenten Kontext.
Oder übergeben Sie strukturierten Kontext inline:
Log.Info('msg', 'tag', [LogParam.I('id', 42)]).
Sollte ich Shutdown aufrufen?
Ja, rufen Sie Log.Shutdown in der Finalization Ihrer Anwendung auf.
Er ist idempotent und stellt sicher, dass ausstehende Logs vor dem
Beenden geschrieben werden. Besonders wichtig innerhalb von DLLs,
Windows-Diensten und containerisierten Apps mit kurzer Lebensdauer.
Unterstützt LoggerPro asynchrones Logging?
Ja - jeder Appender läuft auf einem eigenen Hintergrund-Thread. Log- Aufrufe kehren sofort zurück; ein Logger-Thread verteilt Items an die Queue jedes Appenders.
Welche Appender haben native Builder-Unterstützung?
File, JSONL File, Time Rotating File, FileBySource (neu), Console,
Simple Console, OutputDebugString, HTTP, ElasticSearch, UDP-Syslog,
FireDAC, Memory, Callback, Strings, VCL (Memo, ListBox, ListView),
Windows Event Log. Redis, E-Mail, NSQ werden via .WriteToAppender()
ergänzt.
Kann ich Logs zur Laufzeit per Level filtern?
Ja, entweder global per .WithMinimumLevel() zur Build-Zeit oder
dynamisch per Log.MinimumLevel := TLogType.Fatal;.
Wie logge ich aus einem Windows-Dienst in das Windows Event Log?
FLog := LoggerProBuilder
.WriteToWindowsEventLogForService(Self).Done
.Build;
Übergeben Sie die TService-Instanz - LoggerPro nutzt
TService.LogMessage für korrektes Dienst-Modus-Logging.
Welche Delphi-Versionen werden unterstützt?
2.1 unterstützt Delphi 10.2 Tokyo und neuer (bis Delphi 13 Florence). Linux, macOS, Android und iOS werden vollständig unterstützt.
LoggerPro 2.1 ist das moderne asynchrone Logging-Framework für Delphi / Object Pascal - Builder-Pattern-API, strukturiertes Kontext-Logging, spezifikationskonformer LogFmt-Renderer für Grafana Loki, mandantenspezifischer FileBySource-Appender, UTF-8-Konsolenausgabe für Docker, DLL-sichere Initialisierung, ElasticSearch / UDP-Syslog / Windows Event Log-Appender. Das Delphi-Äquivalent zu Serilog. Thread-sicher, plattformübergreifend (Windows / Linux / macOS / Android / iOS), Apache-2.0-lizenziert, aktiv gepflegt seit 2010.
Comments
comments powered by Disqus