معلومات حول تتبُّع الآلات باستخدام OpenTelemetry

1. مقدمة

5af4a7e43b0feaab.png

تاريخ آخر تعديل: 2021-03-05

إمكانية تتبّع بيانات التطبيق

إمكانية تتبّع البيانات وOpenTelemetry

إمكانية تتبّع البيانات هي المصطلح المستخدَم لوصف إحدى سمات النظام. يتيح النظام الذي يتضمّن إمكانية تتبّع البيانات للفرق إمكانية تصحيح أخطاء نظامهم بشكل نشط. في هذا السياق، تشكّل الركائز الثلاث لإمكانية تتبّع البيانات، أي السجلّات والمقاييس وعمليات التتبُّع، أدوات القياس الأساسية التي يحتاج إليها النظام لإتاحة إمكانية تتبّع البيانات.

OpenTelemetry هي مجموعة من المواصفات وحِزم تطوير البرامج (SDK) التي تسرّع عملية قياس حالة التطبيق وتصدير بيانات القياس عن بُعد (السجلّات والمقاييس وعمليات التتبُّع) التي تتطلّبها إمكانية تتبّع البيانات. ‫OpenTelemetry هو معيار مفتوح المصدر ومشروع يعتمد على مساهمات المجتمع ضمن مؤسسة CNCF. باستخدام المكتبات التي يوفّرها المشروع والمنظومة المتكاملة، يمكن للمطوّرين تزويد تطبيقاتهم بالأدوات بطريقة محايدة للمورّدين ومتوافقة مع بنى متعددة.

التتبُّع الموزّع

من بين السجلات والمقاييس وعمليات التتبُّع، تُعدّ عملية التتبُّع بيانات القياس عن بُعد التي توضّح وقت استجابة جزء معيّن من العملية في النظام. خاصةً في عصر الخدمات المصغّرة، يُعدّ التتبُّع الموزّع عاملاً مهمًا لتحديد المشاكل التي تؤدي إلى تأخير الاستجابة في النظام الموزّع بشكل عام.

عند تحليل عمليات التتبُّع الموزّعة، يكون تصور بيانات التتبُّع هو المفتاح لفهم حالات الكمون الإجمالية للنظام في لمحة. في التتبُّع الموزّع، نتعامل مع مجموعة من المكالمات لمعالجة طلب واحد إلى نقطة دخول النظام في شكل عملية تتبُّع تحتوي على عدة فترات.

يمثّل النطاق وحدة فردية من العمل يتم إجراؤها في نظام موزّع، مع تسجيل أوقات البدء والإيقاف. غالبًا ما تكون هناك علاقات هرمية بين الفترات الزمنية. في الصورة أدناه، جميع الفترات الزمنية الأصغر هي فترات زمنية تابعة لفترة زمنية كبيرة بعنوان /messages، ويتم تجميعها في عملية تتبُّع واحدة تعرض مسار العمل خلال أحد الأنظمة.

adbd3ecd69d410cb.png

‫Google Cloud Trace هو أحد الخيارات المتاحة للخدمة الخلفية لتتبُّع البيانات الموزّعة، وهو متكامل بشكل جيد مع المنتجات الأخرى في Google Cloud.

ما ستنشئه

في هذا الدرس التطبيقي حول الترميز، ستسجّل معلومات التتبُّع في الخدمات التي تحمل الاسم "Shakesapp" والتي تعمل على مجموعة Kubernetes على Google Kubernetes Engine. بنية Shakesapp هي كما هو موضح أدناه:

68873c018a7be7de.png

  • يرسل العملاء سلسلة طلب بحث إلى الخادم
  • يقبل الخادم طلب البحث من العميل، ويستردّ جميع أعمال شكسبير بتنسيق نصي من Google Cloud Storage، ويبحث عن الأسطر التي تحتوي على طلب البحث، ويعرض رقم السطر المطابق للعميل.

ستسجّل معلومات التتبُّع في الطلب.

ما ستتعلمه

  • كيفية بدء استخدام مكتبات OpenTelemetry Trace في مشروع Python
  • كيفية إنشاء فترة باستخدام المكتبة
  • كيفية نشر سياقات الامتداد عبر الشبكة بين مكوّنات التطبيق
  • كيفية إرسال بيانات التتبُّع إلى Google Cloud Trace
  • كيفية تحليل التتبُّع على Google Cloud Trace

يوضّح هذا الدرس التطبيقي حول الترميز كيفية قياس حالة التطبيق في الخدمات المصغّرة. لتسهيل الفهم، يحتوي هذا المثال على 3 مكوّنات فقط (مولّد التحميل والعميل والخادم)، ولكن يمكنك تطبيق العملية نفسها الموضّحة في هذا الدرس التطبيقي حول الترميز على أنظمة أكبر وأكثر تعقيدًا.

المتطلبات

  • معرفة لغة Python 3

2. الإعداد والمتطلبات

إعداد البيئة بالسرعة التي تناسبك

