CodeGym /행동 /SQL SELF /함수를 통한 자동 로그 기록

함수를 통한 자동 로그 기록

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

상상해봐, 네가 만든 봇이 데이터베이스에서 복잡한 작업을 하려고 혼자 돌아다니고 있어. 언젠가는 분명히 뭔가에 걸려서 에러가 나거나, 예상 못 한 상황을 만날 거야. 로그가 없으면 봇은 그냥 조용히 멈추고, 넌 도대체 뭐가 잘못됐는지 감도 못 잡을 수도 있어. 자동 로그 기록은 이런 데서 도움이 돼:

  • 에러나 경고가 언제 발생했는지 추적할 수 있어.
  • 문제의 원인과 이유를 파악할 수 있어.
  • 코드 진단이나 성능 개선에도 도움돼.

자동 로그 기록을 쓰면, 데이터베이스에서 일어나는 사건들을 다 기록하는 "블랙박스"를 만드는 거야. 이걸로 에러를 추적할 수 있어서, 마치 명탐정처럼 문제를 찾을 수 있지.

함수를 이용한 자동 로그 기록 만들기

  1. 로그용 테이블 정의하기

에러를 기록하려면, 저장할 공간이 필요하지. 지난 강의에서 error_log 테이블을 이미 만들었어:

CREATE TABLE error_log (
    id SERIAL PRIMARY KEY,                 -- 레코드의 고유 식별자
    error_message TEXT NOT NULL,          -- 에러 메시지
    error_time TIMESTAMP DEFAULT NOW(),   -- 에러 발생 시간
    function_name TEXT                    -- 에러를 발생시킨 함수 이름
);

이 테이블엔 에러 기록에 필요한 것들이 다 있어: 에러 메시지, 발생 시간, 그리고 어디서 에러가 났는지 함수 이름까지.

  1. 로그 기록용 함수 만들기

다음 단계는, error_log 테이블에 에러를 기록하는 범용 함수를 만드는 거야. 이 함수는 에러를 남기고 싶을 때마다 호출하면 돼.

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);
    -- 로그 기록 성공 메시지
    RAISE NOTICE '에러가 기록됨: %', p_error_message;
END;
$$ LANGUAGE plpgsql;

이 코드 설명해줄게:

  1. p_error_messagep_function_name은 함수 파라미터로, 에러 메시지랑 호출한 함수 이름을 받아.
  2. INSERT INTO error_log가 테이블에 레코드를 추가해.
  3. RAISE NOTICE는 콘솔에 메시지를 띄워서, 개발자가 로그 기록 과정을 바로 알 수 있게 해줘.

이제 첫 번째 미션은 해결! 최소한의 노력으로 에러를 테이블에 기록할 수 있게 됐어.

실전에서 log_error 함수 쓰기

예시 1: 0으로 나눌 때 에러 로그 남기기

간단한 나눗셈을 하는 함수를 만들어볼게. 만약 분모가 0이면 에러를 로그로 남겨.

CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    result NUMERIC;
BEGIN
    IF b = 0 THEN
        -- 로그 기록 함수 호출
        PERFORM log_error('0으로 나누려고 시도함!', 'divide_numbers');
        -- 예외 발생
        RAISE EXCEPTION '0으로 나누기는 허용되지 않아.';
    END IF;

    -- 나눗셈 실행
    result := a / b;
    RETURN result;
END;
$$ LANGUAGE plpgsql;
  • 분모가 0이면 log_error 함수가 호출돼서 에러가 테이블에 기록돼.
  • 에러 기록 후 RAISE EXCEPTION으로 사용자에게 에러 메시지를 보여줘.

호출 예시:

SELECT divide_numbers(10, 0);

결과:

  • 0으로 나누는 이 함수를 호출하면 error_log 테이블에 에러가 기록돼.
  • 사용자는 콘솔에서 에러 메시지를 볼 수 있어.

예시 2: 잘못된 데이터 삽입 시 로그 남기기

이번엔 students 테이블에 새 학생을 추가하는 함수를 만들어볼게. 만약 학생 이름이 비어 있으면, 로그를 남기고 실행을 중단해.

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('학생 이름을 꼭 입력해야 해!', 'add_student');
        RAISE EXCEPTION '학생 이름은 비워둘 수 없어.';
    END IF;

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

호출 예시:

SELECT add_student('');

이렇게 이름 없이 학생을 추가하려고 하면, 함수가 error_log에 메시지를 남겨줄 거야.

예시 3: 경고 로그 남기기

항상 예외를 발생시킬 필요는 없어. 가끔은 경고만 남기면 충분하지. 학생 나이를 체크하는 함수를 만들어볼게:

CREATE OR REPLACE FUNCTION check_age(p_age INT)
RETURNS VOID AS $$
BEGIN
    IF p_age < 18 THEN
        -- 경고만 로그로 남기고 실행은 계속
        PERFORM log_error('학생 나이가 18세 미만이야.', 'check_age');
        RAISE NOTICE '경고: 학생 나이가 18세 미만이야.';
    END IF;

    RAISE NOTICE '나이 체크 통과.';
END;
$$ LANGUAGE plpgsql;

호출 예시:

SELECT check_age(16);

결과:

  • error_log 테이블에 경고가 기록돼.
  • 콘솔에 학생 나이가 18세 미만이라는 알림이 떠.

로그 기록과 예외 처리

이제 에러 기록과 예외 처리를 좀 더 복잡한 함수에서 합쳐볼게. 예를 들어, grades 테이블에서 학생들의 점수를 다시 계산하는 작업이 있다고 해보자. 만약 어떤 학생에서 에러가 나면, 에러는 로그로 남기고 나머지 학생들은 계속 처리해.

CREATE OR REPLACE FUNCTION recalculate_grades()
RETURNS VOID AS $$
DECLARE
    student RECORD;
BEGIN
    FOR student IN SELECT * FROM students LOOP
        BEGIN
            -- 예시 작업: 학생 점수 업데이트
            UPDATE grades SET final_grade = final_grade + 1
            WHERE student_id = student.id;

            RAISE NOTICE '학생 %의 점수를 업데이트함', student.name;
        EXCEPTION WHEN OTHERS THEN
            -- 에러를 로그로 남기고 계속 진행
            PERFORM log_error('학생 ' || student.name || '의 점수 업데이트 실패', 'recalculate_grades');
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

호출 예시:

SELECT recalculate_grades();

이런 방식이면 함수가 훨씬 튼튼해져. 에러는 따로 로그로 남기고, 전체 데이터 처리는 멈추지 않으니까.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION