해당 글에서는 java의 Span 데이터를 Tempo로 수집해서, Tempo의 metrics-generator로 Metrics 데이터로 변환 후 Prometheus로 전송하는 방법을 다룹니다
여기서 Prometheus로 전송하는 Metrics 데이터는 Native Histogram 입니다
구성도는 아래와 같습니다

레포에 있는 helm chart와 작성된 helmfile을 주로 이용합니다
git clone https://github.com/kyeongjun-dev/monitoring.git
cd monitoring/example/docker-compose-springboot-native-histogram
docker-compose.yaml 파일을 이용하여 컨테이너를 실행합니다
docker-compose up -d
가끔 wsl 환경에서 아래와 같이 port를 사용할 수 없다고 뜨는데,
Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3000 -> 127.0.0.1:0: listen tcp 0.0.0.0:3000: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
다음 링크를 참고하여 port를 해제할 수 있습니다 : https://not-to-be-reset.tistory.com/638
실행되는 컨테이너는 tempo, springboot, grafana, prometheus, opentelemetry-collector 총 5개 입니다 - 중간의 tempo가 하나 더 있는건 init 컨테이너 입니다
docker ps -a | grep docker-compose
c175a5ed0b26 grafana/tempo:2.7.1 "/tempo -config.file…" 2 minutes ago Up 2 minutes 0.0.0.0:4675->3200/tcp, 0.0.0.0:4676->4317/tcp docker-compose-springboot-native-histogram-tempo-1
6cff2baaf180 kyeongjundev/springboot:39e2e243b5ddd14f47c35a91f00c068aef13b6ab "java -javaagent:ope…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->8080/tcp docker-compose-springboot-native-histogram-springboot-1
80d8a37fdab1 grafana/grafana:11.0.0 "/run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:3000->3000/tcp docker-compose-springboot-native-histogram-grafana-1
5bf01910095e grafana/tempo:2.7.1 "chown 10001:10001 /…" 2 minutes ago Exited (0) 2 minutes ago docker-compose-springboot-native-histogram-init-1
5b666c812370 prom/prometheus:v3.1.0 "/bin/prometheus --c…" 2 minutes ago Up 2 minutes 0.0.0.0:9090->9090/tcp docker-compose-springboot-native-histogram-prometheus-1
1248a61fe2fb otel/opentelemetry-collector:0.86.0 "/otelcol --config=/…" 2 minutes ago Up 2 minutes 4317/tcp, 55678-55679/tcp docker-compose-springboot-native-histogram-otel-collector-1
tempo.yaml 파일에 아래와 같이 metrics-generator를 활성화 했습니다
여기서 중요한 부분은 span-metrics 입니다. 해당 processor가 span 데이터를 metrics 데이터로 변환합니다
generate_native_histograms에는 [native, classic, both] 가 설정 가능합니다
overrides:
defaults:
metrics_generator:
processors: [service-graphs, span-metrics, local-blocks] # enables metrics generator
generate_native_histograms: native
prometheus.yaml 파일에서는 필수 설정은 아니지만 prometheus와 tempo의 metrics 데이터를 수집하도록 설정 했습니다.
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: [ 'localhost:9090' ]
- job_name: 'tempo'
static_configs:
- targets: [ 'tempo:3200' ]
docker-compose.yaml 파일의 명령어에서 prometheus의 remote write, native histogram 기능을 활성화 했습니다 - prometheus.yaml 파일에서 활성화해도 됩니다
...
prometheus:
image: prom/prometheus:v3.1.0
command:
- --config.file=/etc/prometheus.yaml
- --web.enable-remote-write-receiver
- --enable-feature=exemplar-storage
- --enable-feature=native-histograms
volumes:
- ./prometheus.yaml:/etc/prometheus.yaml
ports:
- "9090:9090"
...
otel-collector.yaml에서는 최소한의 설정으로 springboot에서 전달받은 trace를 tempo로 전송하도록 설정했습니다
exporters에 logging을 설정하면, 실제 trace가 어떻게 전달되는지 otel-collector 컨테이너 로그로 확인할 수 있습니다
receivers:
otlp:
protocols:
grpc:
exporters:
otlp:
endpoint: tempo:4317
tls:
insecure: true
logging:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp, logging]
웹 브라우저에서 아래 endpoint의 8080 포트로 직접 접속해도 되고, clone한 repo의 루트에 있는 sh curl-springboot-delay.sh 스크립트를 실행해도 됩니다
localhost:8080
localhost:8080/ip
localhost:8080/delay?delay=1
sh curl-springboot-delay.sh 8080
prometheus의 NodePort 30080으로 접속하여 쿼리를 실행합니다
traces_spanmetrics_latency
아래와 같이 native-histogram으로 수집된 metrics 데이터를 확인할 수 있습니다