إذا لم يكن لديك حساب Google (Gmail أو Google Apps)، عليك إنشاء حساب. سجِّل الدخول إلى "وحدة تحكّم Google Cloud Platform" (console.cloud.google.com) وأنشِئ مشروعًا جديدًا.

إذا كان لديك مشروع حالي، انقر على القائمة المنسدلة لاختيار المشروع في أعلى يمين وحدة التحكّم:

15b8b6ac4d917005.png

وانقر على الزر "مشروع جديد" في مربّع الحوار الناتج لإنشاء مشروع جديد:

7136b3ee36ebaf89.png

إذا لم يكن لديك مشروع، من المفترض أن يظهر لك مربّع حوار مشابه لما يلي لإنشاء مشروعك الأول:

90977ce514204b51.png

يتيح لك مربّع حوار إنشاء المشروع اللاحق إدخال تفاصيل مشروعك الجديد:

6d9573e346e930b4.png

تذكَّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (الاسم أعلاه مستخدَم حاليًا ولن يكون متاحًا لك، نأسف لذلك). سيُشار إليه لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID.

بعد ذلك، إذا لم يسبق لك إجراء ذلك، عليك تفعيل الفوترة في Developers Console من أجل استخدام موارد Google Cloud وتفعيل Cloud Trace API.

eb5325f65619ad6a.png

لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز أكثر من بضعة دولارات، ولكن قد تكون التكلفة أعلى إذا قررت استخدام المزيد من الموارد أو إذا تركتها قيد التشغيل (راجِع قسم "التنظيف" في نهاية هذا المستند). تتوفر أسعار Google Cloud Trace وGoogle Kubernetes Engine وGoogle Artifacat Registry في المستندات الرسمية.

يمكن لمستخدمي Google Cloud Platform الجدد الاستفادة من فترة تجريبية مجانية بقيمة 300 دولار أمريكي، ما يجعل هذا الدرس العملي مجانيًا تمامًا.

إعداد Google Cloud Shell

على الرغم من إمكانية تشغيل Google Cloud وGoogle Cloud Trace عن بُعد من الكمبيوتر المحمول، سنستخدم في هذا الدرس العملي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.

يتم تحميل هذا الجهاز الافتراضي المستند إلى Debian بجميع أدوات التطوير التي تحتاج إليها. توفّر هذه الخدمة دليلًا رئيسيًا دائمًا بسعة 5 غيغابايت وتعمل في Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. وهذا يعني أنّ كل ما تحتاجه لهذا الدرس التطبيقي حول الترميز هو متصفّح (نعم، يمكن استخدامه على جهاز Chromebook).

لتفعيل Cloud Shell من Cloud Console، ما عليك سوى النقر على "تفعيل Cloud Shell" gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A (يستغرق توفير البيئة والاتصال بها بضع لحظات فقط).

ff81d016724c4f67.png

fbe156ee6edfbb2e.png

بعد الاتصال بـ Cloud Shell، من المفترض أن يظهر لك أنّه تمّت المصادقة عليك وأنّ المشروع تمّ ضبطه مسبقًا على PROJECT_ID.

gcloud auth list

ناتج الأمر

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

ناتج الأمر

[core]
project = <PROJECT_ID>

إذا لم يتم ضبط المشروع لسبب ما، ما عليك سوى تنفيذ الأمر التالي:

gcloud config set project <PROJECT_ID>

هل تبحث عن PROJECT_ID؟ يمكنك الاطّلاع على المعرّف الذي استخدمته في خطوات الإعداد أو البحث عنه في لوحة بيانات Cloud Console:

a3e716fc9e7454e9.png

يضبط Cloud Shell أيضًا بعض متغيرات البيئة تلقائيًا، ما قد يكون مفيدًا عند تنفيذ الأوامر المستقبلية.

echo $GOOGLE_CLOUD_PROJECT

ناتج الأمر

<PROJECT_ID>

أخيرًا، اضبط المنطقة التلقائية وإعدادات المشروع.

gcloud config set compute/zone us-central1-f

يمكنك اختيار مجموعة متنوعة من المناطق المختلفة. لمزيد من المعلومات، يُرجى الاطّلاع على الأقاليم والمناطق.

إعداد Python

في هذا الدرس التطبيقي حول الترميز، نستخدم "poetry" لإدارة إصدارات الحِزم بدقة. نفِّذ الأمر التالي على Cloud Shell:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3 -
source $HOME/.poetry/env

إعداد مجموعة Google Kubernetes

في هذا الدرس التطبيقي حول الترميز، ستشغّل مجموعة من الخدمات المصغّرة على Google Kubernetes Engine (GKE). تتضمّن هذه التجربة العملية الخطوات التالية:

  1. تنزيل المشروع الأساسي إلى Cloud Shell
  2. إنشاء خدمات مصغّرة في حاويات
  3. تحميل الحاويات إلى Google Artifact Registry (GAR)
  4. نشر الحاويات على GKE
  5. تعديل رمز المصدر للخدمات من أجل قياس حالة التطبيق
  6. الانتقال إلى الخطوة 2

تفعيل Kubernetes Engine

أولاً، نُعدّ مجموعة Kubernetes حيث يعمل Shakesapp على GKE، لذا علينا تفعيل GKE. انتقِل إلى القائمة "Kubernetes Engine" واضغط على الزر "تفعيل".

56c680e93e169731.png

أنت الآن جاهز لإنشاء مجموعة Kubernetes.

إنشاء مجموعة Kubernetes

في Cloud Shell، نفِّذ الأمر التالي لإنشاء مجموعة Kubernetes. يُرجى التأكّد من أنّ قيمة المنطقة تقع ضمن المنطقة التي استخدمتها لإنشاء مستودع Artifact Registry. غيِّر قيمة المنطقة us-central1-f إذا كانت منطقة المستودع لا تغطي المنطقة.

gcloud container clusters create otel-trace-codelab --zone us-central1-f \
--num-nodes 1 \
--machine-type e2-highcpu-4

ناتج الأمر

Creating cluster otel-trace-codelab in us-central1-f... Cluster is being health-checked (master is healthy)...done.
Created [https://container.googleapis.com/v1/projects/psychic-order-307806/zones/us-central1-f/clusters/otel-trace-codelab].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-f/otel-trace-codelab?project=psychic-order-307806
kubeconfig entry generated for otel-trace-codelab.
NAME                LOCATION       MASTER_VERSION    MASTER_IP        MACHINE_TYPE  NODE_VERSION      NUM_NODES  STATUS
otel-trace-codelab  us-central1-f  1.18.12-gke.1210  104.154.162.176  e2-medium     1.18.12-gke.1210  3          RUNNING

إعداد Artifact Registry وskaffold

لدينا الآن مجموعة Kubernetes جاهزة للنشر. بعد ذلك، نستعدّ لإنشاء سجلّ حاويات لإرسال الحاويات ونشرها. في هذه الخطوة، علينا إعداد GAR وskaffold لاستخدامهما.

إعداد Artifact Registry

انتقِل إلى قائمة "Artifact Registry" واضغط على الزر "تفعيل".

f7493243bae0cdf7.png

بعد بضع لحظات، سيظهر لك متصفّح مستودع GAR. انقر على الزر "إنشاء مستودع" (CREATE REPOSITORY) وأدخِل اسم المستودع.

f97f337f5476651.png

في هذا الدرس العملي، سأسمّي المستودع الجديد trace-codelab. تنسيق العنصر هو "Docker" ونوع الموقع الجغرافي هو "المنطقة". اختَر المنطقة القريبة من المنطقة التلقائية التي ضبطتها في Google Compute Engine. على سبيل المثال، تم اختيار "us-central1-f" أعلاه، لذا سنختار هنا "us-central1 (آيوا)". بعد ذلك، انقر على الزر "إنشاء".

2f04143077ca56db.png

يظهر الآن "trace-codelab" في متصفّح المستودع.

7a3c1f47346bea15.png

سنعود إلى هنا لاحقًا للتحقّق من مسار التسجيل.

إعداد Skaffold

Skaffold هي أداة مفيدة عند العمل على إنشاء خدمات مصغّرة تعمل على Kubernetes. يتعامل مع سير عمل إنشاء حاويات التطبيقات ونقلها ونشرها باستخدام مجموعة صغيرة من الأوامر. تستخدم Skaffold تلقائيًا Docker Registry كسجلّ حاويات، لذا عليك ضبط Skaffold للتعرّف على GAR عند إرسال الحاويات إليه.

افتح Cloud Shell مرة أخرى وتأكَّد من تثبيت Skaffold. (تثبِّت Cloud Shell أداة Skaffold في البيئة تلقائيًا). نفِّذ الأمر التالي واطّلِع على إصدار Skaffold.

skaffold version

ناتج الأمر

v1.20.0

يمكنك الآن تسجيل المستودع التلقائي الذي سيستخدمه Skaffold. للحصول على مسار السجلّ، انتقِل إلى لوحة بيانات Artifact Registry وانقر على اسم المستودع الذي أعددته في الخطوة السابقة.

55173fe922f40327.png

بعد ذلك، ستظهر مسارات شريط التنقّل في أعلى الصفحة. انقر على رمز e157b1359c3edc06.png لنسخ مسار التسجيل إلى الحافظة.

a9b0fa44c37e0178.png

عند النقر على زر النسخ، يظهر مربّع الحوار في أسفل المتصفّح مع رسالة مثل:

تم نسخ "us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab"

ارجع إلى Cloud Shell. نفِّذ الأمر skaffold config set default-repo مع القيمة التي نسختها للتو من لوحة البيانات.

skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab

ناتج الأمر

set value default-repo to us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab for context gke_stackdriver-sandbox-3438851889_us-central1-b_stackdriver-sandbox

عليك أيضًا ضبط سجلّ Docker. نفِّذ الأمر التالي:

gcloud auth configure-docker us-central1-docker.pkg.dev --quiet

ناتج الأمر

{
  "credHelpers": {
    "gcr.io": "gcloud",
    "us.gcr.io": "gcloud",
    "eu.gcr.io": "gcloud",
    "asia.gcr.io": "gcloud",
    "staging-k8s.gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud",
    "us-central1-docker.pkg.dev": "gcloud"
  }
}
Adding credentials for: us-central1-docker.pkg.dev

يمكنك الآن الانتقال إلى الخطوة التالية لإعداد حاوية Kubernetes على GKE.

ملخّص

في هذه الخطوة، عليك إعداد بيئة الدرس العملي:

  • إعداد Cloud Shell
  • تم إنشاء مستودع Artifact Registry لسجلّ الحاويات
  • إعداد Skaffold لاستخدام سجلّ الحاويات
  • أنشأنا مجموعة Kubernetes حيث تعمل الخدمات الدقيقة للدروس التطبيقية

التالي

في الخطوة التالية، ستنشئ خدماتك المصغّرة وتدفعها وتنشرها على المجموعة.

3- إنشاء الخدمات المصغّرة ونشرها

تنزيل مواد الدرس التطبيقي

في الخطوة السابقة، أعددنا جميع المتطلبات الأساسية لهذا الدرس البرمجي. أنت الآن جاهز لتشغيل الخدمات المصغّرة الكاملة فوقها. يتم استضافة مواد الدرس التطبيقي حول الترميز على GitHub، لذا نزِّلها إلى بيئة Cloud Shell باستخدام أمر git التالي.

cd ~
git clone https://github.com/GoogleCloudPlatform/opentelemetry-trace-codelab-python.git

تكون بنية الدليل الخاص بالمشروع على النحو التالي:

shakesapp-python
├── LICENSE
├── manifests
│   ├── client.yaml
│   ├── loadgen.yaml
│   └── server.yaml
├── proto
│   └── shakesapp.proto
├── skaffold.yaml
└── src
    ├── client
    ├── loadgen
    └── server
  • ملفات البيانات: ملفات بيانات Kubernetes
  • proto: تعريف proto للتواصل بين العميل والخادم
  • src: أدلة لرمز المصدر لكل خدمة
  • skaffold.yaml: ملف الإعداد الخاص بـ Skaffold

تنفيذ أمر skaffold

أخيرًا، أنت جاهز لإنشاء المحتوى الكامل ونشره وتوزيعه على مجموعة Kubernetes التي أنشأتها للتو. يبدو أنّ هذه العملية تتضمّن عدة خطوات، ولكن في الواقع، تنفّذ أداة Skaffold كل شيء نيابةً عنك. لنجرِّب ذلك باستخدام الأمر التالي:

cd shakesapp-python
skaffold run --tail

بعد تنفيذ الأمر مباشرةً، سيظهر لك ناتج السجلّ الخاص بـ docker build ويمكنك التأكّد من أنّه تم إرساله بنجاح إلى السجلّ.

ناتج الأمر

...
---> Running in c39b3ea8692b
 ---> 90932a583ab6
Successfully built 90932a583ab6
Successfully tagged us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step1
The push refers to repository [us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice]
cc8f5a05df4a: Preparing
5bf719419ee2: Preparing
2901929ad341: Preparing
88d9943798ba: Preparing
b0fdf826a39a: Preparing
3c9c1e0b1647: Preparing
f3427ce9393d: Preparing
14a1ca976738: Preparing
f3427ce9393d: Waiting
14a1ca976738: Waiting
3c9c1e0b1647: Waiting
b0fdf826a39a: Layer already exists
88d9943798ba: Layer already exists
f3427ce9393d: Layer already exists
3c9c1e0b1647: Layer already exists
14a1ca976738: Layer already exists
2901929ad341: Pushed
5bf719419ee2: Pushed
cc8f5a05df4a: Pushed
step1: digest: sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe size: 2001

بعد إرسال جميع حاويات الخدمة، تبدأ عمليات نشر Kubernetes تلقائيًا.

ناتج الأمر

sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8 size: 1997
Tags used in deployment:
 - serverservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/serverservice:step4@sha256:8acdbe3a453001f120fb22c11c4f6d64c2451347732f4f271d746c2e4d193bbe
 - clientservice -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/clientservice:step4@sha256:b71fce0a96cea08075dc20758ae561cf78c83ff656b04d211ffa00cedb77edf8
 - loadgen -> us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab/loadgen:step4@sha256:eea2e5bc8463ecf886f958a86906cab896e9e2e380a0eb143deaeaca40f7888a
Starting deploy...
 - deployment.apps/clientservice created
 - service/clientservice created
 - deployment.apps/loadgen created
 - deployment.apps/serverservice created
 - service/serverservice created

تنبيه: إذا ظهر لك الخطأ "No push access to specified image repository"، تحقَّق ممّا إذا كان أمر skaffold يحاول إرسال الصور إلى Docker Hub (docker.io) بغض النظر عن الإعدادات في المستودع التلقائي في skaffold. في هذه الحالة، جرِّب إضافة الخيار "‎–default-repo" إلى الأمر "skaffold run" كما هو موضّح أدناه.

$ skaffold run –tail –default-repo=us-central1-docker.pkg.dev/[project ID]/[repository name]

بعد عملية النشر، ستظهر لك سجلات التطبيق الفعلية التي تم إرسالها إلى stdout في كل حاوية على النحو التالي:

ناتج الأمر

[server] {"event": "starting server: 0.0.0.0:5050", "severity": "info", "timestamp": "2021-03-17T05:25:56.758575Z"}
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Starting gunicorn 20.0.4
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
[client] [2021-03-17 05:25:54 +0000] [1] [INFO] Using worker: threads
[client] [2021-03-17 05:25:54 +0000] [7] [INFO] Booting worker with pid: 7
[client] {"event": "server address is serverservice:5050", "severity": "info", "timestamp": "2021-03-17T05:25:54.888627Z"}
[client] {"event": "request to server with query: world", "severity": "info", "timestamp": "2021-03-17T05:26:11.550923Z"}
[server] {"event": "query: world", "severity": "info", "timestamp": "2021-03-17T05:26:11.567048Z"}
[loadgen] {"event": "check connectivity: http://clientservice:8080/_healthz", "severity": "info", "timestamp": "2021-03-17T05:26:11.533605Z"}
[loadgen] {"event": "/_healthz response: ok", "severity": "info", "timestamp": "2021-03-17T05:26:11.544267Z"}
[loadgen] {"event": "confirmed connection ot clientservice", "severity": "info", "timestamp": "2021-03-17T05:26:11.544527Z"}

أخيرًا، أنت جاهز لبدء تزويد تطبيقك بأداة OpenTelemetry لتتبُّع الخدمات الموزّعة.

ملخّص

في هذه الخطوة، أعددت مواد الدرس العملي في بيئتك وتأكّدت من أنّ أداة Skaffold تعمل على النحو المتوقّع.

التالي

في الخطوة التالية، ستعدّل رمز المصدر لخدمة loadgen من أجل تسجيل معلومات التتبُّع.

4. قياس حالة HTTP

مفهوم تتبُّع الأجهزة ونقل البيانات

قبل تعديل الرمز المصدر، سأشرح بإيجاز طريقة عمل التتبُّع الموزّع في مخطط بسيط.

c8c659deaa9c9091.png

في هذا المثال، نعدّل الرمز البرمجي لتصدير معلومات "التتبُّع" و"المدّة" إلى Cloud Trace وننشر سياق التتبُّع في جميع الطلبات من خدمة loadgen إلى خدمة الخادم.

يحتاج التطبيق إلى إرسال البيانات الوصفية لعمليات التتبُّع، مثل معرّف عملية التتبُّع ومعرّف الامتداد، لكي تجمع خدمة Cloud Trace كل الامتدادات التي لها معرّف عملية التتبُّع نفسه في عملية تتبُّع واحدة. يحتاج التطبيق أيضًا إلى نشر سياقات التتبُّع (مجموعة من معرّف التتبُّع ومعرّف الفترة الرئيسية) عند طلب الخدمات النهائية، حتى تتمكّن من معرفة سياق التتبُّع الذي تتعامل معه.

تساعدك OpenTelemetry في ما يلي:

  • لإنشاء معرّف تتبُّع ومعرّف مدى فريدَين
  • لتصدير معرّف التتبُّع ومعرّف الامتداد إلى الخلفية
  • لنشر سياقات التتبُّع إلى خدمات أخرى

Instrument first span

خدمة إنشاء عمليات تحميل الأدوات

افتح Cloud Shell Editor من خلال النقر على الزر 776a11bfb2122549.png في أعلى يسار Cloud Shell. افتح src/loadgen/loadgen.py من "المستكشف" في اللوحة اليمنى وابحث عن الدالة main.

src/loadgen/loadgen.py

def main():
    ...
    # start request loop to client service
    logger.info("start client request loop")
    addr = f"http://{target}"
    while True:
        logger.info("start request to client")
        call_client(addr)
        logger.info("end request to client")
        time.sleep(2.0)

في الدالة main، ترى الحلقة التي تستدعي الدالة call_client. في التنفيذ الحالي، يحتوي القسم على سطرَي سجلّ يسجّلان بداية استدعاء الدالة ونهايته. لنبدأ الآن بتسجيل معلومات Span لتتبُّع وقت استجابة استدعاء الدالة.

أولاً، عليك إنشاء Span باستخدام Trace ID وSpan ID فريدَين. توفّر OpenTelemetry مكتبة مفيدة لذلك. أضِف الأسطر التالية لاستيراد مكتبات OpenTelemetry إلى الرمز البرمجي.

 import structlog
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.instrumentation.requests import RequestsInstrumentor
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator

بما أنّ أداة إنشاء التحميل تستدعي تطبيق العميل في HTTP من خلال الوحدة requests، نستخدم حزمة الإضافة requests ونفعّل قياس حالة التطبيق.

 from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
+
+RequestsInstrumentor().instrument()

بعد ذلك، اضبط مثيل Tracer الذي يتعامل مع إعدادات Trace Contenxt وعمليات التصدير.

     target = os.environ.get("CLIENT_ADDR", "0.0.0.0:8080")

+    exporter = CloudTraceSpanExporter()
+    trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(exporter))
+    tracer = trace.get_tracer(__name__)
+    propagate.set_global_textmap(CloudTraceFormatPropagator())
+    trace.set_tracer_provider(TracerProvider())
+
     # connectivity check to client service
     healthz = f"http://{target}/_healthz"
     logger.info(f"check connectivity: {healthz}")

يُرجى العِلم أنّه بما أنّ هذا الدرس التطبيقي حول الترميز يهدف إلى فهم طريقة عمل قياس حالة التطبيق، فإنّنا نضبط Tracer لتسجيل كل طلب وإرساله إلى الخلفية. (SimpleSpanProcessor()) لا يناسب هذا الإعداد بيئات الإنتاج، لذا احرص على تغيير هذا الجزء عند إعداد تطبيقك في مرحلة الإنتاج.

يمكنك الآن تسجيل بيانات Spans باستخدام Tracer. النقطة المهمة هنا هي أنّ ما عليك فعله هو إنشاء Span بشكلٍ صريح، وهذا كل ما في الأمر. على الرغم من وجود سطرَين يضيفان البيانات الوصفية للحدث إلى Span، ليس عليك إنشاء Trace ID وSpan ID فريدَين يدويًا وتضمينهما في Span.

     logger.info("start client request loop")
     addr = f"http://{target}"
     while True:
-        logger.info("start request to client")
-        call_client(addr)
-        logger.info("end request to client")
+        with tracer.start_as_current_span("loadgen") as root_span:
+            root_span.add_event(name="request_start")
+            logger.info("start request to client")
+            call_client(addr)
+            root_span.add_event(name="request_end")
+            logger.info("end request to client")
         time.sleep(2.0)

لكي يتمكّن Docker build من جلب حِزم OpenTelemetry المطلوبة، شغِّل الأمر التالي:

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-requests=^0.20b0"

يمكنك التأكّد من أنّ وصف التبعية المقابل مكتوب في pyproject.toml.

خدمة عملاء أجهزة القياس

في القسم السابق، أضفنا أدوات إلى الجزء المضمّن في المستطيل الأحمر في الرسم أدناه. لقد أضفنا معلومات حول النطاق في خدمة إنشاء الحمل. على غرار خدمة إنشاء الحمل، علينا الآن إعداد خدمة العميل. يختلف هذا عن خدمة إنشاء التحميل في أنّ خدمة العميل تحتاج إلى استخراج معلومات رقم تعريف التتبُّع التي تم نشرها من خدمة إنشاء التحميل في عنوان HTTP واستخدام رقم التعريف لإنشاء Spans.

ae074d4513c9931f.png

افتح "محرِّر Cloud Shell" وأضِف الوحدات المطلوبة كما فعلنا مع خدمة إنشاء الحمل.

src/client/client.py

 import flask
 import grpc
 import structlog
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.instrumentation.flask import FlaskInstrumentor
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import \
+    CloudTraceFormatPropagator

 import shakesapp_pb2
 import shakesapp_pb2_grpc

تلاحظ أنّك استوردت FlaskInstrumentor الذي يتيح قياس حالة التطبيق تلقائيًا لتطبيق Flask نيابةً عن المستخدمين من أجل استخراج عناوين HTTP للحصول على سياقات التتبُّع باستخدام سطر واحد من الرمز. يوفّر منتدى OpenTelemetry عمليات دمج مفيدة مماثلة مع مكتبات رئيسية أخرى. لمزيد من المعلومات، يمكنك الرجوع إلى المستندات الرسمية.

 app = flask.Flask(__name__)
+FlaskInstrumentor().instrument_app(app)

قبل بدء عملية قياس حالة التطبيق، عليك مرة أخرى إعداد مثيل Tracer بشكل مشابه لما فعلناه في خدمة إنشاء الحمل.

 logger.info(f"server address is {SERVER_ADDR}")

+exporter = CloudTraceSpanExporter()
+trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(exporter))
+propagate.set_global_textmap(CloudTraceFormatPropagator())
+trace.set_tracer_provider(TracerProvider())

 @app.route("/")
 def main_handler():
    ....

أصبحت الآن جاهزة لإضافة قياس حالة التطبيق في المعالج. ابحث عن main_handler() وعدِّل الجزء الذي يرسل طلب gRPC إلى خدمة الخادم.

@app.route("/")
def main_handler():
    q, count = random.choice(list(queries.items()))

    # get Tracer
    tracer = trace.get_tracer(__name__)

    with tracer.start_as_current_span("client") as cur_span:
        channel = grpc.insecure_channel(SERVER_ADDR)
        stub = shakesapp_pb2_grpc.ShakespeareServiceStub(channel)
        logger.info(f"request to server with query: {q}")
        cur_span.add_event("server_call_start")
        resp = stub.GetMatchCount(shakesapp_pb2.ShakespeareRequest(query=q))
        cur_span.add_event("server_call_end")
        if count != resp.match_count:
            raise UnexpectedResultError(
                f"The expected count for '{q}' was {count}, but result was {resp.match_count } obtained"
            )
        result = str(resp.match_count)
        logger.info(f"matched count for '{q}' is {result}")
    return result

على غرار خدمة إنشاء التحميل، أضِف الحِزم المطلوبة إلى pyproject.toml باستخدام الأمر التالي.

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-flask=^0.20b0"

بعد ذلك، جرِّب تشغيل التطبيق باستخدام الأمر skaffold run واطّلِع على ما تعرضه لوحة بيانات Cloud Trace:

skaffold run --tail

بعد ظهور بعض رسائل الإنشاء والدفع والنشر، ستظهر لك سجلات التطبيق بتنسيقات JSON. انتقِل إلى Cloud Trace > قائمة عمليات التتبُّع للتحقّق مما إذا كنت تتلقّى معلومات التتبُّع. بما أنّ خدمة إنشاء الحمل ترسل طلبات إلى خدمة العميل بشكلٍ دوري وقد فعّلت عمليات التتبُّع لجميع الطلبات، ستبدأ في رؤية الكثير من النقاط في قائمة عمليات التتبُّع.

f7440360551980e.png

من خلال النقر على أحد هذه الأقسام، سيظهر لك رسم بياني متتالي على النحو التالي يوضّح وقت الاستجابة لكل جزء أثناء عملية الطلب والاستجابة. ابحث عن مربّع الاختيار بجانب "عرض الأحداث"، وستظهر لك التعليقات التوضيحية داخل الرسم البياني الشلالي. هذه التعليقات التوضيحية هي تلك التي أضفتها في الرمز باستخدام طريقة span.add_event().

67596a4a313738.png

قد تلاحظ أنّك لا ترى الفترات الزمنية من خدمة الخادم. هذا صحيح لأنّنا لم نفعّل "المدد الزمنية" في خدمة الخادم على الإطلاق.

ملخّص

في هذه الخطوة، تم إعداد خدمة إنشاء التحميل وخدمة العميل، وتم التأكّد من إمكانية نشر "سياق التتبُّع" بنجاح على مستوى الخدمات وتصدير معلومات "المدّة" من كلتا الخدمتين إلى Cloud Trace.

التالي

في الخطوة التالية، ستعمل على إعداد خدمة العميل وخدمة الخادم للتأكّد من كيفية نشر "سياق التتبُّع" من خلال gRPC.

5- قياس حالة التطبيق لـ gRPC

في الخطوة السابقة، أضفنا أدوات إلى النصف الأول من الطلب في هذه الخدمات المصغّرة. في هذه الخطوة، نحاول تفعيل عملية تسجيل بيانات التواصل بين خدمة العميل وخدمة الخادم باستخدام gRPC. (مستطيل أخضر وأرجواني في الصورة أدناه)

c4dec3e741c3ab4f.png

توفير أدوات القياس تلقائيًا لبرنامج gRPC

توفّر المنظومة المتكاملة لـ OpenTelemetry الكثير من المكتبات المفيدة التي تساعد المطوّرين في قياس أداء التطبيقات. في الخطوة السابقة، استخدمنا ميزة "قياس حالة التطبيق" لوحدة "الطلبات". في هذه الخطوة، وبما أنّنا نحاول نشر Trace Context من خلال gRPC، سنستخدم المكتبة لذلك.

src/client/client.py

 import flask
 import grpc
 import structlog
 from opentelemetry import propagate, trace
 from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
 from opentelemetry.instrumentation.flask import FlaskInstrumentor
+from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
 from opentelemetry.sdk.trace import TracerProvider
 from opentelemetry.sdk.trace.export import SimpleSpanProcessor
 from opentelemetry.propagators.cloud_trace_propagator import \
     CloudTraceFormatPropagator
 import shakesapp_pb2
 import shakesapp_pb2_grpc


 app = flask.Flask(__name__)
 FlaskInstrumentor().instrument_app(app)
+GrpcInstrumentorClient().instrument()

بالنسبة إلى خدمة العميل، فإنّ ما علينا فعله لتوفير قياس حالة التطبيق صغير جدًا. ما نريد فعله هو نشر Trace Context، وهو مزيج من Trace ID وSpan ID الخاص بـ Span الحالي من خلال gRPC. لذلك، نستدعي GrpcInstrumentatorClient.instrument() لكي يتمكّن عميل gRPC في دالة المعالج من تضمين "سياق التتبُّع" في عنوان HTTP أدناه.

احرص على إضافة التبعيات الجديدة إلى pyproject.toml باستخدام الأمر poetry add:

poetry add "opentelemetry-instrumentation-grpc=^0.20b0"

قياس حالة التطبيق تلقائيًا لخادم gRPC

كما فعلنا مع عميل gRPC، نستدعي عملية قياس حالة التطبيق التلقائي لخادم gRPC. أضِف عمليات استيراد، مثل عمليات المتابعة والمكالمات GrpcInstrumentationServer().instrument() في أعلى الملف.

تنبيه: احرص على الاتصال

GrpcInstrumentationServe() 

في هذه الخطوة، وليس

GrpcInstrumentationClient()

.

src/server/server.py

 import grpc
 import structlog
 from google.cloud import storage
 from grpc_health.v1 import health_pb2, health_pb2_grpc
+from opentelemetry import propagate, trace
+from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
+from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer
+from opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator

 import shakesapp_pb2
 import shakesapp_pb2_grpc


 BUCKET_NAME = "dataflow-samples"
 BUCKET_PREFIX = "shakespeare/"

+# enable auto gRPC server trace instrumentation
+GrpcInstrumentorServer().instrument()
+

بعد ذلك، ستضيف أداة التصدير لإرسال معلومات التتبُّع إلى الخلفية في Cloud Trace. أضِف الرمز التالي في الدالة serve().

def serve():
+    # start trace exporter
+    trace.set_tracer_provider(TracerProvider())
+    trace.get_tracer_provider().add_span_processor(
+        SimpleSpanProcessor(CloudTraceSpanExporter())
+    )
+    propagators.set_global_textmap(CloudTraceFormatPropagator())
+
+    # add gRPC services to server
     server = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
     service = ShakesappService()
     shakesapp_pb2_grpc.add_ShakespeareServiceServicer_to_server(service, server)
     health_pb2_grpc.add_HealthServicer_to_server(service, server)

احرص على إضافة الحِزم التي تمت إضافتها حديثًا في خدمة الخادم.

poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0"
poetry add "opentelemetry-instrumentation-grpc=^0.20b0"
poetry add "opentelemetry-propagator-gcp=^1.0.0rc0"
poetry add "opentelemetry-instrumentation=^0.20b0"

تشغيل الخدمة المصغّرة وتأكيد التتبُّع

بعد ذلك، شغِّل الرمز المعدَّل باستخدام أمر skaffold.

skaffold run --tail

مرة أخرى، سترى مجموعة من عمليات التتبُّع في صفحة "قائمة عمليات التتبُّع" في Cloud Trace. انقر على أحد عمليات التتبُّع، وستجد الآن أنّها تغطي الطلب من خدمة إنشاء التحميل إلى خدمة الخادم.

141cb620245b689d.png

ملخّص

في هذه الخطوة، أضفت أدوات إلى عملية التواصل المستندة إلى gRPC باستخدام مكتبات منظومة OpenTelemetry المتكاملة. تأكّدت أيضًا من أنّه تم إرسال "سياق التتبُّع" الذي تم إنشاؤه في خدمة إنشاء التحميل إلى خدمة الخادم بنجاح.

6. تهانينا

لقد أنشأت عمليات تتبُّع موزّعة بنجاح باستخدام OpenTelemery وأكّدت أوقات استجابة الطلبات في جميع الخدمات المصغّرة على Google Cloud Trace.

بالنسبة إلى التمارين الموسّعة، يمكنك تجربة المواضيع التالية بنفسك.

  • ترسل عملية التنفيذ الحالية جميع الفترات الزمنية التي تم إنشاؤها من خلال عملية التحقّق من الصحة. كيف يمكن فلترة هذه الفترات من Cloud Trace؟ يمكنك الاطّلاع على التلميح هنا.
  • ربط سجلّات الأحداث بالنطاقات ومعرفة طريقة عملها على Google Cloud Trace وGoogle Cloud Logging يمكنك الاطّلاع على التلميح هنا.
  • استبدِل بعض الخدمات بالخدمات المتوفّرة بلغة أخرى وحاوِل قياسها باستخدام OpenTelemetry لهذه اللغة.

تنبيه: تستهلك خدمتا Google Kubernetes Engine وGoogle Artifact Registry الموارد باستمرار.

تنظيف

بعد الانتهاء من هذا الدرس التطبيقي حول الترميز، يُرجى إيقاف مجموعة Kubernetes وحذف المشروع لكي لا يتم تحصيل رسوم غير متوقّعة منك في Google Kubernetes Engine وGoogle Cloud Trace وGoogle Artifact Registry.

أولاً، احذف المجموعة باستخدام الأمر التالي:

skaffold delete

ناتج الأمر

Cleaning up...
 - deployment.apps "clientservice" deleted
 - service "clientservice" deleted
 - deployment.apps "loadgen" deleted
 - deployment.apps "serverservice" deleted
 - service "serverservice" deleted

بعد حذف المجموعة، اختَر "إدارة الهوية وإمكانية الوصول (IAM) والمشرف" > "الإعدادات" من لوحة القائمة، ثمّ انقر على الزر "إيقاف".

578ca2b72a161e9d.png

بعد ذلك، أدخِل رقم تعريف المشروع (وليس اسم المشروع) في النموذج في مربّع الحوار وأكِّد عملية الإيقاف.