이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Structured Logging은 단순 문자열 로그와 무엇이 다른가?
  • Correlation ID는 Spring 요청 흐름에서 어떤 장애 분석 문제를 줄이는가?
  • 로그를 남길 때 민감 정보와 필드 설계를 어떻게 다뤄야 하는가?

개요

Structured Logging은 로그를 사람이 읽는 문장만이 아니라 검색 가능한 field 집합으로 남기는 방식이다.

timestamp, level, service, endpoint, status, elapsed_ms, correlation_id 같은 값을 일정한 이름으로 남긴다.

Correlation ID는 한 요청이 지나가며 남긴 여러 로그를 묶는 식별자다.

장애 중에는 “오류가 났다”보다 “어떤 요청이 어디까지 갔고 어떤 값으로 실패했는가”를 빨리 찾아야 한다.

왜 필요한가

문자열 로그만 있으면 검색이 어렵다.

같은 오류라도 서비스마다 표현이 다르면 집계와 필터링이 느려진다.

사용자가 보낸 요청 하나가 controller, service, repository, external client를 지나가면 로그가 여러 줄로 흩어진다.

Correlation ID가 없으면 같은 요청의 로그를 시간과 감으로 맞춰야 한다.

운영 장애에서는 이 시간이 그대로 복구 지연으로 이어진다.

필드 설계

기본 필드는 서비스 전체에서 통일한다.

timestamp
level
service
environment
version
correlation_id
trace_id
span_id
http_method
path
status
elapsed_ms
error_code

필드 이름은 자주 바꾸지 않는다.

로그 검색 쿼리, dashboard, alert, incident report가 이 이름에 의존하기 때문이다.

Spring Filter 예시

@Component
class CorrelationIdFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String id = Optional.ofNullable(request.getHeader("X-Correlation-ID"))
                .filter(value -> !value.isBlank())
                .orElse(UUID.randomUUID().toString());
 
        MDC.put("correlation_id", id);
        response.setHeader("X-Correlation-ID", id);
 
        try {
            chain.doFilter(request, response);
        } finally {
            MDC.remove("correlation_id");
        }
    }
}

MDC에 넣은 값은 같은 thread에서 찍히는 로그에 포함할 수 있다.

비동기 처리나 thread pool을 쓰면 MDC 전달이 끊길 수 있으므로 별도 설정이 필요할 수 있다.

로그 예시

{
  "level": "ERROR",
  "service": "order-api",
  "version": "1.8.3-abc1234",
  "correlation_id": "c-7f1",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "path": "/api/orders",
  "status": 500,
  "elapsed_ms": 842,
  "error_code": "ORDER_DB_TIMEOUT"
}

이런 형태는 특정 correlation id, endpoint, error code로 검색하기 쉽다.

로그 메시지에는 사람이 읽을 설명을 넣되, 분석 기준은 field에 둔다.

민감 정보

로그는 장애 분석 자료이면서 개인정보 노출 경로가 될 수 있다.

Authorization header, cookie, password, 주민번호, 카드 번호, 원문 payload는 그대로 남기지 않는다.

사용자 식별이 필요하면 내부 user id도 masking 또는 hash 기준을 정한다.

요청 body 전체를 debug로 찍는 방식은 장애 중에는 편해 보여도 사고 범위를 키운다.

운영 체크리스트

  • 모든 요청 로그에 correlation id가 들어가는가?
  • correlation id가 응답 header에도 반환되는가?
  • service, environment, version field가 공통으로 남는가?
  • endpoint, status, elapsed time, error code가 검색 가능한 field인가?
  • trace id와 correlation id의 관계가 문서화되어 있는가?
  • 민감 header와 request body가 로그에 남지 않는가?
  • 비동기 처리에서도 correlation id가 끊기지 않는가?

장애 신호

  • 사용자가 correlation id를 제공했는데 로그에서 찾을 수 없다.
  • 같은 요청의 controller 로그와 repository 로그를 연결할 수 없다.
  • error log는 많은데 endpoint나 status field가 없어 영향 범위를 모른다.
  • 로그 검색 쿼리가 메시지 문자열에 의존해 자주 깨진다.
  • debug 로그에 token, cookie, request body가 찍힌다.
  • 비동기 이벤트 처리 로그에서 correlation id가 사라진다.

안전한 완화 조치

로그가 부족하다고 운영 중 전체 debug logging을 오래 켜면 안 된다.

필요한 package와 짧은 시간 범위로 제한한다.

민감 정보가 찍혔다면 로그 삭제만으로 끝내지 말고 노출 범위와 credential 회전을 검토한다.

Correlation ID가 누락됐다면 gateway, Spring filter, async executor 중 어디서 끊기는지 확인한다.

장애 중 공유하는 로그는 field와 일부 sample만 남기고 원문 payload는 제거한다.

인프라 담당자와 공유할 자료

문제: 특정 주문 요청 500
service: order-api
time: 2026-07-01 16:05:12 KST
correlation_id: c-7f1
trace_id: 4bf92f...
endpoint: POST /api/orders
status: 500
elapsed_ms: 842
error_code: ORDER_DB_TIMEOUT
민감 정보: payload 공유 제외

공유 자료에는 검색 가능한 식별자와 시간대를 넣어야 같은 로그를 함께 볼 수 있다.

실전 팁

  • 로그 field 이름은 서비스 간 통일한다.
  • correlation id는 요청 시작 지점에서 만들고 끝까지 전달한다.
  • error code는 사용자 메시지와 별도로 운영 분석용으로 둔다.
  • payload logging은 기본적으로 피하고 필요한 경우 masking한다.
  • 장애 회고에는 실제 검색 쿼리와 필드 이름을 남긴다.

위험 신호!

  • 로그 메시지만 있고 field가 없다.
  • correlation id가 서비스마다 다른 header 이름으로 쓰인다.
  • debug 로그로 민감 정보를 확인한다.
  • 로그량을 늘리는 것을 관측성 개선으로 착각한다.
  • 비동기 작업에서 요청 문맥이 끊기는데 방치한다.

확인 질문

확인 질문

  • Structured Logging이 문자열 로그보다 운영에 유리한 이유는 무엇인가?
    • 검색 가능한 field를 기준으로 요청, 오류, 지연, 버전, 환경을 빠르게 필터링하고 집계할 수 있기 때문이다.
  • Correlation ID가 없으면 장애 분석에서 무엇이 어려운가?
    • 같은 요청이 남긴 여러 로그를 묶지 못해 시간대와 감으로 원인 흐름을 재구성해야 한다.
  • 로그에서 가장 조심해야 할 정보는 무엇인가?
    • 인증 정보, cookie, password, 개인정보, 원문 payload처럼 유출되면 보안 사고가 되는 값이다.

참고 문서