10.3 로깅 설정
PostgreSQL 로그는 운영자의 눈입니다. 잘 설정하면 슬로우 쿼리·에러·락 대기·체크포인트 빈도까지 사후 분석 가능하지만, 무분별하게 켜면 디스크가 차고 진짜 신호가 묻힙니다. 로그 destination·prefix·카테고리·rotation의 균형 잡힌 설정을 봅니다.
출력 destination
log_destination = 'csvlog,stderr' # 기본 'stderr'
logging_collector = on # 별도 프로세스로 로그 수집| destination | 메모 |
|---|---|
stderr | 표준 에러. systemd가 받아 journal·파일로 |
csvlog | CSV 포맷. 분석 도구가 잘 읽음 |
jsonlog | JSON (PG 15+). 외부 수집기와 친화 |
syslog | OS syslog 전송 |
eventlog | Windows 전용 |
운영 표준: csvlog(또는 jsonlog) + logging_collector.
파일 위치·이름·rotation
log_directory = 'log' # PGDATA 상대 또는 절대
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # 시간 패턴
log_rotation_age = 1d # 매일
log_rotation_size = 100MB # 또는 100MB마다
log_truncate_on_rotation = on # 같은 이름 재사용 시 덮어쓰기
log_file_mode = 0600 # 일반 사용자 읽기 금지log_truncate_on_rotation = on + 요일 기반 파일명(%a)을 결합하면 주 단위 rotation:
log_filename = 'postgresql-%a.log' # postgresql-Mon.log 등log_line_prefix — 모든 줄의 머리말
기본값은 비어 있어 누가·언제·어디서 정보 없는 로그가 나옵니다. 운영 표준 prefix:
log_line_prefix = '%t [%p] %u@%d app=%a client=%h '| 코드 | 의미 |
|---|---|
%t | timestamp |
%m | timestamp with ms |
%p | pid |
%u | user |
%d | database |
%a | application_name |
%h | client host |
%c | session id |
%l | session line number |
%x | transaction id |
%q | session 컨텍스트 분리 (이후는 backend 전용) |
CSV 로그는 이 정보가 컬럼으로 자동 들어가므로 prefix를 짧게 둬도 OK.
무엇을 로깅할지
| 파라미터 | 권장 | 의미 |
|---|---|---|
log_min_messages | warning | 서버 메시지 최소 레벨 |
log_min_error_statement | error | 오류 시 SQL 함께 기록 |
log_min_duration_statement | 1000 | 1s 이상 쿼리 |
log_statement | ddl 또는 none | DDL만 기록 (all은 운영 금지) |
log_duration | off | 모든 쿼리 시간 — 너무 많음. log_min_duration_statement 권장 |
log_checkpoints | on | 체크포인트 시점·통계 |
log_connections | on | 새 연결 |
log_disconnections | on | 연결 종료 |
log_lock_waits | on | deadlock_timeout 넘는 락 대기 |
log_temp_files | 0 | 모든 temp file (단위 KB, 0=전체) |
log_autovacuum_min_duration | 1000 | 1s 이상 autovacuum |
log_recovery_conflict_waits | on (PG 14+) | standby 충돌 |
log_replication_commands | off | 복제 명령 — 디버깅 시만 |
log_error_verbosity | default | 또는 verbose (디버깅) |
슬로우 쿼리 — log_min_duration_statement
가장 자주 켜는 설정합니다.
ALTER SYSTEM SET log_min_duration_statement = 1000; -- 1초
SELECT pg_reload_conf();값 의미:
| 값 | 동작 |
|---|---|
-1 | 비활성 |
0 | 모든 쿼리 (운영 금지) |
100 | 100ms 이상 |
1000 | 1s 이상 (보통 권장) |
쿼리 텍스트·실행 시간이 기록됩니다. 더 자세한 plan이 필요하면 auto_explain(10.6).
단편적 카테고리 — log_statement
| 값 | 의미 |
|---|---|
none | 끔 |
ddl | DDL만 (CREATE, ALTER, DROP) |
mod | DDL + DML (INSERT/UPDATE/DELETE) |
all | 모든 SQL (개발 외 금지) |
운영 표준: ddl. 스키마 변경 추적용. 추가 분류·필터링이 필요하면 pgaudit(9.6).
CSV 로그 구조
CSV 컬럼:
log_time, user_name, database_name, process_id,
connection_from, session_id, session_line_num, command_tag,
session_start_time, virtual_transaction_id, transaction_id,
error_severity, sql_state_code, message, detail, hint,
internal_query, internal_query_pos, context,
query, query_pos, location, application_name, backend_type,
leader_pid, query_id이게 분석 도구(pgBadger, pgwatch2, Loki, Splunk)의 입력합니다.
-- CSV 로그를 직접 SQL로 분석
CREATE FOREIGN TABLE pglog (...) SERVER ... -- 외부 테이블 매핑 또는
COPY pglog FROM '/var/lib/pgsql/17/data/log/postgresql-2026-05-23.csv';pgBadger — 로그 리포트 도구
pgBadger는 PostgreSQL 로그를 받아 HTML 리포트를 만드는 Perl 도구입니다. 슬로우 쿼리·시간대별 활동·오류 분포 등 자동 생성합니다.
pgbadger -j 4 --prefix '%t [%p] %u@%d app=%a client=%h ' \
/var/lib/pgsql/17/data/log/postgresql-*.log \
-o /var/www/pgbadger/index.html야간 cron으로 매일 리포트.
외부 수집기 통합
| 도구 | 패턴 |
|---|---|
| Fluent Bit / Vector | 로그 파일 tail → Loki/Elasticsearch |
| Filebeat / Logstash | ELK 스택 |
| Promtail | Loki + Grafana |
| Datadog Agent | DD log pipeline |
| CloudWatch Logs | AWS RDS |
JSON 로그(PG 15+)면 파싱이 가장 깔끔합니다.
로그 디스크 분리
운영 중 로그가 갑자기 폭증하면 데이터 디스크와 같은 디스크면 IO 경합. 권장:
log_directory를 별도 디스크로- rotation·압축·삭제 자동화 (
logrotate또는 PostgreSQL 자체)
로그 보존 정책
| 기간 | 권장 |
|---|---|
| 최근 30일 | 로컬 디스크 |
| 30~365일 | 압축 + 외부 저장 (S3 등) |
| 1년+ | archive — 컴플라이언스 요구사항에 맞춤 |
GDPR·개인정보 관점에서는 쿼리 파라미터에 민감 정보가 들어가지 않게 주의. pg_stat_statements처럼 파라미터화된 형태가 안전합니다.
안티패턴
| 안티패턴 | 위험 |
|---|---|
log_min_duration_statement = 0 | 모든 쿼리 — 디스크 폭주 |
log_statement = 'all' | 같음 |
log_line_prefix 비워 둠 | 누구·언제 정보 누락 |
| 로그 rotation 없음 | 단일 파일이 GB 단위 |
| 로그를 데이터 디스크에 | IO 경합, 디스크 풀 시 클러스터 정지 |
| 로그에 비밀번호·개인정보 평문 | log_statement = all + 파라미터 노출 = 사고 |
정리
- 운영 표준:
csvlog(또는 jsonlog) + logging_collector + 1~7일 rotation log_line_prefix로 모든 줄에 컨텍스트 박기- 슬로우 쿼리는
log_min_duration_statement = 1000 - DDL만
log_statement = ddl, 모든 SQL 로깅은 금지 - 체크포인트·autovacuum·락 대기·temp 파일은 모두 켜기
- 분석은 pgBadger / 외부 수집기 (Loki, Datadog) 둘 다 표준
- 로그 디스크 분리 + 보존 정책 자동화
다음 절(10.4)에서는 실시간 클러스터 상태를 보는 도구 — 통계 뷰(pg_stat_*)를 봅니다.