Logging
DuckDB implementiert einen Logging-Mechanismus, der detaillierte Informationen zu Ereignissen wie Query-Ausführung, Leistungsmetriken und Systemereignissen liefert.
Grundlagen
Der DuckDB-Logging-Mechanismus lässt sich über die spezielle Funktion enable_logging ein- oder ausschalten. Logs werden in einer speziellen View
namens duckdb_logs gespeichert, die sich wie jede normale Tabelle abfragen lässt.
Beispiel:
CALL enable_logging();-- Run some queries...SELECT * FROM duckdb_logs;Um Logging zu deaktivieren, führen Sie aus
CALL disable_logging();Um das aktuelle Log zu leeren, führen Sie aus
CALL truncate_duckdb_logs();Log-Level
DuckDB unterstützt verschiedene Log-Level, die die Ausführlichkeit der Logs steuern:
ERROR: Protokolliert nur FehlermeldungenWARN: Protokolliert Warnungen und FehlerINFO: Protokolliert allgemeine Informationen, Warnungen und Fehler (Standard)DEBUG: Protokolliert detaillierte Debugging-InformationenTRACE: Protokolliert sehr detaillierte Tracing-Informationen
Das Log-Level kann so gesetzt werden:
CALL enable_logging(level = 'debug');Log-Typen
In DuckDB können Log-Meldungen einen zugehörigen Log-Typ haben. Log-Typen ermöglichen zwei Dinge:
- Feingranulare Steuerung der Erzeugung von Log-Meldungen
- Unterstützung für strukturiertes Logging
Bestimmte Typen loggen
Um nur Meldungen eines bestimmten Typs zu loggen:
CALL enable_logging('HTTP');Die obige Funktion setzt automatisch das passende Log-Level und fügt den Typ HTTP zu den Einstellungen enabled_log_types hinzu. So werden
nur Log-Meldungen vom Typ ‘HTTP’ ins Log geschrieben.
Um mehrere Log-Typen zu aktivieren, übergeben Sie einfach:
CALL enable_logging(['HTTP', 'QueryLog']);Strukturiertes Logging
Einige Log-Typen wie HTTP haben ein zugehöriges Nachrichten-Schema. Damit DuckDB die Nachricht automatisch parst, verwenden Sie das Makro duckdb_logs_parsed(). Beispiel:
SELECT request.headers FROM duckdb_logs_parsed('HTTP');Um das Schema jedes strukturierten Log-Typs anzuzeigen, führen Sie einfach aus:
DESCRIBE FROM duckdb_logs_parsed('HTTP');Liste der verfügbaren Log-Typen
Dies ist eine (nicht vollständige) Liste der in DuckDB verfügbaren Log-Typen.
| Log-Typ | Beschreibung | Strukturiert |
|---|---|---|
QueryLog |
Protokolliert, welche Queries in DuckDB ausgeführt werden | Nein |
FileSystem |
Protokolliert alle FileSystem-Interaktionen mit DuckDBs Filesystem | Ja |
HTTP |
Protokolliert den gesamten HTTP-Verkehr des internen HTTP-Clients von DuckDB | Ja |
PhysicalOperator |
Protokolliert Ereignisse physischer Operatoren während der Query-Ausführung | Ja |
Metrics |
Protokolliert Profiling-Metriken, die während der Query-Ausführung erfasst werden | Ja |
Die strukturierten Log-Typen stellen die folgenden Schemas bereit, die Sie jederzeit mit
DESCRIBE FROM duckdb_logs_parsed(⟨log_type⟩){:.language-sql .highlight} einsehen können:
| Log-Typ | Schema |
|---|---|
FileSystem |
fs VARCHAR, path VARCHAR, op VARCHAR, bytes BIGINT, pos BIGINT |
HTTP |
request STRUCT(type, url, start_time, duration_ms, headers MAP), response STRUCT(status, reason, headers MAP) |
PhysicalOperator |
operator_type VARCHAR, parameters MAP(VARCHAR, VARCHAR), class VARCHAR, event VARCHAR, info MAP(VARCHAR, VARCHAR) |
Metrics |
metric VARCHAR, value VARCHAR |
Log-Speicher
Standardmäßig loggt DuckDB in einen In-Memory-Log-Speicher (memory). DuckDB unterstützt verschiedene Arten von Log-Speicher. Derzeit
sind die folgenden Log-Speichertypen im DuckDB-Kern implementiert.
| Log-Speicher | Beschreibung |
|---|---|
memory |
(Standard) In einen In-Memory-Puffer loggen |
stdout |
Auf die stdout des aktuellen Prozesses loggen (im CSV-Format) |
file |
In eine oder mehrere CSV-Dateien loggen |
Beachten Sie, dass die View duckdb_logs automatisch auf den aktuell aktiven Log-Speicher zeigt. Das Umschalten
des Log-Speichers kann daher beeinflussen, was die Funktion duckdb_logs zurückgibt.
Logging nach stdout
CALL enable_logging(storage = 'stdout');Logging in eine Datei
CALL enable_logging(storage = 'file', storage_config = {'path': 'path/to/store/logs'});oder mit der gleichwertigen Kurzform:
CALL enable_logging(storage_path = 'path/to/store/logs');Fortgeschrittene Nutzung
Normalisiertes vs. denormalisiertes Logging
Die Log-Speicher von DuckDB können auf zwei Arten loggen: normalisiert oder denormalisiert.
Beim denormalisierten Logging werden die Kontextinformationen direkt an jeden Log-Eintrag angehängt, beim normalisierten Logging werden die Log-Einträge getrennt gespeichert und verweisen über context_ids auf die Kontextinformationen.
| Log-Speicher | Normalisiert |
|---|---|
memory |
ja |
file |
konfigurierbar |
stdout |
nein |
Für den Dateispeicher können Sie zwischen normalisiert und denormalisiert wechseln, indem Sie einen Pfad angeben, der auf .csv endet (normalisiert)
oder ohne .csv (denormalisiert). Für Datei-Logging ist Denormalisierung in der Regel empfehlenswert, weil das die Leistung steigert
und die Gesamtgröße der Logs verringert. Normalisierung des file-Log-Speichers konfigurieren:
-- normalized: creates `/tmp/duckdb_log_contexts.csv` and `/tmp/duckdb_log_entries.csv`CALL enable_logging(storage_path = '/tmp');-- denormalized: creates `/tmp/logs.csv`CALL enable_logging(storage_path = '/tmp/logs.csv');Beachten Sie, dass der Unterschied zwischen normalisiert und denormalisiert für Benutzer typischerweise hinter der Funktion duckdb_logs verborgen bleibt,
die normalisierte Tabellen automatisch zu einem einheitlichen Ergebnis zusammenführt. Zur Veranschaulichung: Beide Konfigurationen oben sind
mit FROM duckdb_logs; abfragbar und liefern identische Ergebnisse.
Puffergröße
Der Log-Speicher in DuckDB implementiert einen Puffermechanismus, um die Logging-Leistung zu optimieren. Diese Implementierung führt zu einer möglichen Verzögerung zwischen dem Loggen einer Meldung und dem Schreiben in den Speicher. Diese Verzögerung kann den tatsächlichen Schreibzeitpunkt der Meldung verschleiern, was besonders beim Debuggen von Abstürzen problematisch ist, weil unmittelbar vor einem Absturz erzeugte Meldungen möglicherweise nicht geschrieben werden. Um das zu adressieren, kann die Puffergröße wie folgt konfiguriert werden:
CALL enable_logging(storage_config = {'buffer_size': 0});oder mit der gleichwertigen Kurzform:
CALL enable_logging(storage_buffer_size = 0);Beachten Sie, dass die Standard-Puffergröße je nach Log-Speicher unterschiedlich ist:
| Log-Speicher | Standard-Puffergröße |
|---|---|
memory |
STANDARD_VECTOR_SIZE (2048) |
file |
STANDARD_VECTOR_SIZE (2048) |
stdout |
Deaktiviert (0) |
Wenn Sie beispielsweise die stdout-Logging-Leistung steigern möchten, aktivieren Sie einfach Pufferung, um das Logging deutlich (>10×) zu
beschleunigen:
CALL enable_logging(storage = 'stdout', storage_buffer_size = 2048);Oder stellen Sie sich vor, Sie debuggen einen Absturz in DuckDB und möchten den file-Logger nutzen, um zu verstehen, was passiert.
Deaktivieren Sie einfach die Pufferung mit:
CALL enable_logging(storage_path = '/tmp/mylogs', storage_buffer_size = 0);Syntaktischer Zucker
DuckDB bietet etwas syntaktischen Zucker, um gängige Pfade zu vereinfachen. Die folgenden Anweisungen sind beispielsweise alle gleichwertig:
-- regular invocationCALL enable_logging(storage = 'file', storage_config = {'path': 'path/to/store/logs'});-- using shorthand for common path storage config paramCALL enable_logging(storage = 'file', storage_path = 'path/to/store/logs');-- omitting `storage = 'file'` -> is implied from presence of `storage_config`CALL enable_logging(storage_config = {'path': 'path/to/store/logs'});