# Taxa de sucesso por minuto
rate(transcription_requests_total{status="success"}[1m]) * 60
# p99 de latência do Whisper
histogram_quantile(0.99, rate(transcription_whisper_duration_seconds_bucket[5m]))
# Cache hit ratio
rate(transcription_cache_total{result="hit"}[5m])
/ (rate(transcription_cache_total{result="hit"}[5m])
+ rate(transcription_cache_total{result="miss"}[5m]) + 0.0001)
# Estado do circuit breaker (0=fechado, 1=aberto)
resilience4j_circuitbreaker_state{name="whisper"}
# Chamadas não-permitidas pelo CB (circuito aberto)
rate(resilience4j_circuitbreaker_calls_seconds_count{name="whisper",kind="not_permitted"}[1m])
O requestId também é incluído no ProblemDetail de respostas de erro,
permitindo que o cliente correlacione um erro 4xx/5xx com os logs do servidor.
O header X-Request-Id é propagado em todas as respostas HTTP.
Tracing distribuído v2.7.0
OpenTelemetry SDK via micrometer-tracing-bridge-otel.
Exportação para Zipkin com opentelemetry-exporter-zipkin.
Sampling 100% (ajustável via TRACING_SAMPLING env).
Spans automáticos por requisição
Span
O que cobre
HTTP POST /api/transcriptions
Span raiz — toda a requisição de entrada
WebClient POST /v1/audio/transcriptions
Chamada ao Speaches (Whisper)
Redis GET/SET
Leitura e escrita no cache (automático via Spring Data)
Acessar Zipkin
# Subir ambiente
docker compose up -d # ou docker compose -f docker-compose.dev.yml up -d
# Fazer uma transcrição
curl -s -X POST http://localhost:8080/api/transcriptions \
-H "Authorization: Bearer $TOKEN" \
-F "file=@audio.wav;type=audio/wav"
# Abrir UI
open http://localhost:9411
# Pesquisar por: Service Name = "dio-speech-ai"