gRPC Python-এ বেসিক OpenTelemetry প্লাগইন সেটআপ করুন

১. ভূমিকা

এই কোডল্যাবে, আপনি gRPC ব্যবহার করে একটি ক্লায়েন্ট ও সার্ভার তৈরি করবেন, যা পাইথনে লেখা একটি রাউট-ম্যাপিং অ্যাপ্লিকেশনের ভিত্তি তৈরি করবে।

এই টিউটোরিয়ালটি শেষে, আপনি gRPC OpenTelemetry প্লাগইন দ্বারা সজ্জিত একটি সাধারণ gRPC HelloWorld অ্যাপ্লিকেশন তৈরি করতে পারবেন এবং Prometheus-এ এক্সপোর্ট করা অবজার্ভেবিলিটি মেট্রিকগুলো দেখতে সক্ষম হবেন।

আপনি যা শিখবেন

  • বিদ্যমান gRPC পাইথন অ্যাপ্লিকেশনের জন্য OpenTelemetry প্লাগইন কীভাবে সেটআপ করবেন
  • স্থানীয় প্রমিথিউস ইনস্ট্যান্স চালানো হচ্ছে
  • প্রমিথিউসে মেট্রিক্স রপ্তানি করা
  • প্রমিথিউস ড্যাশবোর্ড থেকে মেট্রিক্স দেখুন

২. শুরু করার আগে

তোমার যা লাগবে

  • গিট
  • কার্ল
  • নির্মাণ-অত্যাবশ্যক
  • পাইথন ৩.৯ বা উচ্চতর সংস্করণ। প্ল্যাটফর্ম-নির্দিষ্ট পাইথন ইনস্টলেশন নির্দেশাবলীর জন্য, পাইথন সেটআপ এবং ব্যবহার দেখুন। বিকল্পভাবে, uv বা pyenv-এর মতো টুল ব্যবহার করে একটি নন-সিস্টেম পাইথন ইনস্টল করুন।
  • পাইথন প্যাকেজ ইনস্টল করার জন্য পিপ (pip ) ভার্সন ৯.০.১ বা তার উচ্চতর সংস্করণ প্রয়োজন।
  • পাইথন ভার্চুয়াল এনভায়রনমেন্ট তৈরি করার জন্য venv ব্যবহৃত হয়।

পূর্বশর্তগুলো ইনস্টল করুন:

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

কোডটি নিন

আপনার শেখার প্রক্রিয়াকে সহজ করতে, এই কোডল্যাবটি আপনাকে কাজ শুরু করার জন্য একটি পূর্ব-নির্মিত সোর্স কোড কাঠামো প্রদান করে। নিম্নলিখিত ধাপগুলো আপনাকে একটি অ্যাপ্লিকেশনে gRPC OpenTelemetry প্লাগইনটি ইন্সট্রুমেন্ট করার বিষয়ে নির্দেশনা দেবে।

grpc-codelabs

এই কোডল্যাবের স্কাফোল্ড সোর্স কোড এই গিটহাব ডিরেক্টরিতে পাওয়া যাচ্ছে। আপনি যদি নিজে কোডটি ইমপ্লিমেন্ট করতে না চান, তবে সম্পূর্ণ সোর্স কোডটি completed ডিরেক্টরিতে পাওয়া যাবে।

প্রথমে, grpc কোডল্যাব রিপোটি ক্লোন করুন এবং grpc-python-opentelemetry ফোল্ডারে প্রবেশ করুন:

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

বিকল্পভাবে, আপনি শুধু কোডল্যাব ডিরেক্টরি সম্বলিত .zip ফাইলটি ডাউনলোড করে ম্যানুয়ালি আনজিপ করতে পারেন।

আপনার প্রোজেক্টের ডিপেন্ডেন্সিগুলোকে সিস্টেম প্যাকেজ থেকে আলাদা রাখতে প্রথমে একটি নতুন পাইথন ভার্চুয়াল এনভায়রনমেন্ট (venv) তৈরি করা যাক:

python3 -m venv --upgrade-deps .venv

bash/zsh শেলে ভার্চুয়াল এনভায়রনমেন্ট সক্রিয় করতে:

source .venv/bin/activate

উইন্ডোজ এবং অ-প্রমিত শেলগুলির জন্য, https://docs.python.org/3/library/venv.html#how-venvs-work -এ দেওয়া সারণিটি দেখুন।

এরপর, নিম্নলিখিত কমান্ড ব্যবহার করে এনভায়রনমেন্টে ডিপেন্ডেন্সিগুলো ইনস্টল করুন:

python -m pip install -r requirements.txt

৩. ওপেনটেলিমেট্রি প্লাগইনটি নিবন্ধন করুন

gRPC OpenTelemetry প্লাগইনটি যুক্ত করার জন্য আমাদের একটি gRPC অ্যাপ্লিকেশন প্রয়োজন। এই কোডল্যাবে, আমরা একটি সাধারণ gRPC HelloWorld ক্লায়েন্ট এবং সার্ভার ব্যবহার করব, যেটিকে আমরা gRPC OpenTelemetry প্লাগইন দিয়ে ইন্সট্রুমেন্ট করব।

আপনার প্রথম পদক্ষেপ হলো ক্লায়েন্টে প্রমিথিউস এক্সপোর্টার দিয়ে কনফিগার করা ওপেনটেলিমেট্রি প্লাগইনটি রেজিস্টার করা। আপনার পছন্দের এডিটর দিয়ে start_here/observability_greeter_client.py খুলুন। প্রথমে সম্পর্কিত ডিপেন্ডেন্সি এবং ম্যাক্রো যোগ করে এটিকে এইরকম করে তুলুন -

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

তারপর run() কে এমনভাবে রূপান্তর করুন -

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()

পরবর্তী ধাপ হলো সার্ভারে OpenTelemetry প্লাগইনটি যুক্ত করা। start_here/observability_greeter_server.py খুলুন এবং সম্পর্কিত ডিপেন্ডেন্সি ও ম্যাক্রোগুলো যোগ করে এটিকে এইরকম করে তুলুন -

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

তারপর run() কে এমনভাবে রূপান্তর করুন -

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()

৪. উদাহরণটি চালানো এবং মেট্রিক্স দেখা

সার্ভারটি চালু করতে, চালান -

cd start_here
python -m observability_greeter_server

সফলভাবে সেটআপ সম্পন্ন হলে, আপনি সার্ভারের জন্য নিম্নলিখিত আউটপুট দেখতে পাবেন -

Server started, listening on 50051

সার্ভারটি চালু থাকা অবস্থায়, অন্য একটি টার্মিনালে ক্লায়েন্টটি চালান -

# 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

একটি সফল দৌড় দেখতে এইরকম হবে -

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

যেহেতু আমরা প্রোমিথিউস ব্যবহার করে মেট্রিক্স এক্সপোর্ট করার জন্য gRPC OpenTelemetry প্লাগইনটি সেট-আপ করেছি, সেই মেট্রিক্সগুলো সার্ভারের জন্য localhost:9464 এবং ক্লায়েন্টের জন্য localhost:9465-এ উপলব্ধ হবে।

ক্লায়েন্টের মেট্রিক্স দেখতে -

curl localhost:9465/metrics

ফলাফলটি এই ধরনের হবে -

# 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

একইভাবে, সার্ভার সাইড মেট্রিক্সের জন্য -

curl localhost:9464/metrics

৫. প্রোমিথিউসে মেট্রিক্স দেখা

এখানে, আমরা একটি প্রোমিথিউস ইনস্ট্যান্স সেটআপ করব যা আমাদের gRPC উদাহরণ ক্লায়েন্ট এবং সার্ভার থেকে মেট্রিক্স স্ক্র্যাপ করবে, যেগুলো প্রোমিথিউস ব্যবহার করে মেট্রিক্স এক্সপোর্ট করছে।

প্রদত্ত লিঙ্কটি ব্যবহার করে আপনার প্ল্যাটফর্মের জন্য প্রোমিথিউসের সর্বশেষ রিলিজটি ডাউনলোড করুন , অথবা নিম্নলিখিত কমান্ডটি ব্যবহার করুন:

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

তারপর নিম্নলিখিত কমান্ডটি ব্যবহার করে এটি এক্সট্র্যাক্ট করুন এবং চালান:

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

নিম্নলিখিত বিষয়গুলো অন্তর্ভুক্ত করে একটি প্রোমিথিউস কনফিগারেশন ফাইল তৈরি করুন -

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

নতুন কনফিগারেশন দিয়ে প্রোমিথিউস চালু করুন -

./prometheus --config.file=grpc_otel_python_prometheus.yml

এটি ক্লায়েন্ট এবং সার্ভার কোডল্যাব প্রসেসগুলো থেকে প্রতি ৫ সেকেন্ড পর পর মেট্রিক্স স্ক্র্যাপ করার জন্য কনফিগার করবে।

মেট্রিকগুলো দেখতে http://localhost:9090/graph- এ যান। উদাহরণস্বরূপ, কোয়েরিটি হলো -

histogram_quantile(0.5, rate(grpc_client_attempt_duration_seconds_bucket[1m]))

কোয়ান্টাইল গণনার জন্য ১ মিনিটের টাইম উইন্ডো ব্যবহার করে মিডিয়ান অ্যাটেম্পট ল্যাটেন্সির একটি গ্রাফ দেখানো হবে।

অনুসন্ধানের হার -

increase(grpc_client_attempt_duration_seconds_bucket[1m])

৬. (ঐচ্ছিক) ব্যবহারকারীর জন্য অনুশীলন

প্রমিথিউস ড্যাশবোর্ডগুলোতে আপনি লক্ষ্য করবেন যে QPS কম। উদাহরণটিতে এমন কোনো সন্দেহজনক কোড খুঁজে বের করার চেষ্টা করুন যা QPS কমিয়ে দিচ্ছে।

যারা এই বিষয়ে আগ্রহী, তাদের জন্য ক্লায়েন্ট কোডটি একটি নির্দিষ্ট মুহূর্তে শুধুমাত্র একটি পেন্ডিং RPC রাখার মধ্যে নিজেকে সীমাবদ্ধ রাখে। এটিকে এমনভাবে পরিবর্তন করা যেতে পারে যাতে ক্লায়েন্ট আগের RPC-গুলো সম্পূর্ণ হওয়ার জন্য অপেক্ষা না করেই আরও RPC পাঠাতে পারে। (এর সমাধান এখনও প্রদান করা হয়নি।)