로깅, 왜 해야할까?

2025. 8. 2.

 

새벽 3시에 울리는 장애 알림만큼 개발자를 괴롭히는 것이 또 있을까? 급하게 서버에 접속해서 원인을 찾아보려 하는데, 에러 스택 트레이스도 없고, 언제 어떤 요청에서 문제가 발생했는지도 알 수 없다.

 

이런 경험이 있다면, 왜 로깅이 필요한지 이미 몸소 체감했을 것이다. 로그는 단순히 개발할 때 디버깅용으로만 쓰이는 것이 아니다. 운영 환경에서 시스템의 상태를 파악하고, 장애를 빠르게 해결하며, 사용자 행동을 분석하는 핵심 도구다.

 

 

로깅이 필요한 이유

1. 장애 대응의 핵심

운영 환경에서 발생하는 문제들은 개발 환경에서는 재현되지 않는 경우가 많다. 네트워크 지연, 동시성 문제, 특정 데이터 조합에서만 발생하는 버그들... 이런 문제들을 해결하려면 그 순간의 상황을 기록한 로그가 유일한 단서가 된다.

2. 성능 모니터링

응답 시간이 느려진다는 사용자 신고가 들어왔다. 어느 구간에서 병목이 발생하는지, 데이터베이스 쿼리가 문제인지, 외부 API 호출이 지연되는지... 적절한 로깅 없이는 추측만 할 뿐이다.

3. 사용자 행동 분석

어떤 기능이 많이 사용되는지, 사용자들이 어떤 경로로 서비스를 이용하는지 파악하려면 로그 데이터가 필요하다. 이는 비즈니스 의사결정에도 중요한 근거가 된다.

 

 

로깅 프레임워크 선택: SLF4J + Logback

자바 생태계에는 다양한 로깅 프레임워크가 있다. 우리 피드줍줍 팀이 SLF4J + Logback 조합을 선택한 이유는 다음과 같다.

 

SLF4J: 로깅의 표준 인터페이스

SLF4J(Simple Logging Facade for Java)는 로깅의 인터페이스 역할을 한다. 실제 로깅 구현체(Logback, Log4j2 등)를 바꾸더라도 코드 변경 없이 전환할 수 있다는 장점이 있다.

// SLF4J 인터페이스 사용
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);

logger.info("사용자 {}의 피드백이 저장되었습니다. {}", userId, feedbackId);

 

Logback vs Log4j2

  • Logback: 러닝커브가 낮고, 안정적이며, Spring Boot의 기본 로깅 프레임워크
  • Log4j2: 성능상 더 유리하지만, 설정이 복잡하고 러닝커브가 높음

우리 팀은 현재 성능에 대한 이슈가 없고, 빠른 개발과 안정성을 우선시해서 Logback을 선택했다. 나중에 성능 이슈가 생기면 Log4j2로 전환하는 것도 SLF4J 덕분에 어렵지 않다.

 

 

Logback 설정 파헤치기

1. Appender: 로그를 어디에 출력할 것인가?

Spring Boot의 기본 설정을 사용하지 않고, 우리만의 설정을 구성했다. 가장 중요한 것은 RollingFileAppender다.

<appender name="APP_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <file>${LOGS_ROOT_PATH}/app.log</file>
  
  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>${LOGS_ROOT_PATH}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
    <maxFileSize>10MB</maxFileSize>
    <maxHistory>30</maxHistory>
  </rollingPolicy>
  
  <encoder>
    <pattern>${FILE_LOG_PATTERN}</pattern>
  </encoder>
</appender>
 

2. 롤링 정책: 로그 파일 관리 전략

실제 운영에서는 로그 파일이 계속 쌓이기 때문에 롤링 정책이 중요하다. 우리 팀의 정책은 다음과 같다:

logs/
├── app.log                (현재 쌓이고 있는 로그)
├── 2025-08-02.0.log      (어제 로그)
├── 2025-08-02.1.log      (어제 로그, 10MB 초과시 생성)
├── 2025-08-01.0.log      (그저께 로그)
└── ...

 

로그 파일은 계속 쌓이므로 디스크 용량 모니터링이 필요하다. maxFileSize와 maxHistory 설정을 통해 적절히 관리해야 한다.

현재는 개발 서버: 대략 30일 보관 (maxHistory=30), 운영 서버: 대락 90일 보관 (maxHistory=90)으로 설정했다.

 

3. 로그 패턴과 MDC 활용

<property name="FILE_LOG_PATTERN"
  value="[%d{yyyy-MM-dd HH:mm:ss,Asia/Seoul}] [prod] [%thread] %-5level [%C.%M:%L] [request_id=%X{request_id}] - %msg%n"/>
 

이 패턴에서 주목할 점은 [request_id=%X{request_id}] 부분이다. 이는 **MDC(Mapped Diagnostic Context)**를 활용한 것으로, 분산 시스템에서도 하나의 요청을 추적하는 데 매우 유용하다.

 

현재는 분산 시스템이 아니지만, 멀티 스레드 환경에서 하나의 요청을 식별할 수 있다는 것만으로도 큰 장점이다.

// 컨트롤러나 필터에서 요청마다 고유 ID 설정
MDC.put("request_id", UUID.randomUUID().toString());

try {
    // 비즈니스 로직 실행
    logger.info("사용자 주문 처리 시작");
    orderService.processOrder(order);
    logger.info("사용자 주문 처리 완료");
} finally {
    // 요청 처리 완료 후 정리
    MDC.clear();
}

이렇게 하면 하나의 요청과 관련된 모든 로그를 request_id로 추적할 수 있다.

 

 

로깅은 어쩌면 개발 단계에서는 디버깅 도구지만, 운영 단계에서는 시스템의 건강상태를 파악하는 생명줄이다. 적절한 로깅 전략 없이는 안정적인 서비스 운영이 불가능하다.

 

처음에는 복잡해 보일 수 있지만, 한 번 제대로 설정해두면 장애 상황에서 엄청난 도움이 된다. 새벽 3시에 장애 알림을 받더라도, 로그만 보면 문제의 원인을 빠르게 파악할 수 있다면? 그것만으로도 로깅 설정에 투자한 시간이 충분히 가치 있다고 생각한다.

 

 

 

다음 포스팅에서는 Alloy, Loki, Grafana를 통한 로그 수집과 모니터링에 대해 다뤄보겠습니다. 읽어주셔서 감사합니다~

 

 

 

참고

https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/howto-logging.html

https://docs.spring.io/spring-framework/reference/core/spring-jcl.html

https://docs.spring.io/spring-boot/reference/features/logging.html#features.logging.log4j2-extensions

 

Logging :: Spring Boot

By default, Spring Boot logs only to the console and does not write log files. If you want to write log files in addition to the console output, you need to set a logging.file.name or logging.file.path property (for example, in your application.properties)

docs.spring.io

 

 

서비스 링크

https://github.com/woowacourse-teams/2025-feed-zupzup/

 

GitHub - woowacourse-teams/2025-feed-zupzup

Contribute to woowacourse-teams/2025-feed-zupzup development by creating an account on GitHub.

github.com