CodeGym /행동 /SQL SELF /PostgreSQL에서 에러 자동 로그를 위한 error_log 테이블 만들기

PostgreSQL에서 에러 자동 로그를 위한 error_log 테이블 만들기

SQL SELF
레벨 52 , 레슨 2
사용 가능

상상해봐, DB에서 트랜잭션 엄청 돌리고 있는데 뭔가 꼬였어. 유저는 불평하고, 비즈니스 쪽은 난리치고, 근데 넌 뭐가 터졌는지 감도 안 와. 이럴 때 제대로 된 에러 로그가 필요하지. 에러 로그가 있으면:

  • 에러를 DB에 저장해서 나중에 분석할 수 있어.
  • 에러가 언제, 무슨 메시지로, 어떤 데이터랑 같이 났는지 쉽게 복구 가능.
  • 로그 분석하면서 자주 나오는 에러를 잡아서 코드 퀄리티도 올릴 수 있어.

한마디로, 로그 남기는 건 DB에 CCTV 다는 거랑 똑같아. 뭐가 언제 잘못됐는지 다 볼 수 있지.

error_log 테이블 만들기

일단 기본부터 가자. 에러 정보를 저장할 테이블을 만들어야 해. 테이블에는 이런 필드가 들어가:

  • id — 에러의 유니크한 아이디.
  • error_message — 에러 메시지 텍스트.
  • error_time — 에러가 발생한 시간.
  • (옵션) context — 에러에 대한 추가 정보가 필요하면 여기에 저장.
CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,        -- 에러의 유니크한 아이디
    error_message TEXT NOT NULL,  -- 에러 메시지 텍스트
    error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- 에러 발생 시간
    context JSONB                 -- 에러에 대한 추가 데이터
);

여기서 뭐가 어떻게 돌아가는지 설명할게:

  • id SERIAL PRIMARY KEY — 이 필드는 각 레코드마다 자동으로 유니크한 아이디를 만들어줘.
  • error_message TEXT NOT NULL — 에러 메시지 텍스트가 들어가. 필수 입력이야.
  • error_time TIMESTAMP NOT NULL DEFAULT NOW() — 에러가 언제 났는지 기록. 값 안 넣으면 DEFAULT NOW() 덕분에 자동으로 현재 시간이 들어가.
  • context JSONB — 옵션 필드로, 에러가 난 작업에 대한 추가 정보 같은 걸 저장할 수 있어.

CREATE TABLE 명령 실행하면 DB에 로그 저장용 구조가 생기는 거야.

에러를 테이블에 기록하는 예시

이제 테이블 만들었으니까, 실전으로 에러 정보를 테이블에 저장해보자. 에러 메시지랑 시간 같은 걸 error_log에 넣는 함수를 만들어볼 거야.

에러 기록용 함수 예시

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 — 에러 메시지 텍스트를 받는 파라미터야.
  2. p_context — 추가 데이터 넘길 때 쓰는 옵션 파라미터. 기본값은 NULL이야.
  3. INSERT INTO error_log (error_message, context)error_log 테이블에 새 레코드 추가.
  4. DEFAULT NULL — context 안 넘기면 NULL로 들어가.

이제 에러 메시지 남기고 싶으면 이렇게 함수 호출하면 돼:

SELECT log_error('쿼리 실행 중 에러', '{"query": "SELECT * FROM data"}');

이러면 error_log 테이블에 새 레코드가 추가돼.

에러 자동 로그 남기기

매번 SELECT log_error(...) 직접 쓰는 건 귀찮잖아. 예외 처리로 이걸 자동화해보자.

예외 처리 들어간 함수 예시.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    -- 나눗셈 시도
    result := a / b;

    -- 결과 리턴
    RETURN result;
EXCEPTION
    WHEN division_by_zero THEN
        -- 에러 로그 남기고 context 전달
        PERFORM log_error('0으로 나누기', jsonb_build_object('a', a, 'b', b));
        -- 사용자에게 에러 메시지 던지기
        RAISE EXCEPTION '숫자 %를 %로 나눌 수 없어 — 나누는 값이 0이야', a, b;
END;
$$ LANGUAGE plpgsql;
  1. 나눗셈 체크: result := a / b 실행. b = 0이면 PostgreSQL이 division_by_zero 예외를 던져.
  2. 예외 핸들러 (EXCEPTION)가 에러를 잡아.
  3. 핸들러 안에서 log_error 함수 호출해서 에러랑 파라미터를 로그에 남겨.
  4. 로그 남긴 뒤 RAISE EXCEPTION으로 사용자한테도 에러 메시지 보여줘.

호출 예시:

SELECT divide_numbers(10, 0);

결과:

  • 사용자는 에러 메시지: 숫자 10를 0로 나눌 수 없어 — 나누는 값이 0이야를 보게 돼.
  • error_log 테이블에는 0으로 나누기 에러가 기록돼.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION