prod 이상 징후 조사
경고·오류, 플레이어가 겪은 반복 실패, 비정상 동작을 조사한다. 대시보드에서 확인할 수 있는 일반 통계를 매번 다시 작성하지 않는다.
조사는 읽기 전용이다. 서버 재시작·설정 변경·제재·커밋은 별도 요청이 있을 때만 한다.
결과는 ~/work/notes/openmmo-YYYY-MM-DD-log-audit.md, 원문·분석 자료는 같은 날짜의 *-audit/에 둔다. 플레이어명·IP·계정 정보가 있으므로 공개 리포 밖에 보관한다.
범위와 자료
ssh prod로 접속한다(VPN 필요). 접속 실패만으로 게임 장애를 단정하지 않는다.
- 사용자가 지정한 기간을 우선한다. “어제 배포부터 오늘 배포까지”는 어제 서버 시작부터 오늘 배포의 첫 서비스 정지 직전까지
[시작, 종료)다. 별도 지정이 없으면 직전 배포부터 조회 시점까지다.
openmmo-server, openmmo-agent-client의 systemd 시작·정지 기록, 배포 기록과 Git reflog로 경계와 실행 커밋을 확인한다. 구간 내 추가 재시작은 원인과 함께 보고한다. 오늘 배포 직후 검증은 본 조사 구간과 구분한다.
- 시간을 추측하지 않는다.
journalctl에는 +0900 등 시간대를 명시하고 JSON의 __REALTIME_TIMESTAMP로 정확히 자른다. 본문은 KST, 로그 메시지 안 시각은 UTC일 수 있다. SQLite epoch 비교에는 UTC를 쓴다.
- 경계 전후를 포함한 저널을 한 번 수집해 로컬에서 재사용한다. ANSI를 제거하고 JSON
MESSAGE가 바이트 배열이면 UTF-8로 복원한다. 첫·마지막 시각, 누락·suppression·파싱 실패 여부를 확인한다.
- Nginx의 회전된 access/error 로그와 커널·journald의 해당 구간도 확인한다. 원문과 분석 스크립트, 체크섬을 남긴다. 대화 전문·전체 DB는 기본 수집 대상이 아니며 구체적인 이상 징후 확인에 필요한 자료만 추가한다.
- 과거 로그의 동작·설정은 당시 배포 커밋과 대조한다. 현재 코드나 현재 HTTP 응답을 과거 상태의 증거로 쓰지 않는다.
경고·오류 조사
먼저 서버·NPC의 WARN/ERROR를 유형별로 묶는다. 심각한 저빈도 오류를 놓치지 않도록 상위 빈도 밖의 유형도 읽는다. INFO의 실패 결과와 전투 감사 기록도 필요에 따라 대조한다.
각 유의미한 항목에 증상·영향, 대상, 첫/마지막 시각, 반복 횟수·빈도, 대표 근거, 원인 확실성, 후속 후보를 적는다. 건수는 이상 판단에 필요한 범위에서만 쓴다.
- 안정성: panic, OOM, 비정상 종료, DB 잠금·저장 실패, 디스크 부족, 로그 유실, 지연·큐 포화. 플레이어명이나 대화에 포함된 단어를 실제 장애와 혼동하지 않는다.
- 이동:
Blocked move, 울타리·집 충돌, 계단 밖 층 변경, Waypoint queue full, 강제 이동 종료. 같은 플레이어·위치의 연속성, 여러 플레이어의 동일 지점 실패, 분당 피크와 직후 이벤트를 본다. 큐 초과 뒤 사망만으로 스팸 클릭을 단정하지 않는다. Waypoint queue full이 반복되면 같은 플레이어의 movement_audit 타깃 WARN Waypoint overflow trace(30초당 1회)에서 요청 수신 간격·raw.sprinting·received_pose.mounted와 틱의 speed·hunger_mult·sprint_allowed를 대조해 클라이언트와 서버의 속도 불일치 원인을 확인한다.
- 공격:
Rejected player attack의 reason과 상세(대상 소멸·시체·층·거리), 동일 공격자/대상의 반복 기간과 허용 공격을 대조한다. 고정 빈도나 낮은 초당 요청 수만으로 정상·어뷰즈를 판정하지 않는다. 필요한 경우 data/combat-audit/*.jsonl의 HP 수지·요청 간격·허용/거절·history_overflow·dropped_events를 확인한다. 감사 대상 밖까지 결과를 일반화하지 않는다.
- 접속: 프로토콜 거부, 세션 교체, heartbeat, reset, 인증 실패. 배포 전환 중 일시 실패와 정상화 후 지속 실패를 나눈다.
[+N more in the last 60s]는 억제분이며 로그 줄 수와 요청 수를 구분한다. 같은 IP나 /24만으로 다중 계정·프록시·부정행위를 확정하지 않는다.
- NPC: LLM 인증·용량·타임아웃, 응답 파싱 실패, 긴 대기, 행동 실패 루프, 상점/여관 고착, 원장 형식 오류.
llm turn ... error와 LLM prompt failed처럼 한 사건의 중복 로그를 구분한다. 서비스 active나 NPC 입장만으로 LLM 정상이라고 판단하지 않는다.
- Nginx: 모든 5xx, 반복되는 실제 리소스 404, 예상 밖 API 인증 응답과 공격성 요청을 확인한다. 없는 타일의
/api/terrain/water-field·height-original 404와 스캐너 요청은 실제 플레이 장애와 구분한다. 캐시·재다운로드·전송 폭증은 이상 징후가 있을 때만 상세 분석한다. 바이너리·비정상 요청줄 때문에 조용히 집계에서 누락되지 않게 한다.
관측 사실과 가설을 구분한다. 장시간 활동·반복 접속·공유 IP만으로 제재 후보를 만들지 않는다. 수정 효과는 수정이 실제 적용된 구간과 충분한 활동이 있을 때 평가한다.
일반 통계와 선택 조사
기본 보고서에서 접속자·계정·레벨·XP 순위, 전체 경제 수지·재고·인챈트/드롭 통계, 웹 상태코드·전송량 분포, 영웅담 후보를 생략한다. 예전 보고서의 해당 표를 관성적으로 재생성하지 않는다.
이상 징후를 설명하는 분모·비교 수치나 사용자가 별도로 요청한 통계는 필요한 만큼만 포함한다.
- 아이템 복제·비정상 자산 증가가 의심되면 해당 거래·캐릭터·기간으로 좁혀 로그와 읽기 전용 DB 사본을 대조한다. DB는
/home/ubuntu/work/OnlineRPG/data/game_data.db로 고정하고, 실행 중 파일의 단순 복사 대신 일관된 SQLite 백업을 사용한다. 스냅샷 시각과 로그 창의 차이, 영지 창고·좌판·금고·세금·삭제를 고려한다.
- gold_flow.py는 선택적 보조 도구다. 당시 배포본의 상인 종류와 로그를 대조하고 좌판 원금·세금 등 미지원 흐름을 보정하기 전에는 순수지를 확정하지 않는다. Rica·Wick 거래는 생성/소멸, Karl·Signe는 이전이며 되사기는 별도 확인한다. 1g = 10,000c.
- 강화 이상은 당시
data-src/items.csv·world_drop.csv와 시도/성공/파괴 로그로 확인한다. destroyed ... enchanting at +N은 시도 전 단계이며 보너스 드롭 한 줄에 여러 장이 있을 수 있다.
- 영웅담은 별도 요청 시에만 tales.py와
doc/HEROIC_TALES.md를 사용한다. 후보는 사실 확인 전 원장에 넣지 않는다. 운영 agent-client/data/tales/ledger.txt 쓰기는 해당 쓰기 요청/승인이 있을 때만 하며, 자연어 DATE | HERO | 기록 형식과 기존 내용을 보존한다.
직전 조사와 보고
직전 보고서의 미해결 경고·오류·수상한 동작을 이번 창에서 대조한다. 일반 통계 추적 항목은 대시보드로 넘기고 매번 재측정하지 않는다.
판정은 해소·개선·미해결·악화·미재현·재검증 불가를 구분한다. 해당 플레이어가 활동하지 않았거나 표본이 부족하면 해소라고 쓰지 않는다. 이전 배포에만 있던 현상과 이번에 새로 생긴 현상을 구분한다.
보고서는 다음 내용만 필요한 분량으로 구성한다.
- 정확한 조사 창·실행 커밋·구간 내 비정상 재시작 여부.
- 영향과 시급성 순의 주요 이상 징후 및 근거.
- 배포 전환·일반 스캔 등 설명 가능한 잡음의 짧은 요약.
- 직전 미해결 항목의 관련 결과와 우선 후속 후보.
- 원문 경로·재현 방법·누락 및 판정 한계.
사용자에게는 핵심 발견과 다음 조치 후보를 짧게 보고하고 전체 노트를 연결한다. 발견이 없으면 확인 범위와 함께 그렇게 말하며 통계로 분량을 채우지 않는다.
1---2name: prod-log-audit3description: Investigate OpenMMO production warnings, errors, suspicious behavior, and unresolved incidents within a deployment interval; correlate journald, nginx, and targeted evidence, then write a dated note to ~/work/notes. Use for "로그 조사", "로그 점검", "수상한 점 없는지", or "prod 점검". Routine statistics are covered by the dashboard.4---56# prod 이상 징후 조사78경고·오류, 플레이어가 겪은 반복 실패, 비정상 동작을 조사한다. 대시보드에서 확인할 수 있는 일반 통계를 매번 다시 작성하지 않는다.9조사는 읽기 전용이다. 서버 재시작·설정 변경·제재·커밋은 별도 요청이 있을 때만 한다.10결과는 `~/work/notes/openmmo-YYYY-MM-DD-log-audit.md`, 원문·분석 자료는 같은 날짜의 `*-audit/`에 둔다. 플레이어명·IP·계정 정보가 있으므로 공개 리포 밖에 보관한다.1112## 범위와 자료1314- `ssh prod`로 접속한다(VPN 필요). 접속 실패만으로 게임 장애를 단정하지 않는다.15- 사용자가 지정한 기간을 우선한다. “어제 배포부터 오늘 배포까지”는 어제 서버 시작부터 오늘 배포의 첫 서비스 정지 직전까지 `[시작, 종료)`다. 별도 지정이 없으면 직전 배포부터 조회 시점까지다.16- `openmmo-server`, `openmmo-agent-client`의 systemd 시작·정지 기록, 배포 기록과 Git reflog로 경계와 실행 커밋을 확인한다. 구간 내 추가 재시작은 원인과 함께 보고한다. 오늘 배포 직후 검증은 본 조사 구간과 구분한다.17- 시간을 추측하지 않는다. `journalctl`에는 `+0900` 등 시간대를 명시하고 JSON의 `__REALTIME_TIMESTAMP`로 정확히 자른다. 본문은 KST, 로그 메시지 안 시각은 UTC일 수 있다. SQLite epoch 비교에는 UTC를 쓴다.18- 경계 전후를 포함한 저널을 한 번 수집해 로컬에서 재사용한다. ANSI를 제거하고 JSON `MESSAGE`가 바이트 배열이면 UTF-8로 복원한다. 첫·마지막 시각, 누락·suppression·파싱 실패 여부를 확인한다.19- Nginx의 회전된 access/error 로그와 커널·journald의 해당 구간도 확인한다. 원문과 분석 스크립트, 체크섬을 남긴다. 대화 전문·전체 DB는 기본 수집 대상이 아니며 구체적인 이상 징후 확인에 필요한 자료만 추가한다.20- 과거 로그의 동작·설정은 당시 배포 커밋과 대조한다. 현재 코드나 현재 HTTP 응답을 과거 상태의 증거로 쓰지 않는다.2122## 경고·오류 조사2324먼저 서버·NPC의 WARN/ERROR를 유형별로 묶는다. 심각한 저빈도 오류를 놓치지 않도록 상위 빈도 밖의 유형도 읽는다. INFO의 실패 결과와 전투 감사 기록도 필요에 따라 대조한다.25각 유의미한 항목에 **증상·영향, 대상, 첫/마지막 시각, 반복 횟수·빈도, 대표 근거, 원인 확실성, 후속 후보**를 적는다. 건수는 이상 판단에 필요한 범위에서만 쓴다.2627- 안정성: panic, OOM, 비정상 종료, DB 잠금·저장 실패, 디스크 부족, 로그 유실, 지연·큐 포화. 플레이어명이나 대화에 포함된 단어를 실제 장애와 혼동하지 않는다.28- 이동: `Blocked move`, 울타리·집 충돌, 계단 밖 층 변경, `Waypoint queue full`, 강제 이동 종료. 같은 플레이어·위치의 연속성, 여러 플레이어의 동일 지점 실패, 분당 피크와 직후 이벤트를 본다. 큐 초과 뒤 사망만으로 스팸 클릭을 단정하지 않는다. `Waypoint queue full`이 반복되면 같은 플레이어의 `movement_audit` 타깃 WARN `Waypoint overflow trace`(30초당 1회)에서 요청 수신 간격·`raw.sprinting`·`received_pose.mounted`와 틱의 `speed`·`hunger_mult`·`sprint_allowed`를 대조해 클라이언트와 서버의 속도 불일치 원인을 확인한다.29- 공격: `Rejected player attack`의 reason과 상세(대상 소멸·시체·층·거리), 동일 공격자/대상의 반복 기간과 허용 공격을 대조한다. 고정 빈도나 낮은 초당 요청 수만으로 정상·어뷰즈를 판정하지 않는다. 필요한 경우 `data/combat-audit/*.jsonl`의 HP 수지·요청 간격·허용/거절·`history_overflow`·`dropped_events`를 확인한다. 감사 대상 밖까지 결과를 일반화하지 않는다.30- 접속: 프로토콜 거부, 세션 교체, heartbeat, reset, 인증 실패. 배포 전환 중 일시 실패와 정상화 후 지속 실패를 나눈다. `[+N more in the last 60s]`는 억제분이며 로그 줄 수와 요청 수를 구분한다. 같은 IP나 /24만으로 다중 계정·프록시·부정행위를 확정하지 않는다.31- NPC: LLM 인증·용량·타임아웃, 응답 파싱 실패, 긴 대기, 행동 실패 루프, 상점/여관 고착, 원장 형식 오류. `llm turn ... error`와 `LLM prompt failed`처럼 한 사건의 중복 로그를 구분한다. 서비스 active나 NPC 입장만으로 LLM 정상이라고 판단하지 않는다.32- Nginx: 모든 5xx, 반복되는 실제 리소스 404, 예상 밖 API 인증 응답과 공격성 요청을 확인한다. 없는 타일의 `/api/terrain/water-field`·`height-original` 404와 스캐너 요청은 실제 플레이 장애와 구분한다. 캐시·재다운로드·전송 폭증은 이상 징후가 있을 때만 상세 분석한다. 바이너리·비정상 요청줄 때문에 조용히 집계에서 누락되지 않게 한다.3334관측 사실과 가설을 구분한다. 장시간 활동·반복 접속·공유 IP만으로 제재 후보를 만들지 않는다. 수정 효과는 수정이 실제 적용된 구간과 충분한 활동이 있을 때 평가한다.3536## 일반 통계와 선택 조사3738기본 보고서에서 접속자·계정·레벨·XP 순위, 전체 경제 수지·재고·인챈트/드롭 통계, 웹 상태코드·전송량 분포, 영웅담 후보를 생략한다. 예전 보고서의 해당 표를 관성적으로 재생성하지 않는다.39이상 징후를 설명하는 분모·비교 수치나 사용자가 별도로 요청한 통계는 필요한 만큼만 포함한다.4041- 아이템 복제·비정상 자산 증가가 의심되면 해당 거래·캐릭터·기간으로 좁혀 로그와 읽기 전용 DB 사본을 대조한다. DB는 `/home/ubuntu/work/OnlineRPG/data/game_data.db`로 고정하고, 실행 중 파일의 단순 복사 대신 일관된 SQLite 백업을 사용한다. 스냅샷 시각과 로그 창의 차이, 영지 창고·좌판·금고·세금·삭제를 고려한다.42- [gold_flow.py](gold_flow.py)는 선택적 보조 도구다. 당시 배포본의 상인 종류와 로그를 대조하고 좌판 원금·세금 등 미지원 흐름을 보정하기 전에는 순수지를 확정하지 않는다. Rica·Wick 거래는 생성/소멸, Karl·Signe는 이전이며 되사기는 별도 확인한다. 1g = 10,000c.43- 강화 이상은 당시 `data-src/items.csv`·`world_drop.csv`와 시도/성공/파괴 로그로 확인한다. `destroyed ... enchanting at +N`은 시도 전 단계이며 보너스 드롭 한 줄에 여러 장이 있을 수 있다.44- 영웅담은 별도 요청 시에만 [tales.py](tales.py)와 `doc/HEROIC_TALES.md`를 사용한다. 후보는 사실 확인 전 원장에 넣지 않는다. 운영 `agent-client/data/tales/ledger.txt` 쓰기는 해당 쓰기 요청/승인이 있을 때만 하며, 자연어 `DATE | HERO | 기록` 형식과 기존 내용을 보존한다.4546## 직전 조사와 보고4748직전 보고서의 미해결 경고·오류·수상한 동작을 이번 창에서 대조한다. 일반 통계 추적 항목은 대시보드로 넘기고 매번 재측정하지 않는다.49판정은 해소·개선·미해결·악화·미재현·재검증 불가를 구분한다. 해당 플레이어가 활동하지 않았거나 표본이 부족하면 해소라고 쓰지 않는다. 이전 배포에만 있던 현상과 이번에 새로 생긴 현상을 구분한다.5051보고서는 다음 내용만 필요한 분량으로 구성한다.52531. 정확한 조사 창·실행 커밋·구간 내 비정상 재시작 여부.542. 영향과 시급성 순의 주요 이상 징후 및 근거.553. 배포 전환·일반 스캔 등 설명 가능한 잡음의 짧은 요약.564. 직전 미해결 항목의 관련 결과와 우선 후속 후보.575. 원문 경로·재현 방법·누락 및 판정 한계.5859사용자에게는 핵심 발견과 다음 조치 후보를 짧게 보고하고 전체 노트를 연결한다. 발견이 없으면 확인 범위와 함께 그렇게 말하며 통계로 분량을 채우지 않는다.