Episode ini mengintegrasikan telemetry Envoy ke ekosistem: metrics ke Prometheus, distributed tracing dengan Zipkin, Jaeger, dan OpenTelemetry, serta enrichment access log untuk observability yang lebih dalam.

Episode 7 memperkenalkan access log dan metrics dasar. Episode 11 membawa observability ke level ekosistem: metrics ke Prometheus untuk aggregasi, distributed tracing dengan Zipkin, Jaeger, dan OpenTelemetry untuk melacak satu request melewati banyak service, serta access log enrichment agar log membawa konteks yang cukup untuk di-correlate.
Ini adalah episode jembatan: setelah ini, kalian tidak hanya punya data mentah dari Envoy, tapi sistem yang bisa menjawab pertanyaan "di mana request ini lambat?" dan "service mana yang paling banyak error?".
Envoy menghitung metrics internal dan mengeksposnya lewat admin interface. Untuk production, pastikan statistik aktif dan dikirim ke server statsd atau di-scrape Prometheus:
stats_config:
stats_tags:
- tag_name: cluster
regex: "^cluster\\.(.+?)\\.(upstream|membership)\\."
- tag_name: listener
regex: "^listener\\.(.+?)\\."
stats_flush_interval: 30sBlok stats_config mendefinisikan tag yang diekstrak dari nama metric. Dengan regex di atas, metric cluster.orders_service.upstream_rq_total otomatis diberi label cluster bernilai orders_service, sehingga Prometheus bisa meng-aggregate per cluster.
scrape_configs:
- job_name: envoy
metrics_path: /stats/prometheus
static_configs:
- targets:
- envoy-1:9901
relabel_configs:
- source_labels: [__address__]
target_label: instanceTarget envoy-1:9901 menunjuk admin interface setiap Envoy. Relabel instance memberi label unik per instance sehingga metrics dari banyak Envoy bisa dibedakan.
Beberapa metric yang selalu layak dilihat:
envoy_cluster_upstream_rq_total dan envoy_cluster_upstream_rq_time untuk volume dan latensi.envoy_cluster_upstream_rq_5xx untuk error rate per cluster.envoy_listener_downstream_cx_active untuk koneksi aktif per listener.envoy_cluster_membership_healthy untuk jumlah endpoint sehat.curl -s localhost:9901/stats/prometheus | grep "envoy_cluster_upstream_rq_time"Perintah curl localhost:9901/stats/prometheus mengambil metrics langsung dalam format Prometheus. Di Grafana, kalian bisa menggambar latensi dengan query seperti histogram_quantile(0.99, sum(rate(envoy_cluster_upstream_rq_time_bucket[5m])) by (le, cluster)).
Distributed tracing memungkinkan satu request dilacak melintasi banyak proxy dan service. Konfigurasi tracer dilakukan di bootstrap:
tracing:
http:
name: envoy.tracers.opentelemetry
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.Tracing
http:
name: envoy.tracers.opentelemetry
typed_config:
"@type": type.googleapis.com/envoy.tracers.opentelemetry.v3.OpenTelemetryConfig
grpc_service:
envoy_grpc:
cluster_name: otel_collector
service_name: envoy-gatewayBlok tracing menghubungkan Envoy ke collector OpenTelemetry via gRPC. Setiap request yang melewati Envoy menghasilkan span dengan service_name envoy-gateway, membentuk bagian dari trace yang sama.
Untuk Jaeger atau Zipkin, ganti tracer:
tracing:
http:
name: envoy.tracers.zipkin
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.Tracing
http:
name: envoy.tracers.zipkin
typed_config:
"@type": type.googleapis.com/envoy.tracers.zipkin.v3.ZipkinConfig
collector_cluster_name: zipkin_collector
collector_endpoint: /api/v2/spans
collector_endpoint_version: HTTP_JSONKonsep collector_cluster_name sama untuk semua tracer: Envoy mengirim span ke cluster yang menunjuk collector. Karena tracer Otel kini yang paling umum, banyak tim mengganti langsung ke OpenTelemetry Collector sebagai tujuan tunggal.
Tracing bekerja karena header di-propagasi antar service. Envoy membaca dan meneruskan header seperti traceparent (W3C) dan x-b3-traceid (Zipkin). Pastikan aplikasi backend ikut meneruskan header ini, jika tidak trace akan terputus di service pertama.
Access log bisa diperkaya dengan ID trace sehingga mudah di-correlate dengan data tracing:
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /dev/stdout
format: "%START_TIME% %DOWNSTREAM_REMOTE_ADDRESS% %REQ(X-REQUEST-ID)% traceid=%REQ(TRACEPARENT)% %RESPONSE_CODE% %DURATION%ms %UPSTREAM_CLUSTER%\n"Format di atas menambahkan %REQ(TRACEPARENT)% dan %REQ(X-REQUEST-ID)% ke setiap baris log. Dengan konteks ini, kalian bisa mengambil satu trace ID lalu menemukan semua baris log yang terkait di seluruh service.
Envoy juga bisa otomatis menambahkan x-request-id jika belum ada:
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
start_child_span: trueNilai start_child_span: true membuat router membuat child span per request, memperkaya trace di sisi Envoy. Header x-request-id yang sama bisa dipakai untuk menggabungkan access log di semua hop.
Untuk memastikan semua terhubung:
curl -s -H "Host: api.example.com" http://localhost:10000/api/orders
docker logs jaeger 2>&1 | tail -5Setelah request dikirim, buka UI Jaeger di port 16686 dan cari trace dengan service envoy-gateway. Perintah docker logs jaeger adalah cara cepat melihat apakah span sudah tiba di collector.
Episode 11 menghubungkan Envoy dengan ekosistem observability: metrics Prometheus yang kaya label, tracing terdistribusi melalui OpenTelemetry, Zipkin, dan Jaeger, serta access log yang membawa konteks trace dan request ID.
Inti yang harus dibawa pulang:
stats_config dengan regex tag membuat metric Envoy mudah di-aggregate per cluster.traceparent harus di-propagasi aplikasi agar trace utuh.x-request-id membuat satu request bisa dilacak di semua hop Envoy.Di episode 12 selanjutnya kita akan membahas secure service-to-service communication — Envoy sebagai gateway aman untuk microservices, TLS context dan certificate validation, serta authorization policies dengan filter RBAC.