Menyiapkan Plugin OpenTelemetry Dasar di gRPC Java

1. Pengantar

Dalam codelab ini, Anda akan menggunakan gRPC untuk membuat klien dan server yang membentuk dasar aplikasi pemetaan rute yang ditulis dalam Java.

Pada akhir tutorial ini, Anda akan memiliki aplikasi gRPC HelloWorld sederhana yang diinstrumentasi 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 ada
  • Menjalankan instance Prometheus lokal
  • Mengekspor metrik ke Prometheus
  • Melihat metrik dari dasbor Prometheus

2. Sebelum memulai

Yang akan Anda butuhkan

  • git
  • curl
  • JDK v8 atau yang lebih baru

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 scaffold kode sumber yang telah dibuat sebelumnya untuk membantu Anda memulai. Langkah-langkah berikut akan memandu Anda menginstrumentasi Plugin OpenTelemetry gRPC dalam aplikasi.

grpc-codelabs

Kode sumber scaffold untuk codelab ini tersedia di direktori GitHub ini direktori. Jika Anda tidak ingin menerapkan kode sendiri, kode sumber yang telah selesai tersedia di direktori yang telah selesai.

Pertama, clone repo codelab gRPC dan cd ke folder grpc-java-opentelemetry:

git clone -b v1 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 gRPC OpenTelemetry. Dalam codelab ini, kita akan menggunakan klien dan server gRPC HelloWorld sederhana yang akan kita instrumentasi 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

Membuat pengekspor Prometheus

Buat PrometheusHttpServer untuk mengonversi metrik OpenTelemetry ke format Prometheus dan mengeksposnya melalui HttpServer. Cuplikan kode berikut membuat Pengekspor Prometheus baru.

// Default prometheus port i.e `prometheusPort` has been initialized to 9465
 
PrometheusHttpServer prometheusExporter = PrometheusHttpServer.builder()
        .setPort(prometheusPort)         
        .build();

Membuat instance OpenTelemetry SDK

Daftarkan prometheusExporter yang dibuat 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();

Membuat instance GrpcOpenTelemetry

Dengan menggunakan GrpcOpenTelemetry API, tetapkan OpenTelemetry SDK yang menggunakan pengekspor 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 berikutnya akan diinstrumentasi dengan OpenTelemetry.

Mematikan OpenTelemetry SDK

Penonaktifan harus terjadi di dalam ShutDownHook. openTelemetrySdk.close() mematikan SDK dan juga memanggil penonaktifan di SdkMeterProvider.

Menyiapkan instrumentasi di server

Demikian pula, mari kita tambahkan GrpcOpenTelemetry ke server. Buka codelabs/grpc-java-opentelemetry/start_here/src/main/java/io/grpc/codelabs/opentelemetry/OpenTelemetryServer.java dan tambahkan kode untuk menginisialisasi GrpcOpenTelemetry.

Membuat pengekspor 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();

Membuat instance OpenTelemetry SDK

SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
        .registerMetricReader(prometheusExporter)
        .build();

Menginisialisasi GrpcOpenTelemetry dengan OpenTelemetry SDK

OpenTelemetrySdk openTelemetrySdk =OpenTelemetrySdk.builder()
        .setMeterProvider(sdkMeterProvider)
        .build();

Membuat instance GrpcOpenTelemetry

GrpcOpenTelemetry grpcOpenTelmetry = GrpcOpenTelemetry.newBuilder()
        .sdk(openTelemetrySdk)
        .build();
    // Registers gRPC OpenTelemetry globally.
grpcOpenTelmetry.registerGlobal();

Mematikan OpenTelemetry SDK

Setelah saluran gRPC dimatikan. Memanggil openTelemetrySdk.close() mematikan SDK dan juga memanggil penonaktifan di SdkMeterProvider.

4. Menjalankan contoh dan melihat metrik

Untuk menjalankan server, jalankan -

cd start_here
../gradlew installDist
./build/install/start_here/bin/opentelemetry-server

Dengan penyiapan yang 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

Jalankan 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 berbentuk -

# 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 melakukan scraping klien dan server contoh gRPC yang mengekspor metrik menggunakan Prometheus.

Unduh rilis terbaru Prometheus untuk platform Anda, lalu ekstrak dan eksekusi:

tar xvfz prometheus-*.tar.gz
cd prometheus-*

Buat file konfigurasi Prometheus dengan yang berikut -

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 untuk di-scraping 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 percobaan median menggunakan 1 menit sebagai jendela waktu untuk perhitungan kuantil.

Frekuensi 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 memiliki satu RPC yang tertunda pada waktu tertentu. Hal ini dapat diubah sehingga klien mengirim lebih banyak RPC tanpa menunggu yang sebelumnya selesai. (Solusi untuk hal ini belum diberikan.)