프리서버 로그 분석 기초, 자주 터지는 오류 잡기

프리서버 운영에서 “로그”가 진짜 돈이 되는 순간 프리서버를 운영하다 보면 이상할 정도로 “같은 자리에서” 자주 터지는 문제가 있어요. 유저는 갑자기 튕기고, 특정 맵에서만 렉이 심해지고, 새벽 시간대에만 서버가 멈추기도 하죠. 이럴 때 감으로 패치하거나 설정을 …

person holding game controller in-front of television

프리서버 운영에서 “로그”가 진짜 돈이 되는 순간

프리서버를 운영하다 보면 이상할 정도로 “같은 자리에서” 자주 터지는 문제가 있어요. 유저는 갑자기 튕기고, 특정 맵에서만 렉이 심해지고, 새벽 시간대에만 서버가 멈추기도 하죠. 이럴 때 감으로 패치하거나 설정을 건드리면 잠깐 나아지는 듯하다가 다시 재발하는 경우가 많습니다. 결국 답은 하나예요. 로그를 읽고, 원인을 좁히고, 재현하고, 고치는 것.

로그 분석은 초반엔 어렵게 느껴지지만, 한 번 “어떤 로그가 어떤 문제를 말해주는지” 패턴이 잡히면 운영 난이도가 확 내려갑니다. 실제로 구글의 SRE(Site Reliability Engineering) 문화에서 강조하는 핵심 중 하나가 관측 가능성(Observability)인데요, 그 중심에 로그가 있습니다. 어떤 연구/실무 통계에서도 비슷한 메시지가 나와요. 예를 들어 여러 장애 보고서(포스트모템)들을 보면, 장애의 상당수는 “문제가 생긴 뒤 원인 파악 시간이 길어져서” 피해가 커지는 형태가 흔합니다. 즉, 문제를 더 빨리 찾아내는 능력 자체가 운영 실력을 좌우해요.

오늘은 프리서버에서 자주 발생하는 오류를 “로그로 잡는 방법”을 기초부터 실전까지 친근하게 정리해볼게요. 특정 게임/엔진에 한정되지 않도록, 어디서든 적용 가능한 방식으로 구성했습니다.

1) 로그의 종류부터 정리하기: 무엇을 어디서 봐야 할까?

로그는 그냥 “텍스트 기록”이 아니라, 사건의 타임라인이에요. 프리서버 환경에서는 보통 여러 계층에서 로그가 쌓입니다. 문제는 많은 운영자분들이 한 파일만 보다가 “별 내용이 없네?” 하고 놓치는 거죠. 그래서 먼저 로그 지도를 그려봅시다.

프리서버에서 흔히 쓰는 로그 분류

  • 애플리케이션 로그: 게임 서버 프로세스/월드 서버/로비 서버 등에서 찍는 로그
  • 네트워크 로그: 게이트웨이, 프록시, 방화벽, DDoS 장비(또는 클라우드 보안) 이벤트
  • 시스템 로그: Linux의 syslog/journal, Windows 이벤트 뷰어
  • DB 로그: MySQL/MariaDB/PostgreSQL의 slow query log, error log
  • 웹/패치 서버 로그: Nginx/Apache access/error 로그, CDN 로그
  • 크래시 덤프/코어 덤프: 프로세스가 죽을 때 남기는 덤프(가장 강력한 단서)

로그를 “한 줄로” 읽지 말고 “묶음으로” 읽는 습관

한 줄짜리 에러만 보고 “원인이 이거네” 하는 건 위험해요. 실제 원인은 그 이전에 이미 시작된 경우가 많습니다. 추천하는 방식은 이거예요.

  • 문제가 발생한 시각을 기준으로 앞뒤 5~10분 로그를 같이 보기
  • 동일 시각의 시스템/DB/네트워크 로그를 함께 교차 확인하기
  • 에러 직전의 WARNING/timeout/retry 메시지에 특히 주목하기

시간대(Timezone)와 타임스탬프부터 통일하기

초보 운영에서 가장 흔한 삽질 포인트가 “시간이 안 맞아서” 원인을 못 찾는 거예요. 서버는 UTC, 로그는 KST, DB는 또 다른 타임존이면 교차 분석이 거의 불가능해집니다. 최소한 아래는 통일해두면 좋아요.

  • 서버 OS 타임존
  • 컨테이너/프로세스 타임존
  • 로그 포맷의 타임스탬프(ISO-8601 권장)
  • NTP 동기화(시간 오차가 쌓이면 진짜 지옥입니다)

2) “자주 터지는 오류” TOP 패턴: 로그에서 이렇게 보인다

