gRPC জাভাতে বেসিক OpenTelemetry প্লাগইন সেটআপ করুন

১. ভূমিকা

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

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

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

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

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

আপনার যা যা লাগবে

  • git
  • curl
  • JDK v8 বা উচ্চতর

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

sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y git curl

কোডটি নিন

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

grpc-codelabs

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

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

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

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

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

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

আপনার প্রথম পদক্ষেপ হলো ক্লায়েন্টে প্রমিথিউস এক্সপোর্টার দিয়ে কনফিগার করা ওপেনটেলিমেট্রি প্লাগইনটি রেজিস্টার করা। আপনার পছন্দের এডিটর দিয়ে codelabs/grpc-java-opentelemetry/start_here/src/main/java/io/grpc/codelabs/opentelemetry/OpenTelemetryClient.java ফাইলটি খুলুন, তারপর gRPC জাভা ওপেনটেলিমেট্রি এপিআই সেটআপ করার জন্য কোড যোগ করতে main ফাংশনটি পরিবর্তন করুন।

ক্লায়েন্টে ইন্সট্রুমেন্টেশন সেটআপ করুন

প্রমিথিউস এক্সপোর্টার তৈরি করুন

OpenTelemetry মেট্রিকগুলোকে Prometheus ফরম্যাটে রূপান্তর করতে এবং একটি HttpServer-এর মাধ্যমে এগুলো প্রকাশ করতে একটি PrometheusHttpServer তৈরি করুন। নিম্নলিখিত কোড স্নিপেটটি একটি নতুন Prometheus Exporter তৈরি করে।

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

OpenTelemetry SDK ইনস্ট্যান্স তৈরি করুন

একটি SdkMeterProvider থেকে মেট্রিক পড়ার জন্য উপরে তৈরি করা prometheusExporter MetricReader হিসেবে রেজিস্টার করুন। মেট্রিক সেটিংস কনফিগার করার জন্য SdkMeterProvider ব্যবহৃত হয়।

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

OpenTelemetry- এর SDK বাস্তবায়নের জন্য উপরে তৈরি করা sdkMeterProvider ব্যবহার করে OpenTelemetrySdk-এর একটি ইনস্ট্যান্স তৈরি করুন।

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

GrpcOpenTelemetry ইনস্ট্যান্স তৈরি করুন

GrpcOpenTelemetry API ব্যবহার করে OpenTelemetry SDK সেট করুন, যা Prometheus Metric exporter ব্যবহার করে।

GrpcOpenTelemetry grpcOpenTelmetry = GrpcOpenTelemetry.newBuilder()
        .sdk(openTelemetrySdk)
        .build();

// Registers gRPC OpenTelemetry globally.
grpcOpenTelmetry.registerGlobal();

registerGlobal ব্যবহার করে একবার একটি GrpcOpenTelemetry ইনস্ট্যান্স বিশ্বব্যাপী নিবন্ধিত হয়ে গেলে, পরবর্তীতে তৈরি হওয়া সমস্ত gRPC ক্লায়েন্ট এবং সার্ভার OpenTelemetry দ্বারা সজ্জিত হবে।

ওপেনটেলিমেট্রি এসডিকে বন্ধ করুন

ShutDownHook-এর ভিতরে শাটডাউন করতে হবে। openTelemetrySdk.close() SDK বন্ধ করে দেয় এবং SdkMeterProvider-এর উপরও shutdown কল করে।

সার্ভারে ইন্সট্রুমেন্টেশন সেটআপ করুন

একইভাবে, সার্ভারে GrpcOpenTelemetry-ও যোগ করা যাক। codelabs/grpc-java-opentelemetry/start_here/src/main/java/io/grpc/codelabs/opentelemetry/OpenTelemetryServer.java খুলুন এবং GrpcOpenTelemetry ইনিশিয়ালাইজ করার জন্য কোড যোগ করুন।

প্রমিথিউস এক্সপোর্টার তৈরি করুন

যেহেতু এই কোডল্যাবটি একই মেশিন থেকে চালানো হতে পারে, তাই PrometheusHttpServer তৈরি করার সময় পোর্ট দ্বন্দ্ব এড়াতে আমরা gRPC সার্ভার সাইড মেট্রিক্স হোস্ট করার জন্য একটি ভিন্ন পোর্ট ব্যবহার করছি।

// Default prometheus port i.e `prometheusPort` has been set to 9464

PrometheusHttpServer prometheusExporter = PrometheusHttpServer.builder()
        .setPort(prometheusPort)
        .build();

OpenTelemetry SDK ইনস্ট্যান্স তৈরি করুন

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

OpenTelemetry SDK ব্যবহার করে GrpcOpenTelemetry চালু করুন

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

GrpcOpenTelemetry ইনস্ট্যান্স তৈরি করুন

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

ওপেনটেলিমেট্রি এসডিকে বন্ধ করুন

gRPC চ্যানেলটি শাটডাউন হওয়ার পরে, openTelemetrySdk.close() কল করলে SDK এবং SdkMeterProvider উভয়ই শাটডাউন হয়ে যায়।

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

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

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

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

[date and time] io.grpc.codelabs.opentelemetry.OpenTelemetryServer start
INFO: Server started, listening on 50051

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

./build/install/start_here/bin/opentelemetry-client world

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

[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

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

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

curl localhost:9465/metrics

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

# 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

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

curl localhost:9464/metrics

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

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

আপনার প্ল্যাটফর্মের জন্য প্রোমিথিউসের সর্বশেষ রিলিজটি ডাউনলোড করুন , তারপর এটি এক্সট্র্যাক্ট করে চালান:

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

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

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

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

./prometheus --config.file=grpc_otel_java_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 পাঠাতে পারে। (এর সমাধান এখনও প্রদান করা হয়নি।)