로깅 가이드

SLF4J + Logback 기반 로깅 규칙 및 운영 설정

마지막 수정: 2026-05

로깅 가이드

기본 원칙

  • System.out.println 사용 금지 → @Slf4j 사용
  • 문자열 "+" 연산 금지 → {} 바인딩 포맷팅 사용
  • 로그에 비밀번호, 카드번호, 개인정보 출력 금지
  • 운영 환경에서 DEBUG 비활성화

로거 선언

// @Slf4j 어노테이션 사용 (권장)
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    // log.info(), log.warn(), log.error() 바로 사용
}

// 또는 직접 선언
private static final Logger log = LoggerFactory.getLogger(UserService.class);

System.out.println 사용 금지

// 잘못된 예 — 절대 금지
System.out.println("사용자 조회: " + userId);

// 올바른 예 — @Slf4j 사용
log.info("사용자 조회: userId={}", userId);

문자열 "+" 연산 금지 → {} 바인딩 사용

// 잘못된 예 — "+" 연산 (성능 저하, DEBUG 레벨에서도 문자열 생성)
log.info("사용자 조회: userId=" + userId + ", userNm=" + userNm);

// 올바른 예 — {} 바인딩 포맷팅
log.info("사용자 조회: userId={}, userNm={}", userId, userNm);

로그 레벨 기준

레벨사용 상황예시
ERROR장애, 복구 불가능한 오류DB 연결 실패, 외부 API 오류
WARN주의, 비정상이지만 계속 가능재시도, 예상치 못한 상태
INFO주요 비즈니스 흐름로그인 성공, 배치 시작/완료
DEBUG개발용 상세 정보파라미터 값, 중간 계산
TRACE아주 상세한 추적 정보메서드 진입/종료

올바른 로깅 예시

// INFO — 주요 비즈니스 이벤트
log.info("사용자 등록 완료: userId={}", vo.getUserId());
log.info("배치 시작: batchId={}", batchId);

// WARN — 비정상이지만 계속 가능한 상황
log.warn("로그인 실패: userId={}", userId);
log.warn("외부 API 응답 지연: url={}, elapsed={}ms", url, elapsed);

// ERROR — 스택트레이스 포함
log.error("사용자 등록 실패: userId={}", vo.getUserId(), e);
log.error("DB 연결 실패", e);

// DEBUG — 개발 환경에서만
log.debug("쿼리 파라미터: keyword={}, page={}", keyword, page);

잘못된 로깅 (금지)

// 개인정보 출력 금지
log.info("사용자: email={}, phone={}", email, phone);   // 금지
log.info("로그인: password={}", password);               // 절대 금지
log.info("카드번호: cardNo={}", cardNo);                  // 금지
log.info("API 키: key={}", apiKey);                      // 금지

// System.out.println 금지
System.out.println("처리 완료");  // 금지

// "+" 연산 금지
log.info("결과: " + result);      // 금지

application.yml 로깅 설정

logging:
  level:
    root: INFO
    com.{회사명}.{프로젝트명}: INFO
    org.springframework.web: WARN
    org.mybatis: WARN

Logback 운영 설정 (logback-spring.xml)

<!-- src/main/resources/logback-spring.xml -->
<configuration>
    <springProfile name="prod">
        <!-- 운영 환경: 파일 출력 (rolling) -->
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>/var/log/{서비스명}/app.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>/var/log/{서비스명}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <root level="INFO">
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>
</configuration>

체크리스트

  • [ ] System.out.println 사용 금지 → @Slf4j + log.* 사용
  • [ ] 문자열 "+" 연산 금지 → {} 바인딩 사용
  • [ ] 로그에 비밀번호, 카드번호, 개인정보 미포함
  • [ ] 운영 환경 DEBUG 로그 비활성화
  • [ ] 예외 로그: log.error("설명", e) — 스택트레이스는 로그에만
  • [ ] 로거는 클래스별로 선언 (@Slf4j 또는 직접 선언)