본문으로 건너뛰기

로그와 헬스

로그는 세 겹입니다. 어느 겹을 봐야 하는지만 알면 됩니다.

무엇보는 법
컨테이너 로그컨테이너가 stdout 으로 내보낸 것 — 부팅 로그 + 아래 서비스 로그 전부에 [태그] 를 붙인 것호스트 bin/logs.sh plantpulse-datalake
서비스 로그각 모듈이 자기 logs/ 에 쓰는 파일 40여 개컨테이너 안 pd logs [서비스]
부팅 로그pd start 가 서비스 런처의 출력을 이어 붙인 한 파일 /var/log/plantpulse-datalake.logpd logsBOOT 태그, 또는 tail

호스트에서 — logs.sh

cd /opt/kopens/plantpulse-platform-docker/bin

./logs.sh # 모든 컨테이너의 마지막 200줄, 1회 출력
./logs.sh plantpulse-datalake # 데이터레이크 컨테이너만
./logs.sh -f plantpulse-datalake # 계속 따라간다 (Ctrl+C)
./logs.sh --list # 서비스 · 컴포넌트 이름 목록
./logs.sh cassandra # 컴포넌트 이름을 주면 데이터레이크 안 그 로그 파일

2026-09-02 부터 기본이 1회 출력입니다. 따라가려면 -f 를 붙입니다. 앱 컨테이너(서버 · 배치 · 웨어하우스 · HA · OPC-UA · AASX)의 로그도 같은 명령으로 봅니다 — 그쪽은 pd logs 에 없습니다.

컨테이너 안에서 — pd logs

docker exec plantpulse-datalake pd logs --list # 따라갈 파일 <태그> <경로> 목록만
docker exec plantpulse-datalake pd logs --lines 50 cep # cep 만, 마지막 50줄부터
docker exec plantpulse-datalake pd logs --lines 3 admin-api
docker exec -it plantpulse-datalake pd logs storage messaging # 여러 서비스, 계속 따라감 (Ctrl+C)
옵션
--list파일 목록을 찍고 바로 끝난다
--lines N파일마다 기존 내용을 N줄 보여 주고 시작(기본 10). 0 이면 지금부터 쓰이는 것만
--no-boot-log부팅 로그는 빼고
서비스 …이 서비스들만

pd logs서비스가 선언한 파일만 따라갑니다. 아직 없는 파일은 5초마다 다시 찾아 생기는 즉시 첫 줄부터 따라갑니다. 일부러 안 따라가는 것도 있습니다 — 로테이션 사본, JVM GC 로그, Cassandra debug.log(대신 pd node errors), HiveMQ event.log(메시지 단위 감사, 수십 MB), Kafka 요청 감사 로그.

자주 보는 태그와 파일:

태그파일 (PP_HOME 기준)
BOOT/var/log/plantpulse-datalake.log
VALKEY/data1/pp-data/valkey/logs/system.log — 데이터 볼륨 아래입니다
POSTGRES · CASSANDRAplantpulse-storage/db/<엔진>/logs/system.log
KAFKA · MQTTplantpulse-messaging/kafka/logs/ · mqtt/logs/
CEP-TOMCAT · DGW-TOMCATplantpulse-cep/server/logs/catalina.<날짜>.log
TEMPORAL · KESTRAplantpulse-workflow/temporal/logs/ · kestra/logs/
ADMIN-APIplantpulse-datalake-admin-api/logs/admin-api.log

정확한 목록은 상자마다 다르니 pd logs --list 를 믿으세요.

헬스 — 셋이 서로 다른 질문에 답합니다

검사무엇을 보나어디서
컨테이너 HEALTHCHECKpostgres · cassandra 가 실제 쿼리에 답하나 + pd 의 포트 전부가 열려 있나. 20초마다, 기동 유예 900초, 30회 연속 실패면 unhealthydocker ps(healthy)
pd status포트 21개가 열려 있나. 서비스 이름을 주면 그 서비스의 헬스 스크립트컨테이너 안
/api/health관리 콘솔 백엔드가 모은 종합 판정(OK · WARN · FAIL)https://<서버IP>:4950/api/health

docker ps 는 healthy 인데 pd status 에 STOPPED 가 있으면 기동 창이거나 한 번 빗나간 것입니다(다시 치면 RUNNING). 반대로 unhealthy 인데 pd status 는 전부 RUNNING 이면 포트는 열렸지만 쿼리에 답을 못 하는 상태입니다 — pd logs storage.

Kafka 는 특별합니다. 9092 는 브로커가 요청을 처리하기 10초 전에 열리므로 pd 는 포트 대신 «브로커가 광고한 주소로 ApiVersions 요청을 보내 답을 받나» 를 봅니다. messaging 의 헬스 줄에 UP (advertised 10.99.0.100:9092 answered ApiVersions) 처럼 사유가 붙는 이유입니다.

docker inspect --format '{{json .State.Health.Log}}' plantpulse-datalake | jq # 최근 헬스체크 결과
docker exec plantpulse-datalake pd status messaging # 서비스 하나의 헬스 줄

이벤트 저널 — 누가 언제 무엇을 했나

pd start · stop · restart · backup 이 JSON 한 줄씩을 plantpulse-datalake-admin-api/logs/pd-events.jsonl 에 남깁니다. 관리 콘솔의 이벤트 화면이 이것을 타임라인으로 보여 줍니다.

{"at":"2026-09-03T10:11:53+09:00","kind":"service.stop","subject":"datalake","severity":"info","message":"pd stop","actor":"pd","exit_code":0}

콘솔에서 실행한 명령은 actoroperator:<이름> 입니다. 계획 밖 정지(service.down / service.recovered)는 사람이 아니라 pd downtime 의 기록이 씁니다.

진단 묶음

장애 문의에 첨부할 것을 한 번에 모으려면 호스트에서:

cd /opt/kopens/plantpulse-platform-docker/bin
./ops-check.sh # 헬스 + 최근 critical 로그 + 제거된 워커의 잔여물
./doctor.sh # 진단 tarball — 시크릿 값은 마스킹된다

관련 문서