Menyiapkan Plugin OpenTelemetry Dasar di gRPC Python

1. Pengantar

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

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 gRPC Python yang ada
  • Menjalankan instance Prometheus lokal
  • Mengekspor metrik ke Prometheus
  • Melihat metrik dari dasbor Prometheus

2. Sebelum memulai

Yang Anda butuhkan

  • git
  • curl
  • build-essential
  • Python 3.9 atau yang lebih tinggi. Untuk mengetahui petunjuk penginstalan Python khusus platform, lihat Penyiapan dan Penggunaan Python. Atau, instal Python non-sistem menggunakan alat seperti uv atau pyenv.
  • pip versi 9.0.1 atau yang lebih tinggi untuk menginstal paket Python.
  • venv untuk membuat lingkungan virtual Python.

Instal prasyarat:

sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y git curl build-essential clang
sudo apt install python3
sudo apt install python3-pip python3-venv

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.

grpc-codelabs

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-python-opentelemetry:

git clone https://github.com/grpc-ecosystem/grpc-codelabs.git
cd grpc-codelabs/codelabs/grpc-python-opentelemetry/

Atau, Anda dapat mendownload file .zip yang hanya berisi direktori codelab dan mengekstraknya secara manual.

Pertama, buat lingkungan virtual python (venv) baru untuk mengisolasi dependensi project Anda dari paket sistem:

python3 -m venv --upgrade-deps .venv

Untuk mengaktifkan lingkungan virtual di shell bash/zsh:

source .venv/bin/activate

Untuk Windows dan shell non-standar, lihat tabel di https://docs.python.org/3/library/venv.html#how-venvs-work.

Selanjutnya, instal dependensi di lingkungan menggunakan:

python -m pip install -r requirements.txt

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 start_here/observability_greeter_client.py dengan editor favorit Anda. Pertama, tambahkan dependensi dan makro terkait agar terlihat seperti ini -

import logging
import time

import grpc
import grpc_observability
import helloworld_pb2
import helloworld_pb2_grpc
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from opentelemetry.sdk.metrics import MeterProvider
from prometheus_client import start_http_server

_SERVER_PORT = "50051"
_PROMETHEUS_PORT = 9465

Kemudian, ubah run() agar terlihat seperti -

def run():
    # Start Prometheus client
    start_http_server(port=_PROMETHEUS_PORT, addr="0.0.0.0")
    meter_provider = MeterProvider(metric_readers=[PrometheusMetricReader()])

    otel_plugin = grpc_observability.OpenTelemetryPlugin(
        meter_provider=meter_provider
    )
    otel_plugin.register_global()

    with grpc.insecure_channel(target=f"localhost:{_SERVER_PORT}") as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        # Continuously send RPCs every second.
        while True:
            try:
                response = stub.SayHello(helloworld_pb2.HelloRequest(name="You"))
                print(f"Greeter client received: {response.message}")
                time.sleep(1)
            except grpc.RpcError as rpc_error:
                print("Call failed with code: ", rpc_error.code())

    # Deregister is not called in this example, but this is required to clean up.
    otel_plugin.deregister_global()

Langkah berikutnya adalah menambahkan plugin OpenTelemetry ke server. Buka start_here/observability_greeter_server.py dan tambahkan dependensi dan makro terkait agar terlihat seperti ini -

from concurrent import futures
import logging
import time

import grpc
import grpc_observability
import helloworld_pb2
import helloworld_pb2_grpc
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from prometheus_client import start_http_server

_SERVER_PORT = "50051"
_PROMETHEUS_PORT = 9464

Kemudian, ubah run() agar terlihat seperti -

def serve():
    # Start Prometheus client
    start_http_server(port=_PROMETHEUS_PORT, addr="0.0.0.0")

    meter_provider = MeterProvider(metric_readers=[PrometheusMetricReader()])

    otel_plugin = grpc_observability.OpenTelemetryPlugin(
        meter_provider=meter_provider
    )
    otel_plugin.register_global()

    server = grpc.server(
        thread_pool=futures.ThreadPoolExecutor(max_workers=10),
    )
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port("[::]:" + _SERVER_PORT)
    server.start()
    print("Server started, listening on " + _SERVER_PORT)

    server.wait_for_termination()

    # Deregister is not called in this example, but this is required to clean up.
    otel_plugin.deregister_global()

4. Menjalankan contoh dan melihat metrik

Untuk menjalankan server, jalankan -

cd start_here
python -m observability_greeter_server

Jika penyiapan berhasil, Anda akan melihat output berikut untuk server -

Server started, listening on 50051

Saat server berjalan, di terminal lain, jalankan klien -

# Run the below commands to cd to the working directory and activate virtual environment in the new terminal
cd grpc-codelabs/codelabs/grpc-python-opentelemetry/
source .venv/bin/activate

cd start_here
python -m observability_greeter_client

Eksekusi yang berhasil akan terlihat seperti -

Greeter client received: Hello You
Greeter client received: Hello You
Greeter client received: Hello You

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 python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 241.0
python_gc_objects_collected_total{generation="1"} 163.0
python_gc_objects_collected_total{generation="2"} 0.0
# HELP python_gc_objects_uncollectable_total Uncollectable objects found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
# HELP python_gc_collections_total Number of times this generation was collected
# TYPE python_gc_collections_total counter
python_gc_collections_total{generation="0"} 78.0
python_gc_collections_total{generation="1"} 7.0
python_gc_collections_total{generation="2"} 0.0
# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="10",patchlevel="9",version="3.10.9"} 1.0
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.868988416e+09
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 4.1680896e+07
# TYPE process_resident_memory_bytes gauge                                                                                                                                                                                                                                                                21:20:16 [154/966]
process_resident_memory_bytes 4.1680896e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.72375679833e+09
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.38
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 9.0
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 4096.0
# HELP target_info Target metadata
# TYPE target_info gauge
target_info{service_name="unknown_service",telemetry_sdk_language="python",telemetry_sdk_name="opentelemetry",telemetry_sdk_version="1.26.0"} 1.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="other",grpc_target="localhost:50051"} 18.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="other",grpc_status="OK",grpc_target="localhost:50051",le="0.0"} 0.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="5.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="10.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="25.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="50.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="75.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="100.0"} 18.0
grpc_client_attempt_sent_total_compressed_message_size_bytes_bucket{grpc_method="other",grpc_status="OK",grpc_target="localhost:50051",le="250.0"} 18.0

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 menggunakan link yang diberikan, atau gunakan perintah berikut:

curl -sLO https://github.com/prometheus/prometheus/releases/download/v3.7.3/prometheus-3.7.3.linux-amd64.tar.gz

Kemudian, ekstrak dan jalankan menggunakan perintah berikut:

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

Buat file konfigurasi prometheus dengan -

cat > grpc_otel_python_prometheus.yml <<EOF
scrape_configs:
  - job_name: "prometheus"
    scrape_interval: 5s
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: "grpc-otel-python"
    scrape_interval: 5s
    static_configs:
      - targets: ["localhost:9464", "localhost:9465"]
EOF

Mulai prometheus dengan konfigurasi baru -

./prometheus --config.file=grpc_otel_python_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.)