감사 로그가 필요한 순간은 늘 사고 뒤에 옵니다
월말 정산에서 특정 거래처 단가가 지난달보다 15% 낮게 잡혀 있습니다. 재고는 장부상 1,200개인데 실사 결과는 980개입니다. 퇴사한 직원 계정에 아직 결재 권한이 남아 있습니다. 세 경우 모두 첫 질문은 같습니다. "누가, 언제 이 값을 바꿨습니까?" 이 질문에 답하지 못하는 시스템이 생각보다 많습니다.
흔한 오해는 애플리케이션 로그가 있으니 충분하다는 생각입니다. 애플리케이션 로그는 장애를 분석하려는 개발자용 기록입니다. 레벨에 따라 걸러지고, 로그 회전 정책에 따라 몇 주 만에 지워지기도 합니다. 반면 감사 로그는 업무 책임을 추적하는 기록입니다. 빠짐없이 남아야 하고, 정해진 기간 동안 보존되어야 하며, 고칠 수 없어야 합니다. 목적이 다르므로 저장소와 설계도 따로 가져가야 합니다.
무엇을 남길 것인가
변경 기록의 6요소
조회 이력의 범위
모든 조회를 남기면 저장량이 변경 기록의 수십 배로 늘어납니다. 개인정보처럼 열람 자체가 책임 대상인 데이터만 조회 이력을 남기는 것이 현실적입니다. 국내에서는 개인정보 안전성 확보조치 기준에 따라 개인정보처리시스템 접속기록을 최소 1년(정보주체 5만 명 이상 등 일부 경우 2년) 보관해야 하고, 권한 부여·변경·말소 내역은 3년 보관해야 합니다. 반면 상품 목록이나 공지사항 조회는 남길 필요가 거의 없습니다.
기록 방식 비교
| 방식 | 장점 | 한계 |
|------|------|------|
| 애플리케이션 계층 | 사용자·사유 등 업무 맥락을 담기 쉬움 | 직접 SQL이나 다른 앱의 변경은 빠짐 |
| DB 트리거 | 경로와 무관하게 모든 변경을 포착 | 앱 사용자를 모름, 쓰기 성능 부담 |
| CDC(변경 데이터 캡처) | 트랜잭션 로그를 읽어 운영 DB 부담이 적음 | 인프라 구성이 필요하고 사용자 맥락은 따로 전달해야 함 |
실무에서는 조합이 정답인 경우가 많습니다. 업무 화면의 변경은 애플리케이션 계층에서 맥락까지 담아 기록하고, 트리거나 CDC를 안전망으로 두어 우회 경로의 변경을 잡아냅니다. 트리거를 쓴다면 PostgreSQL의 `SET LOCAL` 세션 변수처럼 트랜잭션마다 앱 사용자 ID를 DB에 전달해 "DB 계정 app_user가 바꿨다"에서 끝나지 않도록 합니다.
일괄 처리를 놓치지 않는 법
단가 일괄 인상이나 재고 보정 배치는 한 번에 수만 건을 바꿉니다. ORM의 일괄 업데이트는 개별 엔티티 이벤트를 건너뛰는 경우가 많아 애플리케이션 계층 기록이 통째로 빠지기 쉽습니다. 배치마다 실행 ID를 발급해 모든 변경 행에 붙이고, 실행자·대상 조건·처리 건수를 담은 배치 단위 기록을 함께 남기면 "3월 2일 배치 #4821이 1만 2천 건을 바꿨다"까지 추적할 수 있습니다.
위변조 방지와 보존
감사 로그를 쓸 수 있게 만드는 화면
기록만 쌓이고 조회할 화면이 없으면, 사고가 날 때마다 개발자가 SQL을 짜야 합니다. 레코드 상세 화면에 "변경 이력" 탭을 두어 필드별 이전→이후 값을 시간순으로 보여주고, 사용자·기간·필드·배치 실행 ID로 검색할 수 있게 합니다. 검색이 잦은 레코드 키와 시각 컬럼에는 인덱스를 둡니다.
한 단계 더 나아가면 이상 변경 알림입니다. 단가 30% 이상 변경, 업무 시간 외 권한 상향, 한 사용자의 단시간 대량 수정 같은 규칙을 걸어두면 감사 로그가 사후 조회 도구에서 사전 감지 장치로 바뀝니다.
POLYGLOTSOFT의 감사 로그 설계 지원
POLYGLOTSOFT는 운영 중인 시스템을 멈추지 않고 변경 이력 계층을 추가합니다. 1단계 단가·재고·권한 등 핵심 테이블 선정과 보존 정책 수립, 2단계 트리거·CDC 기반 안전망 구축, 3단계 애플리케이션 계층 맥락 기록과 배치 실행 ID 도입, 4단계 변경 이력 조회 화면과 이상 변경 알림 구현 순으로 진행합니다. "누가 바꿨는지" 답할 수 있는 시스템이 필요하시면 구독형 개발 서비스로 편하게 문의해 주십시오.
