9. 로그 관리
이 장을 마치면: 어떤 로그가 어디에 쌓이는지 알고, 로그와 core 파일이 디스크를 채우지 않게 관리한다.
9.1 로그 파일 지도
모든 로그는 ~/gritdb1/log/에 있다.
| 구분 | 파일 | 회전 |
|---|---|---|
| 설치 | install_gritdb_<일시>.log(설치마다 새 파일) |
없음 |
| 감독 프로세스 | grit_admin_main.log와 grit_admin_channel_server.log |
자동 |
| 화면 출력 | grit_admin_stdout.log — 감독 프로세스, GritDB 엔진, catalog의 화면 출력. ⚠ 기동할 때마다 덮어쓴다 |
없음 |
| PostgreSQL | postgresql.log — 실패한 SQL 원문이 들어간다 |
없음(9.4) |
| 공용(PostgreSQL 쪽과 GritDB 엔진이 같이 쓴다) | grit_surfer_main.log와 grit_plug_producer_processor.log |
200 MB를 넘길 수 있다. 크기 회전이 거의 일어나지 않기 때문이다. 정리는 9.5를, 크기 기록은 7.4를 본다 |
| PostgreSQL 안의 GritDB 작업 | grit_surfer_slot_manager_worker.log와 grit_recovery_worker_process.log |
자동 |
| catalog | grit_catalog_processor.log(기동, 설정 읽기, 처리) |
자동 |
| 엔진 — 변경분 수집 | grit_plug_consumer_processor.log |
자동 |
| 엔진 — 저장 | grit_unify_main.log, grit_unify_delta_processor.log, grit_unify_chunk_processor.log, grit_unify_writer_processor.log, grit_unify_cold_store_compactor_gc_processor.log, grit_unify_hot_store_gc_processor.log, grit_unify_hot_store_memory_pool_gc_processor.log |
자동 |
| 엔진 — 질의 처리 | grit_burst_main.log와 grit_burst_query_processor.log |
자동 |
| 중단 기록 | GRIT_SURFER_ASSERT.log — 평소에는 0바이트다. 0보다 크면 중단이 있었다 |
없음 |
9.2 형식 · 등급
- GritDB 로그 형식은
[일시][등급][tid:스레드][발생 위치] 내용이다. 등급은INFO,WARN,ERROR다. 형식과 등급은 QuickStart 5.1과 같다. - 한 줄은 최대 4096바이트다. 넘는 줄은 잘리고
...로 끝난다. - 회전된 새 파일의 첫 줄은
[GritSurferLogger] Log rotated - old file size: <바이트> bytes다. 이 줄에는 머리 칸이 없다. - PostgreSQL 로그(
postgresql.log)는 PostgreSQL 기본 형식이다. 줄 머리는log_line_prefix기본값인<일시> <시간대> [<PID>]다. 그 뒤에LOG:,ERROR:,FATAL:,PANIC:등이 온다. 실패한 문장은 다음 줄STATEMENT:에 남는다(9.7). GritDB 확장의 메시지(GritSurfer: …)도 이 파일에 남는다. - GritDB 로그는 늘
INFO등급으로 쓴다.INFO,WARN,ERROR줄이 남는다.config/grit_*.config의 등급 키(*.log_level)는 1.1에서 등급을 바꾸지 않는다. 키는 지우지 않는다(5.6). - 로그 크기 키(
grit_unify.delta.log_file_max_byte)도 1.1에서 쓰지 않는다. 회전 크기는 9.3의 고정값이다. 키는 지우지 않는다(5.6).
9.3 회전 · 크기
| 구분 | 회전 | 크기 |
|---|---|---|
| GritDB 로그(9.1 표의 “자동”) | 파일마다 200 MB에서 회전한다. .1(최신)부터 .20까지 남기고 그보다 오래된 파일은 지운다 |
로그 1종에 최대 약 4 GB |
공용 로그 2개(grit_surfer_main.log와 grit_plug_producer_processor.log) |
크기 회전이 거의 일어나지 않는다 | 200 MB를 넘어 계속 커질 수 있다. 실행 중에는 그대로 둔다. 정지 때 보관하고 정리한다(9.5) |
회전하지 않는 파일 4개(postgresql.log, grit_admin_stdout.log, GRIT_SURFER_ASSERT.log, datafiles/query_text_archive.jsonl) |
없음 | 계속 커진다. grit_admin_stdout.log만 기동할 때 새로 쓴다. 9.4와 9.5를 본다 |
- 실행 중에 회전된 파일(
.1~.20)을 지우거나 옮겨도 된다. - 회전하는 GritDB 로그가 모두 차면
log/는 수십 GB가 된다. 디스크 계획은 1.3을, 매일 크기 기록은 7.4를 본다.
9.4 PostgreSQL 로그 회전
설치 기본에서는 postgresql.log를 회전하지 않는다. 한 파일이 계속 커지므로 운영자가 회전을 설정한다. PostgreSQL 쪽 설명은 로그 파일 관리에 있다.
OS의 logrotate로 회전한다. 로그의 자리와 이름은 바뀌지 않는다. /etc/logrotate.d/gritdb를 root로 만든다.
<설치 경로>/log/postgresql.log {
su gritdb gritdb
daily
rotate 30
compress
delaycompress
missingok
notifempty
copytruncate
}
-
<설치 경로>에는 절대 경로를 쓴다(예: 서비스 계정 홈 아래gritdb1). -
rotate 30과daily는 예다. 보존 기간(9.5)에 맞춘다. -
copytruncate는 파일을 복사한 뒤 비운다. GritDB를 멈추지 않고 회전한다. 복사와 비우기 사이에 쓴 몇 줄을 잃을 수 있다. GritDB는postgresql.log를 덧붙이기(append)로 열어 쓰므로 비운 뒤 앞에 빈 공간이 생기지 않는다. -
sudo logrotate -d /etc/logrotate.d/gritdb를 실행해 오류 줄이 없는지 확인한다. 다음 날ls -l <설치 경로>/log/postgresql.log*를 실행해 회전된 파일이 있는지 확인한다. -
회전한 날의 ERROR 수(QuickStart 5.2, 7.4)는 아래 명령처럼 두 파일에서 함께 센다. logrotate는 하루 한 번 돈다(Ubuntu 24.04에서는 자정부터 1시간 안). 회전 전에 쓴 오늘 줄은
postgresql.log.1로 옮겨진다.delaycompress는.1을 압축하지 않는다는 뜻이다.cat ~/gritdb1/log/postgresql.log.1 ~/gritdb1/log/postgresql.log 2>/dev/null | grep -c "^$(date +%F).*ERROR:"
PostgreSQL 로그 수집기(logging_collector)로 회전할 수도 있다. 이때는 로그 자리가 바뀐다.
⚠
logging_collector를 켜면 PostgreSQL 로그의 자리와 이름이 바뀐다
- 이유: 새 로그는
log_directory와log_filename이 정한 파일에 쌓인다. QuickStart 5.2와 7장의postgresql.log명령이 새 줄을 보지 못한다.- 대신: logrotate를 쓴다. 수집기를 켰으면 바꾼 자리와 이름을 운영 기록에 적고, 점검 명령의 파일 이름을 바꾼다.
9.5 보존 · 정리
- 보존 기간은 기관의 로그 보존 규정을 따른다.
- 장애가 난 때부터 지원 문의가 끝날 때까지는 그때의 로그를 지우지 않는다. QuickStart 7.4가
log/를 통째로 모으기 때문이다.
| 파일 | 실행 중 정리 | 정리 방법 |
|---|---|---|
회전된 GritDB 로그(*.log.<N>) |
된다 | 보존 기간이 지난 것을 지우거나 옮긴다(아래) |
공용 로그 2개(grit_surfer_main.log와 grit_plug_producer_processor.log) |
하지 않는다 | 정지한 상태에서 이름을 바꿔 보관한다(아래) |
postgresql.log |
회전 설정(9.4) | logrotate가 지운다 |
grit_admin_stdout.log |
하지 않는다 | 기동할 때마다 새로 쓴다. 비정상 종료 뒤에는 다시 기동하기 전에 모은다(4.3) |
GRIT_SURFER_ASSERT.log |
하지 않는다 | 0보다 크면 모아서 지원 문의를 한다(QuickStart 7.4). 문의가 끝난 뒤 정지 상태에서 다른 이름으로 옮긴다. 다음 기동 때 빈 파일이 생긴다 |
install_gritdb_<일시>.log |
된다 | 설치 기록으로 보관한다 |
datafiles/query_text_archive.jsonl |
옮길 수 있다 | SQL 원문이 들어 있으므로 보관 규정에 따라 옮기고 지운다(9.7) |
보존 기간이 지난 회전 파일을 서비스 계정으로 지운다. 먼저 -print로 대상을 본다.
find ~/gritdb1/log -name '*.log.[0-9]*' -mtime +<일수> -print
find ~/gritdb1/log -name '*.log.[0-9]*' -mtime +<일수> -delete
정지한 상태에서 공용 로그 2개를 보관한다.
for f in grit_surfer_main.log grit_plug_producer_processor.log; do
mv ~/gritdb1/log/"$f" ~/gritdb1/log/"$f.$(date +%Y%m%d)"
done
ls -l ~/gritdb1/log/를 실행해 날짜가 붙은 파일이 있는지 확인한다. 다음 기동 뒤에는 원래 이름의 새 파일이 생겼는지 확인한다.- 이름을 바꾼 파일도 위
find정리 대상이 된다.
9.6 core 파일
core 파일은 프로세스가 비정상으로 끝날 때 그 메모리를 디스크에 쓴 파일이다. GritDB 엔진의 core는 엔진 메모리만큼(수십 GB) 크다.
| 생기는 때 | 절 |
|---|---|
즉시 정지(gritdb-stop --quick) |
4.2 |
| 정상 정지가 남은 세션 때문에 즉시 정지로 넘어갔을 때 | 4.2 |
| 비정상 종료나 정지 실패 | 4.3 |
core가 생기는 조건과 자리를 서비스 계정으로 본다.
ulimit -Hc
cat /proc/sys/kernel/core_pattern
ulimit -Hc가0이면 core가 생기지 않는다. GritDB 엔진은 soft 한도를 이 hard 값까지 올려 쓴다. 설정은 1.4에 있다.core_pattern이 경로면 그 자리에 쓴다.|로 시작하면 OS의 core 수집 프로그램이 받는다. 이때는 그 프로그램의 자리와 설정을 본다.- core를 1분 안에 다 쓰지 못하면 잘리므로 빠른 디스크에 둔다.
- core는 엔진 메모리만큼 여유가 있는 디스크에 둔다.
datafiles/와 같은 파일시스템이면 core가 데이터 디스크를 채울 수 있다. - core는 지원 문의가 끝날 때까지 지우지 않는다. 끝난 뒤 지운다(7.6).
- 지원 문의 때는 core의 자리와 크기를 알린다(QuickStart 7.4).
- core에는 메모리 안의 데이터 값이 들어 있다. 반출은 9.7을 본다.
9.7 반출
- ⚠ 로그, core 파일, 분석 질의 원문 파일에 SQL 원문과 데이터 값이 들어 있을 수 있다.
| 파일 | 들어 있는 것 |
|---|---|
postgresql.log |
실패한 문장 원문(STATEMENT: 줄과 이어지는 줄), 오류 설명(DETAIL:, CONTEXT:, QUERY:), 오류 문구(ERROR:)의 값, log_statement(11.9)와 log_min_duration_statement로 남긴 문장(LOG: statement:, LOG: execute <이름>:, LOG: duration: … statement: 줄과 이어지는 줄). 11.9의 ddl이면 암호도 들어 있다 |
GritDB 로그(grit_*.log*) |
SQL 원문, 데이터 값, 파일 경로가 들어갈 수 있다 |
datafiles/query_text_archive.jsonl |
분석 세션 조회의 SQL 원문 전체 |
| 분석 질의 이력(6.5) | SQL 원문 앞 1024자 |
| core 파일 | 프로세스 메모리 전체(데이터 값) |
반출 전 순서:
-
보낼 파일은 아래 3번에서 만드는
$S.masked.tar.gz로 정한다. 이 묶음은 QuickStart 7.4 수집물, 실제로 쓰인 설정, 가린 로그로 이루어진다. QuickStart 7.4의$S.tar.gz에는 가리지 않은 로그가 들어 있으므로 보내지 않는다. 이 파일은 서비스 계정만 읽게 두거나 지운다(11.7). -
위 표의 자리를 기관 반출 규정에 따라 검토한다.
-
로그를 가린다. SQL 원문 줄을 뺀 사본으로 묶음을 다시 만든다. QuickStart 7.4와 같은 셸(
cd ~,$S)에서 실행한다.for f in ~/gritdb1/log/postgresql.log*; do zcat -f "$f" | awk '/(STATEMENT|DETAIL|CONTEXT|QUERY):/ || /LOG: +(duration: [0-9.]+ ms +)?(statement|execute|bind|parse)[^:]*:/ {skip=1; next} skip && /^\t/ {next} {skip=0; print}' > "$S/masked_$(basename "$f" .gz)" done grep -c -E '(STATEMENT|DETAIL|CONTEXT|QUERY):|LOG: +(duration: [0-9.]+ ms +)?(statement|execute|bind|parse)[^:]*:' "$S"/masked_* cp ~/gritdb1/datafiles/pgdata/postgresql.auto.conf "$S/" cp -r ~/gritdb1/config "$S/" tar -czf "$S.masked.tar.gz" --exclude='postgresql.log*' "$S" -C ~/gritdb1 log tar -tzf "$S.masked.tar.gz" | grep -c '/postgresql\.log'- 빼는 줄은 오류에 딸린 문장과 설명(
STATEMENT:,DETAIL:,CONTEXT:,QUERY:),log_statement와log_min_duration_statement로 남긴 문장(statement:,execute,bind,parse)이다. 탭으로 시작하는 이어지는 줄까지 뺀다. - 회전된 파일(9.4의
.1,.2.gz…)도 가린다.zcat -f는 압축하지 않은 파일을 그대로 읽는다. 묶음에는 가리지 않은postgresql.log*를 넣지 않는다(--exclude). - 첫
grep -c가 파일마다0을 내고 마지막 줄이0을 내는지 확인한다. postgresql.auto.conf(ALTER SYSTEM값, 5.3)와config/(GritDB 엔진 설정, 5.6)는 실제로 쓰인 설정이므로 함께 보낸다.ERROR:줄에도 값이 들어갈 수 있으므로 2번 검토에서 본다.
- 빼는 줄은 오류에 딸린 문장과 설명(
-
core 파일은 가릴 수 없으므로 보낼지를 기관과 정한다. 보내지 못하면 지원 문의 때 그렇게 알린다.
-
보낸 파일, 날짜, 받는 곳을 기록한다.
- 자세한 수집과 반출 절차는 TroubleShooting을 본다.
문제가 생기면
- 디스크가 모자라면 QuickStart 7장의 GDB-RUNTIME-002와 TroubleShooting을 본다.