Episode ini membahas observability dasar: mengaktifkan access logs, memformat log dengan request metadata, menyiapkan health check liveness readiness untuk Envoy, serta mengekspos metrics dalam format Prometheus.

Envoy adalah proxy yang "berbicara" melalui data: setiap request yang lewat bisa dicatat, diukur, dan dipantau. Episode 7 membuka dunia access logging dan basic observability — bagaimana mengaktifkan log per request, menyusun format log yang berisi metadata berguna, memastikan Envoy sendiri sehat melalui endpoint health check, dan mengekspos metrics dalam format Prometheus.
Ini adalah fondasi observability yang akan diperdalam di episode 11 dan 21. Setelah episode ini, kalian tidak hanya punya proxy yang bekerja, tapi proxy yang bisa diajak bicara.
Access log didefinisikan di dalam http_connection_manager:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
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%] %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %RESPONSE_CODE% %DURATION%ms\n"
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: api_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterBagian access_log menambahkan satu logger file yang menulis ke /dev/stdout dengan format khusus. Format ini memakai operator Envoy seperti %START_TIME%, %RESPONSE_CODE%, dan %DURATION% untuk mencetak metadata tiap request.
Setiap request yang melewati Envoy kini tercatat. Uji dengan beberapa request lalu amati log:
curl -s -H "Host: localhost" http://localhost:10000/health
docker logs envoy-obs 2>&1 | tail -5Perintah docker logs envoy-obs menampilkan access log yang tertulis ke stdout kontainer. Setiap baris mewakili satu request lengkap dengan kode respons dan durasi.
Envoy punya ratusan operator format. Yang paling berguna untuk observability dasar:
%REQ(HEADER)?:DEFAULT% — nilai satu request header.%RESP(HEADER)?:DEFAULT% — nilai satu response header.%START_TIME% — waktu request dimulai.%RESPONSE_CODE% — kode status respons.%DURATION% — lama request dalam milidetik.%UPSTREAM_CLUSTER% — cluster yang menangani request.%DOWNSTREAM_REMOTE_ADDRESS% — alamat klien.format: "%DOWNSTREAM_REMOTE_ADDRESS% %REQ(X-FORWARDED-FOR)% %START_TIME% \"%REQ(METHOD)% %REQ(PATH)%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %DURATION%ms %UPSTREAM_HOST%\n"Format %RESPONSE_FLAGS% adalah operator yang mencatat bagaimana request diproses, misalnya URX untuk retry atau UF untuk upstream failure. Flag ini sangat berharga saat debugging, dan akan kembali muncul di episode 21.
Format yang sama bisa ditetapkan sekali untuk semua listener lewat admin.access_log di bootstrap, sehingga tidak perlu menulis ulang format di setiap listener.
Untuk platform seperti Kubernetes, Envoy perlu mengekspos endpoint health check miliknya sendiri. Gunakan admin interface sebagai target:
curl -s localhost:9901/ready
curl -s localhost:9901/livez
curl -s localhost:9901/healthcheck/failEndpoint local:9901/ready mengembalikan 200 jika Envoy siap menerima traffic, dan local:9901/livez menandakan proses masih hidup. Perintah healthcheck/fail sengaja menandai Envoy tidak sehat — teknik yang dipakai platform orchestration untuk menarik traffic sebelum shutdown.
Di Kubernetes, probe tersebut menjadi livenessProbe dan readinessProbe pada pod:
readinessProbe:
httpGet:
path: /ready
port: 9901
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /livez
port: 9901
initialDelaySeconds: 10
periodSeconds: 10Konfigurasi readinessProbe memastikan pod Envoy tidak menerima traffic sebelum benar-benar siap, sementara livenessProbe membuat kubelet me-restart pod yang macet.
Admin interface Envoy sudah menyediakan metrics dalam format Prometheus di satu endpoint:
curl -s localhost:9901/stats/prometheus | head -20
curl -s localhost:9901/stats/prometheus | grep "^envoy_cluster" | head -5Endpoint stats/prometheus menampilkan semua metrics dalam format yang langsung bisa discrape Prometheus. Metric envoy_cluster_* menunjukkan status per cluster: healthy endpoints, request, dan latensi.
Agar Prometheus mengambil data secara berkala, tambahkan job berikut di prometheus.yml:
scrape_configs:
- job_name: envoy
metrics_path: /stats/prometheus
static_configs:
- targets:
- envoy-1:9901
- envoy-2:9901Target envoy-1:9901 memberi tahu Prometheus di mana menemukan endpoint metrics Envoy. Dengan satu job ini, semua metric Envoy masuk ke sistem monitoring dan bisa digambar di Grafana.
Karena jumlah metric Envoy sangat banyak, gunakan filter di admin:
curl -s localhost:9901/stats?filter=envoy_cluster_api_service.upstream_cx_total
curl -s localhost:9901/stats/prometheus?filter=envoy_cluster_api_serviceParameter filter=envoy_cluster_api_service mempersempit output ke satu cluster. Di production, filtering penting untuk menghindari beban parsing ribuan baris metric setiap kali scrape.
Episode 7 memberi kalian indra observability pertama pada Envoy: access log per request dengan format yang bisa disusun, endpoint health check untuk orkestrasi, dan metrics Prometheus yang siap discrape.
Inti yang harus dibawa pulang:
http_connection_manager lewat blok access_log.%REQ(...)%, %RESPONSE_CODE%, dan %DURATION% membentuk log.%RESPONSE_FLAGS% mencatat detail bagaimana request diproses.local:9901/ready dan local:9901/livez untuk health check Envoy sendiri.stats/prometheus mengekspos semua metric dalam format Prometheus.Di episode 8 selanjutnya kita akan membahas Envoy filter chain lanjutan — filter HTTP seperti ext_authz dan gRPC JSON transcoder, filter TCP seperti tcp_proxy, serta urutan dan matching filter yang benar.