CodeGym /Kurslar /SQL SELF /Funksiyalar vasitəsilə avtomatik loglama

Funksiyalar vasitəsilə avtomatik loglama

SQL SELF
Səviyyə , Dərs
Mövcuddur

Təsəvvür elə ki, botunu database-də sərbəst buraxmısan ki, orda çətin əməliyyatlar aparsın. Tez ya gec o, nəyisə səhv edəcək, ilişəcək və ya gözlənilməz bir vəziyyətlə qarşılaşacaq. Loglama olmadan o, sadəcə susacaq və sən başa düşməyəcəksən ki, nə baş verdi. Avtomatik loglama sənə kömək edir:

  • Error və warning-lərin baş verməsini izləməyə.
  • Problem və nasazlıqların səbəbini və təbiətini anlamağa.
  • Kodun diaqnostikasını və performansını yaxşılaşdırmağa.

Avtomatik loglama ilə sən database-də baş verənləri qeyd edən "qara qutu" yaradırsan və error-ları tapmaqda özünü birinci dərəcəli detektiv kimi hiss edirsən.

Funksiyalar vasitəsilə avtomatik loglamanın yaradılması

  1. Loglar üçün cədvəl təyin edirik

Error-ları loglamaq üçün onları saxlamaq üçün yer lazımdır. Biz artıq əvvəlki mühazirədə error_log cədvəlini yaratmışdıq:

CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,                 -- Qeyd üçün unikal identifikator
    error_message TEXT NOT NULL,          -- Error mesajı
    error_time TIMESTAMP DEFAULT NOW(),   -- Error-un baş vermə vaxtı
    function_name TEXT                    -- Error-u çağıran funksiyanın adı
);

Bu cədvəldə error yazmaq üçün lazım olan hər şey var: error-un mətni, vaxtı və hansı funksiyadan gəldiyi.

  1. Log yazmaq üçün funksiya yaradırıq

Növbəti addım — universal funksiya yaratmaqdır ki, error-ları error_log cədvəlinə yazsın. Bu funksiya istədiyimiz vaxt error-u qeyd etmək üçün çağırılacaq.

CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_function_name TEXT)
RETURNS VOID AS $$
BEGIN
    INSERT INTO error_log (error_message, function_name)
    VALUES (p_error_message, p_function_name);
    -- Uğurlu loglama barədə mesaj
    RAISE NOTICE 'Error logged: %', p_error_message;
END;
$$ LANGUAGE plpgsql;

Bu kodu izah edək:

  1. p_error_messagep_function_name — funksiyanın parametrləridir, error mesajını və çağıran funksiyanın adını qəbul edir.
  2. INSERT INTO error_log cədvələ qeyd əlavə edir.
  3. RAISE NOTICE konsolda mesaj çıxarır ki, developer loglama prosesindən xəbərdar olsun.

İndi birinci tapşırığın həllini tapdıq: error-ları cədvələ minimal səylə yaza bilirik.

log_error funksiyasının real tapşırıqlarda istifadəsi

Nümunə 1: Sıfıra bölmə zamanı error-un loglanması

Bir funksiya yaradaq ki, sadə bölmə aparır, amma əgər məxrəc 0-dırsa, error-u loglayır.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    IF b = 0 THEN
        -- Loglama funksiyasını çağırırıq
        PERFORM log_error('Sıfıra bölmə cəhdi!', 'divide_numbers');
        -- Exception yaradırıq
        RAISE EXCEPTION 'Sıfıra bölmək olmaz.';
    END IF;

    -- Bölməni icra edirik
    result := a / b;
    RETURN result;
END;
$$ LANGUAGE plpgsql;
  • Əgər məxrəc 0-dırsa, log_error funksiyası çağırılır və error cədvələ yazılır.
  • Error yazıldıqdan sonra RAISE EXCEPTION ilə istifadəçiyə bildiriş gedir.

Çağırış nümunəsi:

SELECT divide_numbers(10, 0);

Nəticə:

  • Bu funksiyanı sıfıra bölmə ilə çağıranda error error_log cədvəlinə yazılacaq.
  • İstifadəçi konsolda error mesajı görəcək.

Nümunə 2: Yanlış məlumat əlavə edəndə loglama

Bir funksiya nümunəsinə baxaq ki, yeni tələbəni students cədvəlinə əlavə edir. Əgər tələbənin adı boşdursa, hadisəni loglayırıq və icranı dayandırırıq.

CREATE OR REPLACE FUNCTION add_student(p_name TEXT)
RETURNS VOID AS $$
BEGIN
    IF p_name IS NULL OR p_name = '' THEN
        PERFORM log_error('Tələbə adı daxil edilməlidir!', 'add_student');
        RAISE EXCEPTION 'Tələbə adı boş ola bilməz.';
    END IF;

    INSERT INTO students (name) VALUES (p_name);
END;
$$ LANGUAGE plpgsql;

Çağırış nümunəsi:

SELECT add_student('');

Əgər tələbəni ad olmadan əlavə etməyə çalışsaq, funksiya error_log-da uyğun mesajla qeyd yaradacaq.

Nümunə 3: Warning-lərin loglanması

Həmişə istifadəçiyə exception göstərmək lazım deyil. Bəzən sadəcə warning qeyd etmək kifayətdir. Tələbənin yaşını yoxlayan funksiya düzəldək:

CREATE OR REPLACE FUNCTION check_age(p_age INT)
RETURNS VOID AS $$
BEGIN
    IF p_age < 18 THEN
        -- Warning loglayırıq, amma icranı dayandırmırıq
        PERFORM log_error('Tələbənin yaşı 18-dən aşağıdır.', 'check_age');
        RAISE NOTICE 'Diqqət: Tələbənin yaşı 18-dən aşağıdır.';
    END IF;

    RAISE NOTICE 'Yaş yoxlaması keçdi.';
END;
$$ LANGUAGE plpgsql;

Çağırış nümunəsi:

SELECT check_age(16);

Nəticə:

  • Warning error_log cədvəlinə yazılır.
  • Konsolda tələbənin yaşının 18-dən az olduğu barədə bildiriş çıxır.

Loglama və exception-ların işlənməsi

Gəlin error yazma və exception işləməyi bir az daha mürəkkəb funksiyada birləşdirək. Təsəvvür elə ki, grades cədvəlində tələbələrin qiymətlərini yenidən hesablamaq tapşırığımız var. Əgər proses hansısa tələbə üçün icra olunmasa, error loglanır, amma əməliyyat davam edir.

CREATE OR REPLACE FUNCTION recalculate_grades()
RETURNS VOID AS $$
DECLARE
    student RECORD;
BEGIN
    FOR student IN SELECT * FROM students LOOP
        BEGIN
            -- Tapşırıq nümunəsi: tələbənin qiymətlərini yeniləmək
            UPDATE grades SET final_grade = final_grade + 1
            WHERE student_id = student.id;

            RAISE NOTICE 'Tələbə üçün qiymətlər yeniləndi %', student.name;
        EXCEPTION WHEN OTHERS THEN
            -- Error-u loglayırıq və icranı davam etdiririk
            PERFORM log_error('Tələbə üçün qiymətləri yeniləmək alınmadı ' || student.name, 'recalculate_grades');
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Çağırış nümunəsi:

SELECT recalculate_grades();

Bu yanaşma funksiyanı daha dayanıqlı edir, çünki error-lar ayrıca loglanır və bütün məlumatlar üçün icra dayanmaz.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION