노트

로그 레벨과 Logback

Log Levels and Logback

백엔드#spring · 연결된 개념 5개

쉽게 말하면

로그 레벨은 구멍 크기를 고를 수 있는 체 같아요. 평소엔 INFO 이상 굵직한 기록만 걸러 보고, 문제를 찾을 땐 구멍을 좁혀 DEBUG 같은 잔챙이까지 받죠. 코드를 고치지 않고 설정만 바꿔요.

비유가 깨지는 곳 체에 붓기 전에 기록을 만드는 비용도 있어요. 그래서 문자열을 직접 이어 붙이지 않고 {} 자리표시자를 써야 꺼진 레벨에선 문자열을 아예 만들지 않아요. 비밀번호·토큰은 어떤 레벨에도 남기지 않아요.

스프링 부트는 로깅 퍼사드(logging facade) SLF4J(Simple Logging Facade for Java)와 구현체 Logback을 기본으로 쓴다. 코드는 SLF4J API로 로그를 남기고, 어떤 레벨을 어디에 어떤 형식으로 쓸지는 설정으로 정한다.

레벨

레벨용도
ERROR요청 실패 등 즉시 봐야 할 문제
WARN동작은 하지만 이상한 상황
INFO시작·종료·주요 업무 이벤트 (기본)
DEBUG개발 중 진단 정보
TRACE아주 세밀한 흐름

설정한 레벨과 그보다 심각한 레벨만 출력된다. 기본은 INFO라 DEBUG·TRACE는 나오지 않는다. FATAL은 Logback에 없고 ERROR로 다룬다.

설정

logging:
  level:
    root: INFO
    com.example.order: DEBUG
    org.hibernate.SQL: DEBUG        # 실행되는 SQL 보기
  group:
    web: org.springframework.web, org.springframework.security
  • 패키지별, 그룹별로 레벨을 다르게 준다. debug=true는 스프링 내부 로거 일부만 DEBUG로 올린다
  • 기본은 콘솔 출력만 한다. 파일은 logging.file.name이나 logback-spring.xml에서 롤링 정책(rolling policy: 날짜·크기별 분할, 보관 개수)을 정한다
  • 운영에서는 사람이 읽는 형식보다 JSON 구조화 로그(structured logging)가 수집·검색에 유리하다

코드에서

@Slf4j                                   // Lombok: private static final Logger log 생성
public class OrderService {
    void pay(Order o) {
        log.info("결제 요청 orderId={}", o.getId());   // 문자열 결합 대신 {} 자리표시자
        log.debug("상세 {}", o);                       // DEBUG가 꺼져 있으면 toString 호출 안 함
    }
}
  • {} 자리표시자(placeholder)는 레벨이 꺼져 있으면 문자열을 만들지 않는다
  • 예외는 마지막 인자로 넘겨야 스택 트레이스(stack trace)가 남는다: log.error("실패 orderId={}", id, e)
  • 비밀번호·토큰·개인정보는 로그에 남기지 않는다

예외를 잡고 로그만 남긴 채 넘어가는 실수는 예외 삼키기, 디버깅에서 로그의 역할은 디버깅 포켓 가이드 (개요)을 본다. @Slf4j는 Lombok이 만든다.

출처: Spring Boot 문서: Log Levels · Log Groups · File Rotation · Structured Logging

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 저장소 역할 분담 (DB·캐시·큐·검색)

    서버 애플리케이션 옆에는 거의 늘 관계형 DB, 인메모리 캐시, 메시지 브로커(message broker), 검색 엔진이 붙는다. 하나로 다 하지 않는 이유는 데이터의 성격(영구성·속도·전달·검색)마다 잘하는 도구가 다르기 때문이다.

  • 동기·비동기와 블로킹·논블로킹

    동기·비동기는 결과를 언제 어떻게 받느냐, 블로킹·논블로킹은 기다리는 동안 호출한 스레드가 멈추느냐의 문제다.

  • 스프링 부트 자동 설정

    스프링 부트는 스프링 앱을 만들 때 반복되던 설정(의존성 버전 맞추기, 서블릿 컨테이너 연결, 배포)을 관례(convention over configuration)로 대신해 주는 도구다. 클래스패스(classpath)에 무엇이 있는지 보고 필요한 빈을 자동으로 등록하고, 웹 서버를 내장해 java -jar 하나로 실행된다.

  • JDBC와 JdbcTemplate

    JDBC(Java Database Connectivity)는 자바가 여러 DB와 통신하기 위한 표준 API이고, Hibernate·MyBatis·스프링 JDBC 모두 그 위에 있다. JdbcTemplate은 스프링이 JDBC의 반복 작업(연결 열고 닫기, 예외 변환, 결과 순회)을 대신해 주는 클래스다.

  • Kafka

    Kafka는 이벤트(메시지)를 디스크의 추가 전용 로그(append-only log)에 쌓아 두고, 여러 소비자가 각자 읽은 위치를 기억하며 꺼내 가게 하는 분산 이벤트 스트리밍 플랫폼(distributed event streaming platform)이다. 흔히 메시지 큐(message queue)라고 부르지만 동작은 큐보다 로그에 가깝다.

보기 옵션