일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- scala
- DDD
- elasticsearch
- hibernate
- nginx
- Gradle
- elastic search
- hdfs
- Spring XD
- spark
- Hbase
- docker
- 도메인주도설계
- Clean Code
- design pattern
- Spring Batch
- Linux
- 엘라스틱서치
- Storm
- SBT
- 스프링 배치
- apache storm
- 제주
- Java
- 인텔리J
- Angular2
- intellij
- Spring
- hadoop
- Spring Boot
- Today
- Total
욱'S 노트
마이크로미터 오픈텔레메트리 집킨 Exporter 해보기 본문
마이크로미터 오픈텔레메트리 기본 세팅은 지난 시간에 해봤었다. 그럼 Tracing API에 대해서 조금 더 알아보자.
예제 코드
먼저 기본 세팅은 그대로 유지한다.
import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext
import io.micrometer.tracing.otel.bridge.OtelTracer
import io.micrometer.tracing.otel.bridge.Slf4JEventListener
import io.opentelemetry.sdk.OpenTelemetrySdk
fun main() {
// [OTel component] The SDK implementation of OpenTelemetry
val openTelemetrySdk: OpenTelemetrySdk = OpenTelemetrySdk.builder()
.build()
// [OTel component] Tracer is a component that handles the life-cycle of a span
val otelTracer = openTelemetrySdk.tracerProvider.get("io.micrometer.test")
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel
val otelCurrentTraceContext = OtelCurrentTraceContext()
// [Micrometer Tracing component] A Micrometer Tracing listener for setting up MDC
val slf4JEventListener = Slf4JEventListener()
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel's Tracer.
val tracer = OtelTracer(otelTracer, otelCurrentTraceContext, { event ->
slf4JEventListener.onEvent(event)
})
// ... 후략 ...
다음은 스펜이 이미 시작 중인데 다음 스펜을 붙이는 코드이다.
val initSpan = tracer.nextSpan().name("calculateTax")
val newSpan = tracer.nextSpan(initSpan).name("calculateCommission")
try {
tracer.withSpan(newSpan.start())
newSpan.tag("taxValue", "100")
newSpan.event("taxCalculated")
} finally {
newSpan.end()
initSpan.end()
}
println(initSpan)
println(newSpan)
출력된 결과를 보면 같은 트레이스ID에 부모 스펜으로 이전 스팬이 참조되는 걸 확인 할 수 있다.
SdkSpan{traceId=766e4849fd3dec873a104dce4acaafad, spanId=64266dc2fb8d480f, parentSpanContext=ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}, name=calculateTax, kind=INTERNAL, attributes=null, status=ImmutableStatusData{statusCode=UNSET, description=}, totalRecordedEvents=0, totalRecordedLinks=0, startEpochNanos=1741332382998919000, endEpochNanos=1741332388853309542}
SdkSpan{traceId=766e4849fd3dec873a104dce4acaafad, spanId=b9a9621a2e66e564, parentSpanContext=ImmutableSpanContext{traceId=766e4849fd3dec873a104dce4acaafad, spanId=64266dc2fb8d480f, traceFlags=01, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=true}, name=calculateCommission, kind=INTERNAL, attributes=AttributesMap{data={taxValue=100}, capacity=128, totalAddedValues=1}, status=ImmutableStatusData{statusCode=UNSET, description=}, totalRecordedEvents=1, totalRecordedLinks=0, startEpochNanos=1741332383001096083, endEpochNanos=1741332387238214750}
로컬에서 Zipkin 실행하기
집킨 공식 사이트를 보면 Getting Started에 가장 먼저 나오는 방식이 도커를 이용하는 방식이다. 아래의 명령을 사용해서 zipkin 이미지를 로컬에 설치하고 실행시켜보자.
docker pull openzipkin/zipkin
docker run -p 9411:9411 openzipkin/zipkin
브라우저에서 http://localhost:9411/zipkin/ 로 접속하면 다음가 같은 화면을 확인 할 수 있다.
Zipkin으로 Tracing 정보 보내기
Zipkin으로 연동하기 위해서 다음과 같은 설정 코드가 추가된다. 아래의 코드는 사실 프로덕션 레벨에서는 쓸 수 없다. 이유는 성능 때문이다. 보통은 즉시 전송보다는 배치 전송을 http보다는 kafka등의 큐를 이용한다.
fun main() {
// 트레이싱 정보를 Zipkin으로 전송하기 세팅 Endpoint를 지정하면 OkHttp을 이용하여 전송
val spanExporter: SpanExporter = ZipkinSpanExporterBuilder()
.setEndpoint("http://localhost:9411/api/v2/spans")
.build()
// 단순한 스팬 처리기 즉시 전송한다.
val build = SimpleSpanProcessor.builder(spanExporter).build()
// 샘플링이랑 서비스 이름등을 설정
val sdkTracerProvider = SdkTracerProvider.builder()
.setSampler(alwaysOn())
.addResource(Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "my-service")))
.addSpanProcessor(SimpleSpanProcessor.builder(spanExporter).build())
.build()
// B3 Propagation은 Tracing Propagation의 스펙 중 하나, 헤더에 "X-B3-"로 시작
val propagator: ContextPropagators = ContextPropagators.create(B3Propagator.injectingSingleHeader())
val openTelemetrySdk: OpenTelemetrySdk = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(propagator)
.build()
// [OTel component] Tracer is a component that handles the life-cycle of a span
val otelTracer = openTelemetrySdk.tracerProvider.get("io.micrometer.test")
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel
val otelCurrentTraceContext = OtelCurrentTraceContext()
// [Micrometer Tracing component] A Micrometer Tracing listener for setting up MDC
val slf4JEventListener = Slf4JEventListener()
// [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel's Tracer.
val tracer = OtelTracer(otelTracer, otelCurrentTraceContext, { event ->
slf4JEventListener.onEvent(event)
})
... 중략 ...
다시 예제코드를 수행해보자. 화면에 출력된 트레이스 아이디를 집킨에서 조회를 할 수 있다.
참고자료 : https://docs.micrometer.io/tracing/reference/api.html
Using Micrometer Tracing Directly :: Micrometer Tracing
Micrometer Tracing contains @NewSpan, @ContinueSpan, and @SpanTag annotations that frameworks can use to create or customize spans for either specific types of methods such as those serving web request endpoints or, more generally, to all methods. Micromet
docs.micrometer.io
'Programming > Micrometer' 카테고리의 다른 글
오픈텔레메트리 JavaAgent 설정 및 Zipkin Exporter 하기 (OpenTelemetry - JavaAgent - Collector - Zipkin) (0) | 2025.03.21 |
---|---|
OpenTelemetry 개요 및 구성 (2) | 2025.03.14 |
마이크로미터 오픈텔레메트리 트레이싱 시작하기 (Micrometer OpenTelemetry Tracing Getting Started) (2) | 2025.02.17 |
마이크로미터 트레이싱 개요 (Micrometer Tracing Outline) (0) | 2025.02.13 |