Stell dir vor, du arbeitest mit einer Datenbank, bearbeitest jede Menge Transaktionen, aber irgendwas läuft schief. Der User meckert, das Business schreit und du hast keinen Plan, was genau passiert ist. Genau hier kommt richtiges Fehler-Logging ins Spiel. Das hilft dir dabei:
- Fehler in der Datenbank zu speichern, damit du sie später analysieren kannst.
- Fehlerdetails easy wiederherzustellen: wann ist der Fehler passiert, was war die Message und welche Daten waren betroffen.
- Deinen Code zu verbessern, indem du typische Fehler findest, die du beim Log-Check entdeckst.
Kurz gesagt: Logging ist wie die Überwachungskamera für deine Datenbank – du siehst alles, was schiefgelaufen ist und wann es passiert ist.
Wir erstellen die Tabelle error_log
Lass uns mal mit dem Fundament starten. Wir brauchen eine Tabelle, in der wir Infos zu Fehlern speichern. Die Tabelle hat folgende Felder:
id— eindeutige Fehler-ID.error_message— Fehlertext.error_time— Zeitpunkt, wann der Fehler aufgetreten ist.- (Optional)
context— Fehlerkontext, falls du Details speichern willst.
CREATE TABLE error_log (
id SERIAL PRIMARY KEY, -- Eindeutige Fehler-ID
error_message TEXT NOT NULL, -- Fehlertext
error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- Zeitpunkt des Fehlers
context JSONB -- Zusätzliche Fehlerdaten
);
Was passiert hier?
id SERIAL PRIMARY KEY— dieses Feld erzeugt automatisch eine eindeutige ID für jeden Eintrag.error_message TEXT NOT NULL— hier landet der Fehlertext. Das Feld muss ausgefüllt werden.error_time TIMESTAMP NOT NULL DEFAULT NOW()— dieses Feld speichert den Zeitpunkt des Fehlers. Wenn du keinen Wert angibst, wird automatisch die aktuelle Zeit mitDEFAULT NOW()eingetragen.context JSONB— optional, um zusätzliche Infos zu speichern, z.B. Daten zur Operation, bei der der Fehler aufgetreten ist.
Nach dem Ausführen von CREATE TABLE hast du die Struktur zum Speichern deiner Logs in der Datenbank.
Beispiel: Fehler in die Tabelle schreiben
Jetzt, wo die Tabelle steht, geht's ans Praktische: Wir speichern Fehlerinfos in die Tabelle. Wir schreiben eine Funktion, die den Fehlertext und die Zeit in error_log einträgt.
Beispiel für eine Fehler-Logging-Funktion
CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_context JSONB DEFAULT NULL)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, context)
VALUES (p_error_message, p_context);
END;
$$ LANGUAGE plpgsql;
p_error_message— Eingabeparameter, hier kommt der Fehlertext rein.p_context— optionaler Parameter für zusätzliche Daten. Standardmäßig ist dasNULL.INSERT INTO error_log (error_message, context)— fügt einen neuen Eintrag in dieerror_log-Tabelle ein.DEFAULT NULL— wenn kein Kontext übergeben wird, bleibt das FeldNULL.
Wenn du jetzt eine Fehlermeldung speichern willst, kannst du die Funktion so aufrufen:
SELECT log_error('Fehler beim Ausführen der Anfrage', '{"query": "SELECT * FROM data"}');
Das fügt einen neuen Eintrag in die error_log-Tabelle ein.
Automatisches Fehler-Logging
Jedes Mal SELECT log_error(...) von Hand zu schreiben, ist nervig. Lass uns das mit Exception-Handling automatisieren.
Beispiel für eine Funktion mit Exception-Handling.
CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
result NUMERIC;
BEGIN
-- Wir versuchen zu dividieren
result := a / b;
-- Ergebnis zurückgeben
RETURN result;
EXCEPTION
WHEN division_by_zero THEN
-- Fehler loggen und Kontext übergeben
PERFORM log_error('Division durch Null', jsonb_build_object('a', a, 'b', b));
-- Exception für den User werfen
RAISE EXCEPTION 'Division % durch % nicht möglich — Divisor ist Null', a, b;
END;
$$ LANGUAGE plpgsql;
- Divisions-Check:
result := a / bwird ausgeführt. Wennb = 0, wirft PostgreSQL die Exceptiondivision_by_zero. - Exception-Handler (
EXCEPTION) fängt den Fehler ab. - Im Handler rufen wir
log_errorauf, um den Fehler samt Parametern in die Tabelle zu schreiben. - Nach dem Logging wird mit
RAISE EXCEPTIONeine neue Fehlermeldung geworfen, damit der User auch Bescheid weiß.
Beispielaufruf:
SELECT divide_numbers(10, 0);
Ergebnis:
- Der User sieht den Fehler:
Division 10 durch 0 nicht möglich — Divisor ist Null. - In der
error_log-Tabelle steht jetzt ein Eintrag zur Division durch Null.
GO TO FULL VERSION