11.1 로그
Patroni는 데몬으로 상시 동작하므로, 장애가 지나간 뒤 무슨 일이 있었는지 재구성할 1차 자료는 로그입니다. 어느 시점에 leader lock을 잃었는지, 왜 demote를 결정했는지는 DCS에도 메트릭에도 남지 않고 로그에만 남습니다. 로그 동작은 patroni.yml의 log 섹션에서 제어합니다.
출력 형식과 레벨
log.type은 plain(기본)과 json 중 하나입니다. json을 쓰려면 python-json-logger 패키지가 필요합니다. plain 형식의 기본 포맷은 "%(asctime)s %(levelname)s: %(message)s"이고 log.format으로 바꿉니다. json 형식에서는 format에 문자열 대신 리스트를 주어 어떤 필드를 내보낼지 정의하고, key-value 표기로 필드 이름을 바꿔 붙일 수도 있습니다.
레벨은 둘로 나뉩니다. log.level(기본 INFO)이 일반 로그 레벨이고, 예외 스택 트레이스를 어느 레벨로 기록할지는 log.traceback_level(기본 ERROR)이 따로 정합니다. timestamp 형식은 log.dateformat으로 조정합니다.
json 전용 옵션인 log.static_fields는 모든 레코드에 고정 필드를 추가합니다. 여러 노드의 로그를 중앙 수집기로 모을 때 노드 식별자를 넣어 두면 출처 구분이 쉬워집니다.
log:
type: json
level: INFO
traceback_level: ERROR
static_fields:
node: patroni-node1
loggers:
patroni.postmaster: WARNING
log.loggers는 모듈별 레벨 오버라이드입니다. 전체 레벨은 그대로 두고 유난히 소란한 모듈만 WARNING으로 낮추거나, 추적 중인 모듈만 DEBUG로 올리는 식으로 씁니다.
파일 로깅과 로테이션
log.dir을 지정하면 stderr 대신 파일로 기록합니다. 디렉토리는 미리 존재해야 하고 Patroni를 실행하는 사용자가 쓸 수 있어야 합니다. 파일 로깅의 기본 로테이션은 25MB 파일 4개입니다. 파일 크기는 log.file_size, 보관 개수는 log.file_num으로 조정합니다. log.mode는 로그 파일 권한(예: 0644)이고, 지정하지 않으면 umask를 따릅니다.
log:
dir: /var/log/patroni
file_num: 8
mode: 0644
기본 보관량 100MB(25MB x 4)는 로그가 조용한 클러스터에서는 며칠 분량이지만, DEBUG 레벨을 켜거나 장애로 오류가 쏟아지는 상황에서는 빠르게 밀려납니다. 장애 분석에 필요한 구간이 로테이션으로 사라지기 전에 수집기로 옮기거나 file_num을 여유 있게 설정해 두는 편이 안전합니다.
비동기 로깅 큐
Patroni의 로깅은 2단계입니다. 로그 레코드를 먼저 메모리 큐에 넣고, 별도의 로깅 스레드가 큐에서 꺼내 stderr 또는 파일에 씁니다. 로그 저장소의 I/O가 느려져도 HA 루프를 도는 스레드가 쓰기에 직접 막히지 않도록 한 구조입니다.
큐 크기는 log.max_queue_size로 정하며 기본 1000 레코드입니다. 기본 설정 기준으로 약 1시간 20분 분량의 로그에 해당합니다.
heartbeat 로그와 deduplicate_heartbeat_logs
Patroni는 매 HA 루프마다 자신의 판단을 로그로 남깁니다. 안정 상태에서는 매 loop_wait(기본 10초)마다 "leader lock을 유지했고 할 일이 없다"는 취지의 같은 내용이 반복되므로, 로그 대부분이 이 heartbeat로 채워집니다. log.deduplicate_heartbeat_logs(기본 false)를 true로 켜면 내용이 같은 heartbeat 로그의 반복을 억제합니다.
heartbeat 로그의 반복은 노이즈이기만 한 것이 아닙니다. 각 레코드의 timestamp 간격이 곧 HA 루프가 제때 돌았다는 증거라서, 루프가 I/O 대기 등으로 정체된 구간을 로그 간격이 벌어진 지점으로 찾아내는 진단이 가능합니다. deduplicate_heartbeat_logs를 켜면 저장 공간을 아끼는 대신 이 타이밍 정보를 잃습니다.
장애 분석에서 보는 로그 패턴
로그 메시지의 정확한 문구는 버전에 따라 달라지므로, 특정 문자열을 외우기보다 패턴 단위로 보는 접근이 오래 갑니다. 장애 시각 전후로 보통 다음 순서로 검사합니다.
- heartbeat 간격이
loop_wait를 크게 벗어난 구간이 있는지. 있다면 그 시각에 Patroni 프로세스나 호스트 자체가 정체된 것입니다. - promote 또는 demote 결정이 기록된 지점과 그 직전의 판단 근거. role 전환 로그는 failover 재구성의 축이 됩니다.
- DCS 통신 오류와 재시도 기록. leader lock 갱신 실패로 이어졌다면 시나리오 A의 전개를 따라갑니다.
json 로깅을 쓰면 이 검사를 수집기 쿼리로 대신할 수 있습니다.
정리
- 로그 동작은
log섹션 하나로 제어합니다.type(plain/json),level과traceback_level,format, json 전용static_fields, 모듈별loggers오버라이드가 있습니다. dir을 지정하면 파일 로깅으로 전환되고 기본 25MB x 4 로테이션이 적용됩니다.file_size,file_num,mode로 조정합니다.- 로깅은 메모리 큐(기본 1000 레코드)와 별도 스레드를 거치는 비동기 구조입니다.
- heartbeat 로그의 timestamp 간격은 HA 루프 타이밍의 진단 자료입니다.
deduplicate_heartbeat_logs는 이 정보와 저장 공간을 맞바꾸는 설정입니다.