CodeGym /Kursy /SQL SELF /Tworzenie tabeli error_log do automatycznego logowania bł...

Tworzenie tabeli error_log do automatycznego logowania błędów

SQL SELF
Poziom 52, Lekcja 2
Dostępny

Wyobraź sobie sytuację, gdzie pracujesz z bazą danych, obsługujesz masę transakcji, ale coś poszło nie tak. Użytkownik narzeka, biznes krzyczy, a ty nawet nie widzisz, co dokładnie się wydarzyło. Właśnie tutaj wchodzi do gry poprawne logowanie błędów. Pozwala ono na:

  • Przechowywanie błędów w bazie danych do późniejszej analizy.
  • Łatwe odzyskiwanie szczegółów błędu: kiedy się pojawił, jaka była wiadomość i powiązane dane.
  • Poprawianie swojego kodu, pracując nad typowymi błędami, które można wykryć analizując logi.

Krótko mówiąc, logowanie to jak nagranie z kamery monitoringu dla twojej bazy danych: widzisz wszystko, co poszło nie tak i kiedy to się wydarzyło.

Tworzymy tabelę error_log

Zacznijmy, jak to się mówi, od fundamentów. Musimy stworzyć tabelę, w której będziemy trzymać info o błędach. Tabela będzie miała następujące pola:

  • id — unikalny identyfikator błędu.
  • error_message — tekst błędu.
  • error_time — czas, kiedy wystąpił błąd.
  • (Opcjonalnie) context — kontekst błędu, jeśli chcemy przechowywać szczegóły.
CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,        -- Unikalny identyfikator błędu
    error_message TEXT NOT NULL,  -- Tekstowa wiadomość o błędzie
    error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- Czas wystąpienia błędu
    context JSONB                 -- Dodatkowe dane o błędzie
);

Co się tutaj dzieje?

  • id SERIAL PRIMARY KEY — to pole tworzy automatycznie unikalny identyfikator dla każdego wpisu.
  • error_message TEXT NOT NULL — tutaj będzie przechowywany tekst błędu. Pole obowiązkowe.
  • error_time TIMESTAMP NOT NULL DEFAULT NOW() — pole rejestrujące czas zdarzenia. Jeśli nie podasz wartości, automatycznie zapisze aktualny czas dzięki DEFAULT NOW().
  • context JSONB — opcjonalnie, do przechowywania dodatkowych informacji, np. danych o operacji, gdzie wystąpił błąd.

Po wykonaniu komendy CREATE TABLE w twojej bazie danych pojawi się struktura do przechowywania logów.

Przykład zapisu błędów do tabeli

Teraz, gdy tabela już jest, przejdźmy do praktyki: będziemy zapisywać info o błędach do tabeli. Napiszemy funkcję, która wrzuca tekst błędu i czas do error_log.

Przykład funkcji do zapisywania błędów

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;
  1. p_error_message — parametr wejściowy, gdzie przekazujesz tekst błędu.
  2. p_context — opcjonalny parametr do przekazania dodatkowych danych. Domyślnie przyjmuje NULL.
  3. INSERT INTO error_log (error_message, context) — dodaje nowy wpis do tabeli error_log.
  4. DEFAULT NULL — jeśli nie podasz kontekstu, pole będzie NULL.

Teraz, jeśli chcesz zapisać wiadomość o błędzie, możesz wywołać funkcję tak:

SELECT log_error('Błąd podczas wykonywania zapytania', '{"query": "SELECT * FROM data"}');

To doda nowy wpis do tabeli error_log.

Automatyczne logowanie błędów

Za każdym razem pisać SELECT log_error(...) ręcznie może być upierdliwe. Zautomatyzujmy ten proces używając obsługi wyjątków.

Przykład funkcji z obsługą wyjątków.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    -- Spróbuj wykonać dzielenie
    result := a / b;

    -- Zwróć wynik
    RETURN result;
EXCEPTION
    WHEN division_by_zero THEN
        -- Logujemy błąd i przekazujemy kontekst
        PERFORM log_error('Dzielenie przez zero', jsonb_build_object('a', a, 'b', b));
        -- Rzucamy wyjątek dla użytkownika
        RAISE EXCEPTION 'Dzielenie % przez % niemożliwe — dzielnik jest zerem', a, b;
END;
$$ LANGUAGE plpgsql;
  1. Sprawdzenie dzielenia: wykonuje się result := a / b. Jeśli b = 0, PostgreSQL rzuca wyjątek division_by_zero.
  2. Obsługa wyjątków (EXCEPTION) przechwytuje błąd.
  3. W środku obsługi wywołujemy funkcję log_error, żeby zapisać błąd do tabeli razem z parametrami, które wywołały problem.
  4. Po zapisaniu błędu przez RAISE EXCEPTION rzucamy nowe info o błędzie, żeby użytkownik też dostał powiadomienie.

Przykład wywołania:

SELECT divide_numbers(10, 0);

Wynik:

  • Użytkownik zobaczy błąd: Dzielenie 10 przez 0 niemożliwe — dzielnik jest zerem.
  • W tabeli error_log pojawi się wpis o dzieleniu przez zero.
2
Zadanie
SQL SELF, poziom 52, lekcja 2
Niedostępne
Wstawianie rekordu z błędem do tabeli `error_log`
Wstawianie rekordu z błędem do tabeli `error_log`
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION