1. Pengantar
Dalam codelab ini, Anda akan menggunakan gRPC untuk membuat klien dan server yang membentuk dasar aplikasi pemetaan rute yang ditulis dalam java.
Di akhir tutorial, Anda akan memiliki aplikasi gRPC HelloWorld sederhana yang diinstrumentasikan dengan plugin gRPC OpenTelemetry dan dapat melihat metrik kemampuan observasi yang diekspor di Prometheus.
Yang akan Anda pelajari
- Cara menyiapkan Plugin OpenTelemetry untuk aplikasi Java gRPC yang sudah ada
- Menjalankan instance Prometheus lokal
- Mengekspor metrik ke Prometheus
- Melihat metrik dari dasbor Prometheus
2. Sebelum memulai
Yang Anda butuhkan
gitcurlJDKv8 atau yang lebih tinggi
Instal prasyarat:
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y git curl
Mendapatkan kode
Untuk menyederhanakan pembelajaran Anda, codelab ini menawarkan struktur kode sumber bawaan untuk membantu Anda memulai. Langkah-langkah berikut akan memandu Anda menginstrumentasi Plugin OpenTelemetry gRPC dalam aplikasi.
Kode sumber scaffold untuk codelab ini tersedia di direktori GitHub ini. Jika Anda memilih untuk tidak menerapkan kode sendiri, kode sumber yang sudah selesai tersedia di direktori completed.
Pertama, clone repo codelab grpc dan cd ke folder grpc-java-opentelemetry:
git clone https://github.com/grpc-ecosystem/grpc-codelabs.git
cd grpc-codelabs/codelabs/grpc-java-opentelemetry/
Atau, Anda dapat mendownload file .zip yang hanya berisi direktori codelab dan mengekstraknya secara manual.
3. Mendaftarkan Plugin OpenTelemetry
Kita memerlukan aplikasi gRPC untuk menambahkan plugin OpenTelemetry gRPC. Dalam codelab ini, kita akan menggunakan klien dan server gRPC HelloWorld sederhana yang akan kita instrumentasikan dengan plugin gRPC OpenTelemetry.
Langkah pertama Anda adalah mendaftarkan Plugin OpenTelemetry yang dikonfigurasi dengan pengekspor Prometheus di klien. Buka codelabs/grpc-java-opentelemetry/start_here/src/main/java/io/grpc/codelabs/opentelemetry/OpenTelemetryClient.java dengan editor favorit Anda, lalu ubah main untuk menambahkan kode guna menyiapkan gRPC Java OpenTelemetry API.
Menyiapkan instrumentasi di klien
Buat eksportir Prometheus
Buat PrometheusHttpServer untuk mengonversi metrik OpenTelemetry ke format Prometheus dan mengeksposnya melalui HttpServer. Cuplikan kode berikut membuat Prometheus Exporter baru.
// Default prometheus port i.e `prometheusPort` has been initialized to 9465
PrometheusHttpServer prometheusExporter = PrometheusHttpServer.builder()
.setPort(prometheusPort)
.build();
Buat instance SDK OpenTelemetry
Daftarkan prometheusExporter di atas sebagai MetricReader untuk membaca metrik dari SdkMeterProvider. SdkMeterProvider digunakan untuk mengonfigurasi setelan metrik.
SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(prometheusExporter)
.build();
Buat instance OpenTelemetrySdk dengan sdkMeterProvider yang dibuat di atas untuk penerapan SDK OpenTelemetry.
OpenTelemetrySdk openTelemetrySdk =OpenTelemetrySdk.builder()
.setMeterProvider(sdkMeterProvider)
.build();
Buat instance GrpcOpenTelemetry
Dengan menggunakan API GrpcOpenTelemetry, tetapkan SDK OpenTelemetry yang menggunakan eksportir Metrik Prometheus.
GrpcOpenTelemetry grpcOpenTelmetry = GrpcOpenTelemetry.newBuilder()
.sdk(openTelemetrySdk)
.build();
// Registers gRPC OpenTelemetry globally.
grpcOpenTelmetry.registerGlobal();
Setelah instance GrpcOpenTelemetry didaftarkan secara global menggunakan registerGlobal, semua klien dan server gRPC yang dibuat setelahnya akan diinstrumentasikan dengan OpenTelemetry.
Menonaktifkan OpenTelemetry SDK
Penonaktifan harus terjadi di dalam ShutDownHook. openTelemetrySdk.close() mematikan SDK dan juga memanggil shutdown di SdkMeterProvider.
Menyiapkan instrumentasi di server
Demikian pula, mari kita tambahkan GrpcOpenTelemetry ke server juga. Buka codelabs/grpc-java-opentelemetry/start_here/src/main/java/io/grpc/codelabs/opentelemetry/OpenTelemetryServer.java dan tambahkan kode untuk menginisialisasi GrpcOpenTelemetry.
Buat eksportir Prometheus
Karena codelab ini mungkin dijalankan dari mesin yang sama, kita menggunakan port yang berbeda untuk menghosting metrik sisi server gRPC guna menghindari konflik port saat membuat PrometheusHttpServer.
// Default prometheus port i.e `prometheusPort` has been set to 9464
PrometheusHttpServer prometheusExporter = PrometheusHttpServer.builder()
.setPort(prometheusPort)
.build();
Buat instance SDK OpenTelemetry
SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
.registerMetricReader(prometheusExporter)
.build();
Lakukan inisialisasi GrpcOpenTelemetry dengan OpenTelemetry SDK
OpenTelemetrySdk openTelemetrySdk =OpenTelemetrySdk.builder()
.setMeterProvider(sdkMeterProvider)
.build();
Buat instance GrpcOpenTelemetry
GrpcOpenTelemetry grpcOpenTelmetry = GrpcOpenTelemetry.newBuilder()
.sdk(openTelemetrySdk)
.build();
// Registers gRPC OpenTelemetry globally.
grpcOpenTelmetry.registerGlobal();
Menonaktifkan OpenTelemetry SDK
Setelah saluran gRPC dimatikan. Memanggil openTelemetrySdk.close() akan mematikan SDK dan juga memanggil shutdown di SdkMeterProvider.
4. Menjalankan contoh dan melihat metrik
Untuk menjalankan server, jalankan -
cd start_here
../gradlew installDist
./build/install/start_here/bin/opentelemetry-server
Jika penyiapan berhasil, Anda akan melihat output berikut untuk server -
[date and time] io.grpc.codelabs.opentelemetry.OpenTelemetryServer start
INFO: Server started, listening on 50051
Saat server berjalan, di terminal lain, jalankan klien -
./build/install/start_here/bin/opentelemetry-client world
Eksekusi yang berhasil akan terlihat seperti -
[date and time]io.grpc.codelabs.opentelemetry.OpenTelemetryClient greet
INFO: Greeting: Hello world
[date and time] io.grpc.codelabs.opentelemetry.OpenTelemetryClient greet
INFO: Will try to greet world ...
[date and time]io.grpc.codelabs.opentelemetry.OpenTelemetryClient greet
INFO: Greeting: Hello world
Karena kita telah menyiapkan plugin gRPC OpenTelemetry untuk mengekspor metrik menggunakan Prometheus. Metrik tersebut akan tersedia di localhost:9464 untuk server dan localhost:9465 untuk klien.
Untuk melihat metrik klien -
curl localhost:9465/metrics
Hasilnya akan dalam bentuk -
# HELP grpc_client_attempt_duration_seconds Time taken to complete a client call attempt
# TYPE grpc_client_attempt_duration_seconds histogram
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.002"} 0
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.003"} 2
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.004"} 14
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.005"} 29
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.1"} 33
grpc_client_attempt_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="+Inf"} 34
grpc_client_attempt_duration_seconds_count{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 34
grpc_client_attempt_duration_seconds_sum{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 0.46512665300000006
# HELP grpc_client_attempt_rcvd_total_compressed_message_size_bytes Compressed message bytes received per call attempt
# TYPE grpc_client_attempt_rcvd_total_compressed_message_size_bytes histogram
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.0"} 0
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_sum{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 442.0
# HELP grpc_client_attempt_sent_total_compressed_message_size_bytes Compressed message bytes sent per client call attempt
# TYPE grpc_client_attempt_sent_total_compressed_message_size_bytes histogram
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.0"} 0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="1024.0"} 34
grpc_client_attempt_sent_total_compressed_message_size_bytes_sum{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 238.0
# HELP grpc_client_attempt_started_total Number of client call attempts started
# TYPE grpc_client_attempt_started_total counter
grpc_client_attempt_started_total{grpc_method="helloworld.Greeter/SayHello",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 34.0
# HELP grpc_client_call_duration_seconds Time taken by gRPC to complete an RPC from application's perspective
# TYPE grpc_client_call_duration_seconds histogram
grpc_client_call_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.0"} 0
grpc_client_call_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="0.003"} 2
grpc_client_call_duration_seconds_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0",le="+Inf"} 34
grpc_client_call_duration_seconds_count{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 34
grpc_client_call_duration_seconds_sum{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-java",otel_scope_version="1.66.0"} 0.512708707
# TYPE target_info gauge
target_info{service_name="unknown_service:java",telemetry_sdk_language="java",telemetry_sdk_name="opentelemetry",telemetry_sdk_version="1.40.0"} 1
Demikian pula, untuk metrik sisi server -
curl localhost:9464/metrics
5. Melihat metrik di Prometheus
Di sini, kita akan menyiapkan instance prometheus yang akan meng-scrape klien dan server contoh gRPC yang mengekspor metrik menggunakan prometheus.
Download rilis terbaru Prometheus untuk platform Anda, lalu ekstrak dan jalankan:
tar xvfz prometheus-*.tar.gz
cd prometheus-*
Buat file konfigurasi prometheus dengan -
cat > grpc_otel_java_prometheus.yml <<EOF
scrape_configs:
- job_name: "prometheus"
scrape_interval: 5s
static_configs:
- targets: ["localhost:9090"]
- job_name: "grpc-otel-java"
scrape_interval: 5s
static_configs:
- targets: ["localhost:9464", "localhost:9465"]
EOF
Mulai prometheus dengan konfigurasi baru -
./prometheus --config.file=grpc_otel_java_prometheus.yml
Tindakan ini akan mengonfigurasi metrik dari proses codelab klien dan server agar di-scrape setiap 5 detik.
Buka http://localhost:9090/graph untuk melihat metrik. Misalnya, kueri -
histogram_quantile(0.5, rate(grpc_client_attempt_duration_seconds_bucket[1m]))
akan menampilkan grafik dengan latensi upaya median menggunakan 1 menit sebagai jangka waktu untuk penghitungan kuantil.
Rasio kueri -
increase(grpc_client_attempt_duration_seconds_bucket[1m])
6. (Opsional) Latihan untuk Pengguna
Di dasbor Prometheus, Anda akan melihat bahwa QPS rendah. Lihat apakah Anda dapat mengidentifikasi beberapa kode mencurigakan dalam contoh yang membatasi QPS.
Untuk yang antusias, kode klien membatasi dirinya hanya untuk memiliki satu RPC yang tertunda pada saat tertentu. Hal ini dapat diubah sehingga klien mengirim lebih banyak RPC tanpa menunggu RPC sebelumnya selesai. (Solusi untuk masalah ini belum diberikan.)