프리서버에서 반복되는 장애는 대체로 몇 가지 유형으로 수렴해요. 여기서는 “로그에 어떤 형태로 찍히는지”와 “의심해야 할 원인”을 같이 정리할게요. (예시는 다양한 환경에서 흔히 보이는 패턴을 일반화한 것입니다.)

접속 끊김/튕김: timeout, reset, broken pipe

유저 입장에서는 “그냥 튕김”이지만, 로그에서는 좀 더 구체적으로 나뉩니다. 대표 키워드는 아래예요.

  • timeout / read timeout / handshake timeout
  • connection reset by peer
  • broken pipe
  • too many connections

원인 후보는 크게 4갈래로 많이 갑니다.

  • 네트워크 품질 문제(특정 ISP, 특정 지역에서만 발생하는지 확인)
  • 서버 부하로 응답 지연(틱 드랍/스레드 정체)
  • 소켓/파일 디스크립터 고갈(리눅스 ulimit, FD leak)
  • 게이트웨이/프록시 설정(keep-alive, idle timeout, NAT 테이블)

메모리 관련 크래시: OOM, out of memory, allocation failed

가장 무서운 유형이죠. 메모리가 터지면 “갑자기 죽는 것처럼” 보이기 쉬워요. 리눅스라면 OOM Killer가 프로세스를 강제 종료시키기도 합니다.

  • OutOfMemoryError / allocation failed
  • OOMKilled (컨테이너 환경)
  • kernel: Out of memory: Kill process …

원인은 보통 아래 중 하나입니다.

  • 메모리 누수(특정 기능/맵/이벤트 이후만 점점 증가)
  • 캐시 설정 과다(메모리를 캐시에 너무 줌)
  • 유저 폭주로 객체/세션이 급증
  • 로그 폭주로 디스크 I/O 대기 → 메모리 압박(버퍼/큐가 쌓임)

디스크/로그 폭주: No space left on device

프리서버 운영에서 “진짜 흔한데 치명적인” 문제입니다. 로그가 쌓이다가 디스크가 꽉 차면, DB도 멈추고 서버도 저장을 못 해서 연쇄적으로 터져요.

  • No space left on device
  • write failed / disk quota exceeded
  • database: could not write…

대응은 단순하지만 꾸준함이 필요해요.

  • logrotate(또는 Windows 스케줄)로 로그 자동 순환
  • 압축 보관(gzip/zstd) + 보관 기간 정책
  • 특정 에러가 반복되며 로그가 폭발한다면 “로그 원인”부터 제거

DB 병목: slow query, lock wait timeout, deadlock

유저는 “렉”으로 느끼고, 운영자는 “서버 상태는 정상인데?” 하고 넘어가기 쉬운 영역입니다. 하지만 로그를 보면 단서가 명확해요.

  • Slow query log에 특정 쿼리가 반복적으로 등장
  • Lock wait timeout exceeded
  • Deadlock found when trying to get lock

특히 이벤트/상점/강화/인벤토리 같은 기능은 트랜잭션이 복잡해서 락 이슈가 자주 납니다. 이때는 “에러 한 번”이 아니라 “동시에 들어오는 요청 수”가 핵심이에요.

3) 로그 분석 기본기: 검색, 필터링, 상관관계 잡는 법

로그 분석은 사실 도구보다 “순서”가 중요해요. 막 grep부터 치기 전에, 어떤 질문을 던질지 정하면 시간이 확 줄어듭니다.

장애 분석 5단계 질문 템플릿

  • 언제(정확한 시각/빈도) 발생했나?
  • 누가(특정 계정/특정 지역/특정 맵) 겪었나?
  • 무엇이(접속/전투/이동/결제 등) 트리거였나?
  • 어디서(서버/채널/인스턴스/노드) 발생했나?
  • 얼마나(영향 범위/재현율/지속 시간) 심각했나?

실무에서 자주 쓰는 검색 키워드 묶음

프리서버 로그는 포맷이 제각각이라, “정규식/키워드 사전”을 만들어두면 진짜 편합니다.

  • 에러 레벨: ERROR, WARN, FATAL, EXCEPTION, TRACEBACK
  • 네트워크: timeout, reset, refused, handshake, disconnect
  • 리소스: OOM, memory, heap, GC, too many open files
  • DB: slow, deadlock, lock, timeout, connection pool
  • 디스크: no space, quota, I/O error

상관관계(코릴레이션) 잡기: “같은 사건”을 묶는 키

로그가 여러 컴포넌트에 흩어져 있으면, “이 로그가 저 로그랑 같은 사건인지”부터 헷갈립니다. 그래서 가능한 한 아래 키를 로그에 남기면 좋아요.

  • 요청 ID(Request ID) 또는 트랜잭션 ID
  • 세션 ID / 캐릭터 ID / 계정 ID
  • 서버 인스턴스 ID(노드명, 컨테이너 ID)
  • 맵 ID, 채널 ID, 스킬 ID 같은 도메인 키

이미 운영 중이라 코드 수정이 어렵다면, 최소한 “동일 시각 + 동일 계정/캐릭터 + 동일 서버 프로세스” 기준으로 묶어서 보세요. 이 조합만으로도 원인 범위를 꽤 좁힐 수 있어요.

4) 재현이 반이다: 오류를 “터지게 만드는 조건”을 찾는 방법

로그로 원인을 추정했으면, 다음은 재현입니다. 재현이 되면 수정이 빨라지고, 수정 후 검증도 쉬워져요. 재현이 안 되면 운영은 계속 ‘기도 메타’가 됩니다.

부하/동시성 문제는 “유저 수”가 아니라 “패턴”이 핵심

예를 들어 300명이 접속해도 멀쩡한데, 특정 시간에만 터진다면 단순 접속자 수보다 “동시에 같은 행동을 하는 순간”이 문제일 수 있어요. 예시를 들어볼게요.

  • 보스 리젠 직후 다수 유저가 같은 인스턴스 생성 → DB/서버 락 폭증
  • 이벤트 시작 시각에 우편함/보상 수령 API가 몰림 → 쿼리 병목
  • 패치 직후 클라이언트 재다운로드 폭주 → 웹 서버/디스크 I/O 급증

재현 체크리스트

  • 발생 조건을 “행동 순서”로 적기(예: 로그인 → A맵 이동 → B NPC 클릭 → 상점 열기)
  • 동시 실행이 필요한지 확인하기(1명 vs 50명)
  • 특정 데이터(특정 아이템/퀘스트 상태/길드 상태)에서만 발생하는지 확인
  • 스테이징 서버에 로그 레벨을 일시적으로 올려 디테일 확보

전문가들이 권하는 방식: 포스트모템 문화

SRE나 대규모 서비스 운영에서 흔한 방식이 “블레임리스 포스트모템(Blameless Postmortem)”이에요. 누가 잘못했는지보다, 어떤 조건에서 어떤 신호를 놓쳤고 다음엔 어떻게 막을지에 집중합니다. 프리서버 운영에서도 이 방식이 꽤 잘 맞아요.

  • 원인(Root Cause) + 기여 요인(Contributing Factors)을 분리해서 기록
  • 재발 방지 액션을 “측정 가능”하게 만들기(예: 디스크 80% 경고 알림 추가)
  • 다음 장애 때 더 빨리 찾을 수 있도록 “로그 개선”을 항목으로 넣기

5) 자주 터지는 오류를 빠르게 잡는 실전 처방전(케이스별)

여기부터는 많이 겪는 장애를 케이스로 묶어서 “로그에서 무엇을 보고, 무엇을 먼저 해볼지”를 정리해볼게요. 모든 항목이 정답은 아니지만, 초동 대응 속도를 올리는 데 도움이 됩니다.

케이스 A: 특정 맵/던전에서만 서버 지연 후 튕김

로그에서 확인할 것:

  • 해당 맵 진입 시 특정 스크립트/AI/스폰 로직이 ERROR/WARN을 뿜는지
  • GC 로그(가능한 환경이라면)에서 스파이크가 있는지
  • DB 쿼리 급증(맵 진입 시 로딩 데이터가 과도한지)

우선순위 대응:

  • 문제 맵 진입 직전/직후 로그를 묶어서 비교(정상 맵과 차이 확인)
  • 스폰 수/드랍 테이블/AI 루프 등 반복 로직 점검(무한 루프가 흔한 원인)
  • 해당 구간만 임시로 로그 레벨 상향(디버그 로그는 짧게!)

케이스 B: 새벽에만 다운, 아침에 보면 아무 흔적이 없음

로그에서 확인할 것:

  • 크론/스케줄러 작업(백업, 로그 압축, DB 최적화)이 도는 시각
  • 서버 재부팅/프로세스 재시작 기록
  • OOM/디스크 풀 등의 시스템 이벤트

우선순위 대응:

  • 스케줄 작업 시간을 분산하거나, 리소스 제한(nice/ionice) 적용
  • 백업/압축 작업이 DB와 같은 디스크를 쓰는지 확인(같으면 병목이 커짐)
  • 다운 시각 전후 CPU/RAM/DISK 사용률을 함께 기록(모니터링이 없으면 최소한 주기적 로그라도)

케이스 C: 갑자기 접속자 늘면 로그인 서버가 먼저 죽음

로그에서 확인할 것:

  • connection pool exhausted, too many connections
  • 인증/세션 발급 과정에서 외부 의존(DB/Redis/웹 API) 지연
  • rate limit 또는 방화벽 차단 이벤트

우선순위 대응:

  • 동시 로그인 제한(큐잉) 도입: “죽는 것”보다 “기다리게 하는 것”이 낫습니다
  • 인증 관련 쿼리/인덱스 점검(특히 계정 테이블)
  • 세션/토큰 저장소 성능(메모리 캐시 사용 여부) 점검

케이스 D: 오류는 없는데 렉이 심하고, 채팅만 늦게 올라옴

이런 건 로그에 에러가 안 찍히는 경우가 많아요. 그래서 “지표형 로그”가 필요합니다.

  • 각 요청 처리 시간(ms)을 INFO로 남기기(핵심 API만이라도)
  • 틱 시간/프레임 시간/큐 길이 같은 성능 지표를 주기적으로 찍기
  • DB 쿼리 시간, 캐시 히트율 같은 수치를 기록

특히 “채팅만 늦다”는 건 메시지 큐/브로드캐스트 처리, 또는 특정 스레드가 막혔을 가능성이 있습니다. 이럴 땐 단순 에러 로그보다 “처리 시간 로그”가 훨씬 더 잘 먹혀요.

6) 로그를 ‘자산’으로 만드는 운영 습관: 저장, 알림, 시각화

로그 분석은 한 번으로 끝나지 않아요. 프리서버는 업데이트/이벤트/유저 패턴 변화가 잦아서, “로그를 쌓고 비교하는 운영 체계”가 있으면 재발률이 확 떨어집니다.

로그 보관 정책: 무조건 오래가 답이 아니다

디스크는 한정되어 있고, 프리서버는 특히 비용 민감하죠. 그래서 현실적인 정책이 필요합니다.

  • 에러/크래시 로그: 30~90일(압축 보관)
  • 일반 액세스/정보 로그: 7~30일
  • 대형 이벤트 기간: 임시로 보관 기간 연장

알림 기준은 “에러 개수”보다 “증가율”이 유용할 때가 많다

예를 들어 평소에 WARN이 하루 100건 나오던 서버가 어느 날 1000건으로 급증하면, 그게 더 중요한 신호예요. 그래서 가능하다면 아래처럼 설계해보세요.

  • 5분 내 ERROR 50건 이상
  • 특정 에러(예: deadlock) 10분 내 5회 이상
  • 프로세스 재시작 감지(크래시 가능성)
  • 디스크 사용률 80%/90% 경고

추천하는 최소 도구 조합(가볍게 시작하기)

대형 스택을 처음부터 올리기 부담스럽다면 “가벼운 조합”부터 가도 충분합니다.

  • 로그 순환: logrotate(리눅스) 또는 스케줄러 기반 압축/삭제
  • 검색: ripgrep/grep + 간단한 스크립트(키워드 템플릿화)
  • 시각화(가능하면): Grafana + Loki 또는 ELK(여건 될 때)

중요한 건 도구가 아니라 “같은 형식으로 남기고, 같은 방식으로 찾을 수 있게” 만드는 표준화입니다.

프리서버에서 오류를 줄이는 가장 현실적인 루틴

정리해보면, 프리서버 운영에서 로그는 단순 기록이 아니라 문제 해결의 지도예요. 자주 터지는 오류는 대부분 패턴이 있고, 그 패턴은 로그에 남습니다. 시간을 통일하고, 로그를 종류별로 묶어서 보고, 사건을 연결할 키를 만들고, 재현 조건을 확보하면 “운영자의 감”이 아니라 “근거 기반 수정”이 가능해져요.

  • 로그는 한 파일만 보지 말고(앱/시스템/DB/네트워크) 교차로 보기
  • 에러 한 줄보다 “직전의 경고/지연”을 같이 보기
  • 재현 조건을 행동 순서로 문서화해두기
  • 디스크/메모리/DB 병목 같은 상위 3대 장애를 우선 관리하기
  • 보관/알림/표준 포맷으로 로그를 자산화하기

이 루틴만 잡혀도 장애 대응 속도는 눈에 띄게 빨라지고, 무엇보다 유저 경험이 안정됩니다. 다음 단계로는 “로그에 성능 지표를 심는 방법”이나 “슬로우 쿼리 최적화 기본” 같은 주제로 확장해도 정말 도움이 될 거예요.