Spring 모니터링 Part 2.

Micrometer Tracing으로 traceId 연결

요청 하나를 여러 span으로 나눈다

요청 ID는 로그 검색의 시작점이지만, 서비스가 다른 API를 호출하거나 메시지를 발행하면 흐름이 금방 넓어진다. 이때는 traceId로 전체 흐름을 묶고 spanId로 각 작업 구간을 구분한다. Spring Boot Actuator는 Micrometer Tracing 자동 구성을 제공하므로, 추적 라이브러리와 내보내기 방식을 정하면 HTTP 요청에서 관측 데이터가 만들어진다.

아래 예시는 Brave와 Zipkin 조합을 쓰는 최소 의존성이다. 실제 운영에서는 조직의 수집 백엔드에 맞춰 OpenTelemetry OTLP 같은 조합으로 바꿀 수 있다.

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-actuator"
    implementation "io.micrometer:micrometer-tracing-bridge-brave"
    implementation "io.zipkin.reporter2:zipkin-reporter-brave"
}

샘플링 비율은 환경별로 다르게 둔다. 로컬 검증에서는 1.0이 편하지만, 운영에서는 트래픽과 저장 비용을 보고 낮춘다.

로그와 traceId를 같은 화면에서 본다

management.tracing.sampling.probability=1.0
logging.pattern.correlation=[${spring.application.name:},%X{traceId:-},%X{spanId:-}]
logging.include-application-name=false

Micrometer Tracing이 활성화되면 Spring Boot는 로그에 상관 ID를 포함할 수 있다. 위 설정은 로그 패턴에서 애플리케이션 이름, traceId, spanId를 명시적으로 보이게 한다. 구조화 로그를 함께 사용한다면 같은 MDC 값이 JSON 필드로도 남아 로그 검색과 trace 화면 이동이 쉬워진다.

자동 구성된 클라이언트를 사용한다

@Configuration
class ClientConfig {
    @Bean
    RestClient inventoryClient(RestClient.Builder builder) {
        return builder
                .baseUrl("https://inventory.internal")
                .build();
    }
}

중요한 점은 new RestTemplate()이나 RestClient.create()처럼 직접 만든 클라이언트가 아니라, Spring Boot가 제공하는 builder를 사용하는 것이다. 자동 구성된 RestClient.Builder, RestTemplateBuilder, WebClient.Builder를 거치면 네트워크 호출에도 추적 컨텍스트가 전달된다.

검증은 API를 한 번 호출하고 로그의 traceId로 Zipkin이나 사용 중인 백엔드에서 같은 trace를 찾는 방식으로 한다. 로그 줄은 문제 발생 시점을 보여 주고, trace는 어느 외부 호출이나 내부 구간에서 시간이 쓰였는지 보여 준다.

댓글