CodeGym /Các khóa học /SQL SELF /Tạo bảng error_log để tự động ghi log lỗi

Tạo bảng error_log để tự động ghi log lỗi

SQL SELF
Mức độ, Bài học
Có sẵn

Hãy tưởng tượng bạn đang làm việc với database, xử lý cả đống transaction, nhưng tự nhiên có gì đó không ổn. Người dùng than phiền, business la hét, còn bạn thì chẳng biết chính xác chuyện gì vừa xảy ra. Đó là lúc log lỗi chuẩn phát huy tác dụng. Nó giúp bạn:

  • Lưu lỗi vào database để sau này phân tích.
  • Dễ dàng lấy lại chi tiết lỗi: thời điểm xảy ra, message và dữ liệu liên quan.
  • Cải thiện code của bạn bằng cách xử lý các lỗi phổ biến mà bạn phát hiện khi phân tích log.

Nói ngắn gọn, log lỗi giống như camera giám sát cho database của bạn: bạn thấy hết mọi thứ sai sót và thời điểm nó xảy ra.

Tạo bảng error_log

Bắt đầu từ nền móng nhé. Ta cần tạo một bảng để lưu thông tin về lỗi. Bảng này sẽ có các trường sau:

  • id — mã định danh duy nhất của lỗi.
  • error_message — nội dung lỗi.
  • error_time — thời điểm lỗi xảy ra.
  • (Tùy chọn) context — ngữ cảnh lỗi, nếu bạn muốn lưu chi tiết hơn.
CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,        -- Mã định danh duy nhất của lỗi
    error_message TEXT NOT NULL,  -- Nội dung lỗi dạng text
    error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- Thời điểm lỗi xảy ra
    context JSONB                 -- Dữ liệu bổ sung về lỗi
);

Ở đây có gì?

  • id SERIAL PRIMARY KEY — trường này tự động tạo mã định danh duy nhất cho mỗi bản ghi.
  • error_message TEXT NOT NULL — nơi lưu nội dung lỗi. Trường này bắt buộc phải có.
  • error_time TIMESTAMP NOT NULL DEFAULT NOW() — trường lưu thời điểm xảy ra lỗi. Nếu bạn không truyền giá trị, nó sẽ tự động lấy thời gian hiện tại nhờ DEFAULT NOW().
  • context JSONB — tuỳ chọn, để lưu thông tin bổ sung, ví dụ dữ liệu về thao tác gây ra lỗi.

Sau khi chạy lệnh CREATE TABLE, database của bạn sẽ có cấu trúc để lưu log lỗi.

Ví dụ ghi lỗi vào bảng

Bây giờ bảng đã có, ta chuyển sang phần thực hành: lưu thông tin lỗi vào bảng. Ta sẽ viết một function để ghi nội dung lỗi và thời điểm vào error_log.

Ví dụ function ghi lỗi

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 — tham số đầu vào, truyền nội dung lỗi.
  2. p_context — tham số tuỳ chọn để truyền dữ liệu bổ sung. Mặc định là NULL.
  3. INSERT INTO error_log (error_message, context) — thêm bản ghi mới vào bảng error_log.
  4. DEFAULT NULL — nếu không truyền context, trường này sẽ là NULL.

Bây giờ, nếu muốn ghi một lỗi, bạn chỉ cần gọi function như sau:

SELECT log_error('Lỗi khi thực hiện truy vấn', '{"query": "SELECT * FROM data"}');

Lệnh này sẽ thêm một bản ghi mới vào bảng error_log.

Tự động log lỗi

Việc mỗi lần đều phải SELECT log_error(...) bằng tay thì hơi phiền. Hãy tự động hoá quá trình này bằng cách dùng exception handling.

Ví dụ function có xử lý exception.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    -- Thử thực hiện phép chia
    result := a / b;

    -- Trả về kết quả
    RETURN result;
EXCEPTION
    WHEN division_by_zero THEN
        -- Ghi log lỗi và truyền context
        PERFORM log_error('Chia cho số 0', jsonb_build_object('a', a, 'b', b));
        -- Thông báo lỗi cho người dùng
        RAISE EXCEPTION 'Không thể chia % cho % — mẫu số bằng 0', a, b;
END;
$$ LANGUAGE plpgsql;
  1. Kiểm tra phép chia: thực hiện result := a / b. Nếu b = 0, PostgreSQL sẽ ném exception division_by_zero.
  2. Exception handler (EXCEPTION) sẽ bắt lỗi này.
  3. Bên trong handler, ta gọi function log_error để ghi lỗi vào bảng cùng với tham số gây ra lỗi.
  4. Sau khi ghi log, dùng RAISE EXCEPTION để báo lỗi cho người dùng luôn.

Ví dụ gọi:

SELECT divide_numbers(10, 0);

Kết quả:

  • Người dùng sẽ thấy lỗi: Không thể chia 10 cho 0 — mẫu số bằng 0.
  • Bảng error_log sẽ có bản ghi về lỗi chia cho số 0.
2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Chèn bản ghi lỗi vào bảng `error_log`
Chèn bản ghi lỗi vào bảng `error_log`
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION