개발이군고구마

로그 본문

SERVER/CS

로그

김구황 2026. 6. 7. 16:34
728x90

요약

catalina.out은 Tomcat 프로세스의 콘솔 출력이 모이는 파일에 가까운 로그. 애플리케이션 로그가 콘솔로 출력되고 있다면 해당 로그도 catalina.out에 쌓일 수 있음. 하지만 Vector가 catalina.out을 수집하지 않는다면 Kibana에서는 이 로그를 확인할 수 없음.

반면 Kibana에서 조회되는 로그는 Vector가 읽고 Kafka를 거쳐 Elasticsearch에 저장된 로그. 서버에 존재하는 모든 로그가 자동으로 Kibana에 보이는 구조가 아님.

logrotate는 일반 로그 파일을 주기적으로 나누고 압축하고 삭제하는 도구. systemd는 서비스를 실행하고 stdout/stderr의 처리 방식을 관리하는 도구. systemd를 사용한다고 해서 모든 로그 파일의 rotate가 자동으로 해결되는 것은 아님.

운영 환경에서 로그를 설계할 때 확인해야 할 핵심 질문은 세 가지.

애플리케이션 로그는 어디에 저장되는가
stdout/stderr는 어디로 흘러가는가
수집기는 어떤 파일을 읽고 있는가
 

이 세 가지가 맞지 않으면 Kibana에서는 조용하지만 서버 디스크만 가득 차는 상황 발생 가능.

로그 파이프라인을 구성할 때는 단순히 “Kibana에서 보이는가”만 볼 것이 아니라, 서버 안에서 실제로 어떤 로그 파일이 생성되고 증가하는지까지 함께 확인하는 관점 필요.

 

1. 서버 로그는 하나가 아니라 여러 갈래의 흐름

서버에서 “로그”라고 부르는 것은 하나의 파일이나 하나의 시스템을 의미하지 않음. 실제로는 로그를 남기는 주체, 로그가 저장되는 위치, 로그를 수집하는 도구, 로그를 조회하는 화면이 모두 분리된 구조.

대표적인 흐름은 다음과 같은 형태.

애플리케이션 코드
  ↓
Logback
  ↓
로그 파일 또는 콘솔 출력
  ↓
Vector
  ↓
Kafka
  ↓
Elasticsearch
  ↓
Kibana
 

애플리케이션에서 다음과 같은 코드를 작성했다고 가정.

 
logger.info("주문 생성 완료");
 

이 로그가 실제로 어디에 남는지는 Logback 설정에 따라 달라짐.

파일로 저장
→ /logs/mobile/application.log

콘솔로 출력
→ stdout 또는 stderr

Tomcat 실행 환경에서 콘솔 출력 저장
→ catalina.out

Vector 수집 대상 파일
→ Kafka, Elasticsearch, Kibana로 전달
 

즉, 애플리케이션에서 로그를 남겼다고 해서 모든 로그가 Kibana에 보이는 구조는 아님. Kibana에 보이는 로그는 수집기가 읽어서 Elasticsearch까지 전달한 로그뿐.


2. catalina.out의 정체

catalina.out은 Tomcat 환경에서 자주 등장하는 로그 파일. 일반적으로 Tomcat 프로세스의 표준 출력과 표준 에러가 모이는 파일에 가까운 개념.

쉽게 말하면 다음과 같은 출력이 catalina.out에 쌓일 수 있음.

System.out.println()
System.err.println()
콘솔로 출력되는 애플리케이션 로그
Tomcat 실행 중 발생한 에러
예외 스택트레이스
 

Tomcat을 실행하면 내부적으로 여러 로그 파일이 생성될 수 있음.

파일의미
catalina.out Tomcat 프로세스의 콘솔 출력 저장 파일
catalina.YYYY-MM-DD.log Tomcat 자체 동작 로그
localhost.YYYY-MM-DD.log 웹 애플리케이션 컨텍스트 관련 로그
localhost_access_log.YYYY-MM-DD.txt HTTP 요청 접근 로그

이 중 디스크 증가 문제에서 자주 원인이 되는 파일은 catalina.out.

중요한 점은 catalina.out이 Logback의 RollingFileAppender가 관리하는 애플리케이션 로그 파일이 아닐 수 있다는 점. 애플리케이션 로그가 콘솔로 출력되고, Tomcat이 그 콘솔 출력을 catalina.out에 저장하는 구조일 수 있음.

예를 들면 이런 흐름.

애플리케이션 로그 발생
  ↓
Logback ConsoleAppender
  ↓
stdout / stderr
  ↓
Tomcat 실행 스크립트
  ↓
catalina.out
 

반대로 Logback이 파일에 직접 쓰는 경우는 다음과 같은 흐름.

애플리케이션 로그 발생
  ↓
Logback RollingFileAppender
  ↓
/var/log/mobile/application.log
 

두 로그는 비슷한 내용을 담을 수 있지만 관리 주체와 저장 위치가 다른 별개의 로그.


3. Kibana 수집 로그의 의미

Kibana는 로그를 직접 수집하는 도구가 아님. Elasticsearch에 저장된 데이터를 검색하고 시각화하는 화면.

즉, Kibana에서 로그를 보기 위해서는 먼저 로그가 Elasticsearch에 들어가 있어야 함. 그 앞단에는 보통 Vector, Filebeat, Logstash 같은 수집기가 존재.

이번 구조를 기준으로 보면 다음과 같은 흐름.

서버 로그 파일
  ↓
Vector
  ↓
Kafka
  ↓
Elasticsearch
  ↓
Kibana
 

각 구성요소의 역할은 다음과 같음.

구성요소역할
Logback 애플리케이션 로그의 출력 위치와 형식 결정
Vector 서버의 로그 파일을 읽고 다음 단계로 전달
Kafka 로그 이벤트를 안정적으로 전달하기 위한 메시지 스트림
Elasticsearch 로그를 검색 가능한 형태로 저장
Kibana Elasticsearch에 저장된 로그 조회 및 시각화

따라서 “Kibana 수집 로그”라는 표현은 정확히는 다음과 같은 의미.

Vector가 읽은 로그
Kafka를 거쳐 Elasticsearch에 저장된 로그
Kibana에서 조회 가능한 로그
 

반대로 서버에 존재하지만 Vector가 읽지 않는 파일은 Kibana에 보이지 않음.

예를 들어 Vector 설정이 다음 파일만 읽는 상태라고 가정.

/logs/mobile/application.log
/logs/mobile/error.log
 

그런데 catalina.out의 위치가 다음과 같다면.

/usr/local/tomcat/logs/catalina.out
 

결과는 다음과 같은 구조.

application.log
→ Vector 수집
→ Kafka
→ Elasticsearch
→ Kibana에서 조회 가능

catalina.out
→ Vector 수집 대상 아님
→ Elasticsearch 미저장
→ Kibana에서 조회 불가
→ 서버 디스크에는 계속 누적
 

이런 구조 때문에 Kibana에서는 문제가 보이지 않는데 서버 저장소는 계속 증가하는 상황 발생 가능.


4. 이번 문제의 구조

이번 저장소 증가 문제는 다음과 같은 구조로 이해 가능.

모바일 서버에서 로그 급증
  ↓
서버 저장소 사용량 증가
  ↓
확인 결과 catalina.out 파일 증가
  ↓
해당 파일은 Vector 수집 대상이 아님
  ↓
Kibana에서는 관련 로그 조회 불가
  ↓
서버 디스크에만 로그 누적
 

즉, 핵심은 “Kibana에 보이는 로그”와 “서버에 실제로 쌓이는 로그”가 서로 다를 수 있다는 점.

애플리케이션에서 예외가 반복적으로 발생하고, 그 예외가 콘솔로 출력되고 있었다면 다음과 같은 흐름 가능.

Exception 발생
  ↓
콘솔 출력
  ↓
Tomcat stdout / stderr
  ↓
catalina.out 증가
  ↓
Vector 수집 대상 아님
  ↓
Kibana에서 확인 불가
  ↓
서버 저장소 증가
 

운영 환경에서 로그를 확인할 때는 Kibana만 보는 것으로 충분하지 않음. 실제 서버에서 어떤 파일이 증가하고 있는지 별도 확인 필요.


5. /dev/null의 의미

로그 문제를 처리하는 과정에서 자주 등장하는 표현 중 하나가 /dev/null.

/dev/null은 리눅스에서 데이터를 버리는 특수 파일. 여기에 출력되는 내용은 저장되지 않고 사라짐.

예를 들어 다음 명령.

 
some-command > /dev/null 2>&1
 

의미는 다음과 같음.

> /dev/null
→ 표준 출력(stdout)을 버림

2>&1
→ 표준 에러(stderr)를 표준 출력과 같은 곳으로 보냄

결과
→ stdout과 stderr 모두 버림
 

systemd 서비스에서는 비슷한 설정을 다음과 같이 적용 가능.

 
[Service]
StandardOutput=null
StandardError=null
 

이 설정은 서비스의 표준 출력과 표준 에러를 저장하지 않고 버리는 방식.

다만 /dev/null 처리는 신중하게 접근 필요. 디스크 증가를 막을 수는 있지만, 해당 로그는 복구 불가능한 형태로 사라짐. 필요한 로그가 Logback 파일 로그나 Kibana 수집 로그로 안정적으로 남고 있다는 전제 필요.


6. .gz 로그 파일의 의미

로그 디렉터리에서 자주 보이는 .gz 파일은 gzip으로 압축된 로그 파일.

예시.

application.log
application.2026-06-01.log.gz
application.2026-06-02.log.gz
application.2026-06-03.log.gz
 

이 파일들은 보통 과거 로그를 압축한 결과물. 생성 주체는 크게 두 가지 가능성.

logrotate가 압축한 로그
Logback RollingFileAppender가 압축한 로그
 

Logback 설정에서 다음과 같은 패턴을 사용하면 과거 로그가 .gz 형태로 보관 가능.

 
<fileNamePattern>/logs/mobile/app.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
 

의미는 다음과 같음.

날짜별 로그 파일 생성
지난 로그를 gzip으로 압축
30일치 보관
전체 보관 용량 3GB 제한
 

.gz 파일 삭제는 이미 압축되어 보관 중인 과거 로그를 제거하여 디스크 공간을 확보하는 조치. 다만 장애 분석이나 추적에 필요한 로그일 수 있으므로 삭제 전 보관 정책 확인 필요.


7. logrotate의 역할

logrotate는 리눅스에서 로그 파일을 자동으로 관리하는 도구.

로그 파일은 그냥 두면 계속 커짐.

application.log
 

그래서 일정 주기나 크기 기준으로 파일을 나누고, 오래된 파일을 압축하거나 삭제하는 관리 필요.

application.log
application.log.1
application.log.2.gz
application.log.3.gz
 

logrotate의 핵심 역할은 다음과 같음.

rotate
→ 현재 로그 파일을 과거 로그 파일로 넘김

compress
→ 오래된 로그 파일 압축

remove
→ 보관 기간이 지난 로그 삭제

postrotate
→ rotate 이후 서비스에 신호 전달
 

예시 설정.

 
/var/log/tomcat/catalina.out {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}
 

각 옵션의 의미.

daily
→ 매일 rotate

rotate 7
→ 7개 파일만 보관

compress
→ 지난 로그 압축

missingok
→ 파일이 없어도 오류 처리하지 않음

notifempty
→ 빈 파일은 rotate하지 않음

copytruncate
→ 기존 파일을 복사한 뒤 원본 파일 크기를 0으로 비움
 

catalina.out처럼 프로세스가 계속 열고 있는 로그 파일은 단순히 파일명을 바꾸는 방식만으로는 충분하지 않을 수 있음. 애플리케이션이 여전히 기존 파일을 바라보고 있을 수 있기 때문. 이런 경우 copytruncate 같은 방식이 사용되기도 함.

단, copytruncate는 복사와 비우기 사이의 짧은 순간에 일부 로그 유실 가능성 존재.


8. systemd의 역할

systemd는 리눅스에서 서비스를 실행하고 관리하는 시스템 관리자.

서버가 켜질 때 서비스를 자동 실행하고, 서비스가 죽었을 때 재시작하며, 어떤 사용자 권한으로 실행할지, 표준 출력과 표준 에러를 어디로 보낼지 등을 관리.

예시.

 
[Unit]
Description=Mobile API Server

[Service]
User=mobile
WorkingDirectory=/opt/mobile
ExecStart=/usr/bin/java -jar mobile.jar
Restart=always
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
 

여기서 중요한 설정은 다음 부분.

 
StandardOutput=journal
StandardError=journal
 

서비스의 표준 출력과 표준 에러를 systemd journal로 보내는 설정. 이 경우 로그는 journalctl 명령으로 확인 가능.

 
journalctl -u mobile.service
journalctl -u mobile.service -f
 

systemd를 사용하면 catalina.out 같은 파일에 stdout/stderr가 쌓이지 않도록 구성 가능. 하지만 이것이 모든 로그 파일에 대해 logrotate가 필요 없다는 의미는 아님.


9. systemd를 쓰면 logrotate가 필요 없을까

항상 그렇지는 않음.

systemd와 logrotate는 역할이 다름.

systemd
→ 서비스를 실행하고 stdout/stderr 처리 방식을 결정

logrotate
→ 일반 파일로 쌓이는 로그를 주기적으로 정리
 

상황별로 보면 다음과 같음.

로그 저장 방식관리 방식
stdout/stderr → journald journald 보관 정책 확인
stdout/stderr → /dev/null 저장되는 로그 없음
stdout/stderr → 일반 파일 logrotate 필요 가능성 높음
Logback → RollingFileAppender Logback rolling 정책 필요
Logback → 단순 FileAppender logrotate 또는 rolling 설정 필요
Tomcat → catalina.out logrotate 필요 가능성 높음

즉, systemd로 서비스를 구성하더라도 애플리케이션이 Logback으로 파일에 직접 쓰고 있다면 해당 파일에 대한 rolling 정책 필요. Tomcat이 catalina.out에 계속 출력하고 있다면 해당 파일 역시 별도 관리 필요.

정확한 표현은 다음에 가까움.

systemd로 stdout/stderr를 journald에 보내면 catalina.out 관리 부담은 줄어들 수 있음
하지만 애플리케이션 로그 파일까지 자동으로 rotate되는 것은 아님
 

10. catalina.out이 위험해지는 이유

catalina.out은 운영 환경에서 디스크 증가 문제의 원인이 되기 쉬운 파일.

주요 이유는 다음과 같음.

stdout과 stderr가 한 파일에 모임
애플리케이션 콘솔 로그가 함께 쌓일 수 있음
반복 에러 발생 시 스택트레이스가 빠르게 누적됨
Logback의 maxHistory, totalSizeCap 관리 대상이 아닐 수 있음
Vector 수집 대상이 아니면 Kibana에서 확인 불가
 

특히 Logback 설정에 ConsoleAppender와 FileAppender가 함께 있으면 같은 로그가 두 경로로 남을 수 있음.

 
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
 

이 경우 흐름은 다음과 같음.

CONSOLE
→ stdout/stderr
→ catalina.out

FILE
→ application.log
→ Vector
→ Kafka
→ Elasticsearch
→ Kibana
 

결과적으로 Kibana에는 application.log 기준 로그만 보이고, catalina.out은 별도로 서버 디스크에서 증가하는 상황 가능.


11. 운영 환경에서 확인할 항목

로그로 인한 디스크 증가가 발생했을 때 확인할 항목.

디스크 사용량 확인

 
df -h
 

어느 파티션이 가득 찼는지 확인.

큰 로그 디렉터리 확인

 
du -sh /var/log/* 2>/dev/null | sort -h
du -sh /usr/local/tomcat/logs/* 2>/dev/null | sort -h
du -sh /opt/*/logs/* 2>/dev/null | sort -h
 

어떤 디렉터리가 커지고 있는지 확인.

Tomcat 로그 확인

 
ls -lh /usr/local/tomcat/logs/
tail -n 100 /usr/local/tomcat/logs/catalina.out
 

catalina.out 크기와 반복 로그 확인.

systemd 서비스 설정 확인

 
systemctl cat mobile.service
 

서비스의 실행 방식과 stdout/stderr 처리 방식 확인.

journald 로그 확인

 
journalctl -u mobile.service -n 100
journalctl -u mobile.service -f
 

systemd journal로 들어가는 로그 확인.

Logback 설정 확인

 
grep -R "ConsoleAppender\|RollingFileAppender\|fileNamePattern\|maxHistory\|totalSizeCap" .
 

콘솔 출력 여부, 파일 로그 여부, rolling 정책 확인.

Tomcat의 catalina.out 설정 확인

 
grep -R "catalina.out\|CATALINA_OUT" /usr/local/tomcat/bin /etc/systemd/system 2>/dev/null
 

catalina.out 생성 방식 확인.

삭제된 파일 점유 여부 확인

 
lsof | grep deleted
 

로그 파일을 삭제했는데도 디스크 사용량이 줄지 않는 경우 존재. 프로세스가 삭제된 파일을 계속 열고 있으면 공간이 바로 반환되지 않을 수 있음. 이 경우 프로세스 재시작 또는 정상적인 로그 파일 해제 필요.

급한 디스크 확보가 필요한 경우 파일 자체 삭제보다 파일 내용만 비우는 방식 사용 가능.

 
: > /usr/local/tomcat/logs/catalina.out
 

파일 핸들을 유지한 채 내용만 비우는 방식. 단, 운영 환경에서는 사전 정책과 영향도 확인 필요.