1. Einführung
Zuletzt aktualisiert:05.03.2021
Beobachtbarkeit der Anwendung
Beobachtbarkeit und OpenTelemetry
Beobachtbarkeit ist der Begriff, mit dem ein Attribut eines Systems beschrieben wird. Ein System mit Beobachtbarkeit ermöglicht es Teams, ihr System aktiv zu debuggen. In diesem Zusammenhang gibt es drei Säulen der Beobachtbarkeit: Logs, Messwerte und Traces sind die grundlegende Instrumentierung für das System, um Beobachtbarkeit zu erlangen.
OpenTelemetry umfasst eine Reihe von Spezifikationen und SDKs, die die Instrumentierung und den Export von Telemetriedaten (Logs, Messwerten und Traces) beschleunigen, die für die Beobachtbarkeit erforderlich sind. OpenTelemetry ist ein Projekt mit offenem Standard und einer Community im Rahmen von CNCF. Mithilfe von Bibliotheken, die im Rahmen des Projekts und seiner Umgebung bereitgestellt werden, können Entwickler ihre Anwendungen anbieterneutral und mit mehreren Architekturen instrumentieren.
Verteilter Trace
Bei Logs, Messwerten und Traces ist Trace die Telemetrie, die die Latenz eines bestimmten Prozessteils im System mitteilt. Besonders im Zeitalter der Mikrodienste ist verteiltes Trace der starke Faktor, um Latenzengpässe im gesamten verteilten System zu identifizieren.
Bei der Analyse verteilter Traces ist die Visualisierung der Trace-Daten der Schlüssel, um die Gesamtsystemlatenzen auf einen Blick zu erfassen. Beim verteilten Trace wird eine Reihe von Aufrufen verarbeitet, um eine einzelne Anfrage an den Systemeinstiegspunkt in Form eines Trace mit mehreren Spans zu verarbeiten.
Ein Span stellt eine einzelne Arbeitseinheit in einem verteilten System dar, die Start- und Endzeiten aufzeichnet. Spans haben häufig hierarchische Beziehungen untereinander. Im Bild unten sind alle kleineren Spans untergeordnete Spans eines großen /messages-Spans und werden in einem Trace zusammengefasst, der den Weg der Arbeit durch ein System zeigt.
Google Cloud Trace ist eine der Optionen für verteilte Trace-Back-Ends und ist gut in andere Produkte in Google Cloud eingebunden.
Inhalt
In diesem Codelab instrumentieren Sie Trace-Informationen in den Diensten namens „Shakesapp“ der in einem Kubernetes-Cluster ausgeführt wird, der in Google Kubernetes Engine ausgeführt wird. Die Architektur von Shakesapp sieht so aus:
- Clients senden einen Abfragestring an den Server
- Der Server akzeptiert die Anfrage vom Client, ruft alle Shakespare-Werke im Textformat aus Google Cloud Storage ab, durchsucht die Zeilen mit der Anfrage und gibt die Nummer der Zeile zurück, die dem Client zugeordnet wurde.
Sie instrumentieren die Trace-Informationen in der gesamten Anfrage.
Aufgaben in diesem Lab
- Erste Schritte mit den OpenTelemetry-Trace-Bibliotheken im Python-Projekt
- Span mit der Bibliothek erstellen
- Span-Kontexte zwischen Anwendungskomponenten auf der Leitungsverbindung weitergeben
- Trace-Daten an Google Cloud Trace senden
- Trace in Google Cloud Trace analysieren
In diesem Codelab wird erläutert, wie Sie Ihre Mikrodienste instrumentieren. Zur besseren Verdeutlichung enthält dieses Beispiel nur drei Komponenten (Load Generator, Client und Server). Du kannst den Prozess, der in diesem Codelab erläutert wird, aber auch auf komplexere und größere Systeme anwenden.
Voraussetzungen
- Kenntnisse in Python 3
2. Einrichtung und Anforderungen
Umgebung für das selbstbestimmte Lernen einrichten
Wenn Sie noch kein Google-Konto (Gmail oder Google Apps) haben, müssen Sie eines erstellen. Melden Sie sich in der Google Cloud Platform Console ( console.cloud.google.com) an und erstellen Sie ein neues Projekt.
Wenn Sie bereits ein Projekt haben, klicken Sie auf das Drop-down-Menü für die Projektauswahl oben links in der Konsole:
und klicken Sie auf „NEUES PROJEKT“, Schaltfläche zum Erstellen eines neuen Projekts:
Wenn Sie noch kein Projekt haben, sollten Sie ein Dialogfeld wie dieses sehen, um Ihr erstes zu erstellen:
Im nachfolgenden Dialog zur Projekterstellung können Sie die Details Ihres neuen Projekts eingeben:
Denken Sie an die Projekt-ID. Dies ist ein eindeutiger Name, der in allen Google Cloud-Projekten eindeutig ist. Der oben angegebene Name ist bereits vergeben und funktioniert leider nicht für Sie. Sie wird in diesem Codelab später als PROJECT_ID bezeichnet.
Falls noch nicht geschehen, müssen Sie als Nächstes in der Developers Console die Abrechnung aktivieren, um Google Cloud-Ressourcen nutzen und die Cloud Trace API aktivieren zu können.
Dieses Codelab sollte nicht mehr als ein paar Euro kosten. Wenn Sie sich jedoch dazu entschließen, mehr Ressourcen zu verwenden oder diese weiter auszuführen (siehe Abschnitt „Bereinigen“ am Ende dieses Dokuments), Die Preise für Google Cloud Trace, Google Kubernetes Engine und Google Artifacat Registry finden Sie in der offiziellen Dokumentation.
- Preise für Google Cloud Observability
- Preise | Kubernetes Engine-Dokumentation
- Artifact Registry – Preise | Artifact Registry-Dokumentation
Neue Google Cloud Platform-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben, wodurch das Codelab in der Regel kostenlos sein sollte.
Google Cloud Shell einrichten
Sie können Google Cloud und Google Cloud Trace per Fernzugriff von Ihrem Laptop aus bedienen. In diesem Codelab verwenden wir jedoch Google Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.
Diese Debian-basierte virtuelle Maschine verfügt über alle erforderlichen Entwicklungstools. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Für dieses Codelab benötigen Sie also nur einen Browser – ja, er funktioniert auf Chromebooks.
Klicken Sie einfach auf „Cloud Shell aktivieren“ , um Cloud Shell über die Cloud Console zu aktivieren. Es dauert nur einen Moment, bis die Umgebung bereitgestellt und eine Verbindung hergestellt werden kann.
Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt bereits auf Ihre PROJECT_ID
eingestellt ist.
gcloud auth list
Befehlsausgabe
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Befehlsausgabe
[core] project = <PROJECT_ID>
Sollte das Projekt aus irgendeinem Grund nicht eingerichtet sein, geben Sie einfach den folgenden Befehl ein:
gcloud config set project <PROJECT_ID>
Du suchst dein Gerät (PROJECT_ID
)? Sehen Sie nach, welche ID Sie bei den Einrichtungsschritten verwendet haben, oder rufen Sie sie im Dashboard der Cloud Console auf:
Cloud Shell legt außerdem standardmäßig einige Umgebungsvariablen fest, die bei der Ausführung zukünftiger Befehle nützlich sein können.
echo $GOOGLE_CLOUD_PROJECT
Befehlsausgabe
<PROJECT_ID>
Legen Sie schließlich die Standardzone und die Projektkonfiguration fest.
gcloud config set compute/zone us-central1-f
Sie können verschiedene Zonen auswählen. Weitere Informationen finden Sie unter Regionen und Zonen.
Python-Einrichtung
In diesem Codelab verwenden wir „poetry“, Paketversionen streng zu verwalten. Führen Sie den folgenden Befehl in Cloud Shell aus:
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3 - source $HOME/.poetry/env
Google Kubernetes-Cluster einrichten
In diesem Codelab führen Sie einen Cluster von Mikrodiensten in Google Kubernetes Engine (GKE) aus. In diesem Codelab werden folgende Schritte ausgeführt:
- Referenzprojekt in Cloud Shell herunterladen
- Mikrodienste in Container umwandeln
- Container in Google Artifact Registry (GAR) hochladen
- Container in GKE bereitstellen
- Quellcode von Diensten für die Trace-Instrumentierung ändern
- Zu Schritt 2
Kubernetes Engine aktivieren
Zuerst richten wir einen Kubernetes-Cluster ein, in dem Shakesapp in der GKE ausgeführt wird. Also müssen wir GKE aktivieren. Rufen Sie das Menü „Kubernetes Engine“ auf. und drücken Sie die Taste AKTIVIEREN.
Jetzt können Sie einen Kubernetes-Cluster erstellen.
Kubernetes-Cluster erstellen
Führen Sie in Cloud Shell den folgenden Befehl aus, um einen Kubernetes-Cluster zu erstellen. Achten Sie darauf, dass sich der Zonenwert in der Region befindet, die Sie für die Erstellung des Artifact Registry-Repositorys verwendet haben. Ändern Sie den Zonenwert us-central1-f
, wenn die Repository-Region die Zone nicht abdeckt.
gcloud container clusters create otel-trace-codelab --zone us-central1-f \ --num-nodes 1 \ --machine-type e2-highcpu-4
Befehlsausgabe
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 und Skaffold einrichten
Jetzt haben wir einen Kubernetes-Cluster, der bereitgestellt werden kann. Als Nächstes bereiten wir eine Container Registry für das Push- und Bereitstellen von Containern vor. Für diesen Schritt müssen wir GAR und Skaffold einrichten, um es verwenden zu können.
Artifact Registry einrichten
Rufen Sie das Menü von „Artifact Registry“ auf und drücken Sie die Taste AKTIVIEREN.
Nach kurzer Zeit wird der Repository-Browser von GAR angezeigt. Klicken Sie auf „REPOSITORY ERSTELLEN“. und geben Sie den Namen des Repositorys ein.
In diesem Codelab nenne ich das neue Repository trace-codelab
. Das Format des Artefakts ist „Docker“ und der Standorttyp ist „Region“. Wählen Sie die Region in der Nähe der Region aus, die Sie für die Google Compute Engine-Standardzone festgelegt haben. In diesem Beispiel ist „us-central1-f“ ausgewählt. Also wählen wir "us-central1 (Iowa)" aus. Klicken Sie dann auf „ERSTELLEN“, Schaltfläche.
Sie sehen jetzt „trace-codelab“ im Repository-Browser.
Wir werden später hierher zurückkehren, um den Registrierungspfad zu überprüfen.
Skaffold-Einrichtung
Skaffold ist ein praktisches Tool, wenn Sie mit der Erstellung von Mikrodiensten arbeiten, die auf Kubernetes ausgeführt werden. Sie übernimmt den Workflow für das Erstellen, Übertragen und Bereitstellen von Anwendungscontainern mit einer kleinen Anzahl von Befehlen. Skaffold verwendet standardmäßig Docker Registry als Container Registry. Daher müssen Sie Skaffold so konfigurieren, dass GAR beim Hochladen von Containern erkannt wird.
Öffnen Sie Cloud Shell noch einmal und prüfen Sie, ob Skaffold installiert ist. Cloud Shell installiert Skaffold standardmäßig in der Umgebung. Führen Sie den folgenden Befehl aus, um die Skaffold-Version aufzurufen.
skaffold version
Befehlsausgabe
v1.20.0
Jetzt können Sie das Standard-Repository für Skaffold registrieren. Um den Registry-Pfad abzurufen, gehen Sie zum Artifact Registry-Dashboard und klicken Sie auf den Namen des Repositorys, das Sie gerade im vorherigen Schritt eingerichtet haben.
Dann sehen Sie oben auf der Seite Navigationspfade. Klicken Sie auf das Symbol , um den Registry-Pfad in die Zwischenablage zu kopieren.
Wenn Sie auf die Schaltfläche „Kopieren“ klicken, erscheint ein Dialogfeld unten im Browser mit einer Meldung wie:
"us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab" wurde kopiert
Kehren Sie zu Cloud Shell zurück. Führen Sie den Befehl skaffold config set default-repo
mit dem Wert aus, den Sie gerade aus dem Dashboard kopiert haben.
skaffold config set default-repo us-central1-docker.pkg.dev/psychic-order-307806/trace-codelab
Befehlsausgabe
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
Außerdem müssen Sie die Registry für die Docker-Konfiguration konfigurieren. Führen Sie dazu diesen Befehl aus:
gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
Befehlsausgabe
{ "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
Jetzt können Sie einen Kubernetes-Container in GKE einrichten.
Zusammenfassung
In diesem Schritt richten Sie Ihre Codelab-Umgebung ein:
- Cloud Shell einrichten
- Artifact Registy-Repository für die Container Registry erstellt
- Skaffold für die Verwendung der Container Registry einrichten
- Es wurde ein Kubernetes-Cluster erstellt, in dem die Codelab-Mikrodienste ausgeführt werden
Nächstes Thema
Im nächsten Schritt erstellen Sie die Mikrodienste, übertragen sie per Push im Cluster und stellen sie bereit
3. Mikrodienste erstellen, per Push übertragen und bereitstellen
Codelab-Material herunterladen
Im vorherigen Schritt haben wir alle Voraussetzungen für dieses Codelab eingerichtet. Jetzt können Sie ganze Mikrodienste auf ihnen ausführen. Das Codelab-Material wird auf GitHub gehostet. Laden Sie es deshalb mit dem folgenden git-Befehl in die Cloud Shell-Umgebung herunter.
cd ~ git clone https://github.com/GoogleCloudPlatform/opentelemetry-trace-codelab-python.git
Die Verzeichnisstruktur des Projekts sieht so aus:
shakesapp-python ├── LICENSE ├── manifests │ ├── client.yaml │ ├── loadgen.yaml │ └── server.yaml ├── proto │ └── shakesapp.proto ├── skaffold.yaml └── src ├── client ├── loadgen └── server
- Manifeste: Kubernetes-Manifestdateien
- proto: Proto-Definition für die Kommunikation zwischen Client und Server
- src: Verzeichnisse für den Quellcode der einzelnen Dienste
- skaffold.yaml: Konfigurationsdatei für Skaffold
skaffold-Befehl ausführen
Schließlich können Sie den gesamten Inhalt erstellen, per Push-Funktion in den soeben erstellten Kubernetes-Cluster übertragen und bereitstellen. Das klingt nach mehreren Schritten, aber im wahrsten Sinne des Wortes ist Skaffold alles für Sie erledigt. Versuchen wir das mit dem folgenden Befehl:
cd shakesapp-python skaffold run --tail
Sobald Sie den Befehl ausführen, wird die Logausgabe von docker build
angezeigt und Sie können bestätigen, dass die Dateien erfolgreich in die Registry übertragen wurden.
Befehlsausgabe
... ---> 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
Nach der Übertragung aller Dienstcontainer werden Kubernetes-Deployments automatisch gestartet.
Befehlsausgabe
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
Achtung: Wenn eine Fehlermeldung wie „Kein Push-Zugriff auf angegebenes Image-Repository“ angezeigt wird, prüfen Sie, ob der Skaffold-Befehl versucht, Images an Docker Hub (docker.io) zu übertragen, unabhängig von Ihrer Konfiguration für das Standard-Repository in Skaffold. Versuchen Sie in diesem Fall, „–default-repo“ hinzuzufügen die Option „Skaffold-Ausführung“ wie unten dargestellt.
$ skaffold run –tail –default-repo=us-central1-docker.pkg.dev/[project ID]/[Repository name]
Nach der Bereitstellung werden die tatsächlichen Anwendungslogs, die an stdout ausgegeben wurden, in jedem Container so angezeigt:
Befehlsausgabe
[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"}
Schließlich können Sie Ihre Anwendung mit OpenTelemetry instrumentieren, um verteiltes Tracing der Dienste zu ermöglichen.
Zusammenfassung
In diesem Schritt haben Sie das Codelab-Material in Ihrer Umgebung vorbereitet und die Skaffold-Ausführungen wie erwartet bestätigt.
Nächstes Thema
Im nächsten Schritt ändern Sie den Quellcode des Diensts "loadgen", um die Trace-Informationen zu instrumentieren.
4. Instrumentierung für HTTP
Konzept der Trace-Instrumentierung und -Weitergabe
Bevor ich den Quellcode bearbeite, möchte ich kurz in einem einfachen Diagramm erklären, wie verteilte Traces funktionieren.
In diesem Beispiel instrumentieren wir den Code, um Trace- und Span-Informationen nach Cloud Trace zu exportieren und den Trace-Kontext über die Anfrage vom Loadgen-Dienst an den Serverdienst weiterzugeben.
Die Anwendung muss Trace-Metadaten wie die Trace-ID und die Span-ID senden, damit Cloud Trace alle Spans mit derselben Trace-ID in einem Trace zusammenfassen kann. Außerdem muss die Anwendung bei der Anforderung von nachgelagerten Diensten Trace-Kontexte (die Kombination aus Trace-ID und Span-ID des übergeordneten Spans) weitergeben, damit sie erkennen kann, welchen Trace-Kontext sie verarbeiten.
OpenTelemetry bietet folgende Vorteile:
- zum Generieren einer eindeutigen Trace-ID und Span-ID
- um die Trace-ID und die Span-ID in das Back-End zu exportieren
- zur Weitergabe von Trace-Kontexten an andere Dienste
Erster Span instrumentieren
Lastgenerator-Dienst für Instrumente
Öffnen Sie den Cloud Shell-Editor, indem Sie oben rechts in Cloud Shell auf die Schaltfläche klicken. Öffnen Sie im Explorer im linken Bereich src/loadgen/loadgen.py
und suchen Sie die Funktion 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)
In der Funktion main
sehen Sie die Schleife, die die Funktion call_client
darin aufruft. In der aktuellen Implementierung hat das sectoin 2 Logzeilen, die den Anfang und das Ende des Funktionsaufrufs aufzeichnen. Instrumentieren wir nun Span-Informationen, um die Latenz des Funktionsaufrufs zu verfolgen.
Zuerst müssen Sie einen Span mit einer eindeutigen Trace-ID und einer Span-ID erstellen. OpenTelemetry bietet eine praktische Bibliothek dafür. Fügen Sie die folgenden Zeilen hinzu, um OpenTelemetry-Bibliotheken in Ihren Code zu importieren.
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
Da der Load Generator eine Clientanwendung in HTTP über das Modul requests
aufruft, verwenden wir das Erweiterungspaket für requests
und aktivieren die Instrumentierung.
from opentelemetry.propagators.cloud_trace_propagator import CloudTraceFormatPropagator
+
+RequestsInstrumentor().instrument()
Richten Sie dann die Tracer-Instanz ein, die die Trace-Einstellungen und die Exporter-Einstellungen verarbeitet.
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}")
Da es sich um ein Codelab handelt, mit dem die Funktionsweise der Trace-Instrumentierung erklärt wird, konfigurieren wir den Tracer so, dass er jede einzelne Anfrage aufzeichnet und an das Back-End sendet. (SimpleSpanProcessor()
) Dieser Teil ist nicht für Produktionsumgebungen geeignet. Ändern Sie diesen Teil, wenn Sie Ihre Produktionsanwendung instrumentieren.
Jetzt können Sie Spans mit dem Tracer instrumentieren. Der Punkt hier ist, dass Sie einen Span explizit generieren müssen. Das war's! Es gibt zwei Zeilen, über die Ereignismetadaten zu einem Span hinzugefügt werden. Sie müssen die eindeutige Trace-ID und Span-ID jedoch nicht manuell generieren und in den Span einbetten.
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)
Damit Docker-Build die erforderlichen OpenTelemetry-Pakete abrufen kann, führen Sie den folgenden Befehl aus:
poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0" poetry add "opentelemetry-propagator-gcp=^1.0.0rc0" poetry add "opentelemetry-instrumentation-requests=^0.20b0"
Sie können prüfen, ob die entsprechende Abhängigkeitsbeschreibung in pyproject.toml
geschrieben ist.
Clientdienst instrumentieren
Im vorherigen Abschnitt haben wir den Teil instrumentiert, der in der Zeichnung unten im roten Rechteck enthalten ist. Wir haben Span-Informationen im Load Generator-Dienst instrumentiert. Ähnlich wie beim Lastgenerator-Dienst müssen wir nun den Client-Dienst instrumentieren. Der Unterschied zum Load Generator-Dienst besteht darin, dass der Clientdienst Trace-ID-Informationen extrahieren muss, die vom Load Generator-Dienst im HTTP-Header weitergegeben werden, und die ID zum Generieren von Spans verwenden muss.
Öffnen Sie den Cloud Shell-Editor und fügen Sie wie für den Load Generator-Dienst die erforderlichen Module hinzu.
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
Sie haben gerade FlaskInstrumentor
importiert. Diese Funktion ermöglicht die automatische Instrumentierung für die Flask-Anwendung im Namen der Nutzer, um HTTP-Header zu extrahieren, um Trace-Kontexte mit einer einzigen Codezeile abzurufen. Die OpenTelemetry-Community bietet ähnliche nützliche Integrationen mit anderen wichtigen Bibliotheken. Weitere Informationen finden Sie in der offiziellen Dokumentation.
app = flask.Flask(__name__)
+FlaskInstrumentor().instrument_app(app)
Bevor Sie die Instrumentierung starten, müssen Sie die Tracer-Instanz ähnlich wie im Load Generator-Dienst vorbereiten.
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():
....
Jetzt kann die Instrumentierung im Handler hinzugefügt werden. Suchen Sie main_handler()
und ändern Sie den Teil, der die gRPC-Anfrage an den Serverdienst sendet.
@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
Ähnlich wie beim Load Generator-Dienst fügen Sie erforderliche Pakete mit dem folgenden Befehl in pyproject.toml
ein.
poetry add "opentelemetry-exporter-gcp-trace=^1.0.0rc0" poetry add "opentelemetry-propagator-gcp=^1.0.0rc0" poetry add "opentelemetry-instrumentation-flask=^0.20b0"
Versuchen Sie dann, die Anwendung mit dem Befehl skaffold run
zu starten, und sehen Sie sich an, was im Cloud Trace-Dashboard angezeigt wird:
skaffold run --tail
Nachdem Sie Build-, Push- und Deployment-Nachrichten gesehen haben, werden Anwendungslogs im JSON-Format angezeigt. Cloud Trace aufrufen > Traceliste, um zu prüfen, ob Sie die Trace-Informationen erhalten. Da der Load Generator-Dienst regelmäßig Anfragen an den Clientdienst sendet und Sie Traces für alle Anfragen aktiviert haben, sehen Sie viele Punkte in der Trace-Liste.
Wenn Sie auf eine dieser Optionen klicken, sehen Sie ein Wasserfalldiagramm wie unten, das die Latenz jedes Teils des Anfrage- und Antwortprozesses erklärt. Setzen Sie ein Häkchen in das Kästchen neben „Ereignisse anzeigen“. Daraufhin werden die Anmerkungen im Wasserfalldiagramm angezeigt. Diese Anmerkungen haben Sie mit der Methode span.add_event()
im Code instrumentiert.
Die Spans des Serverdienstes werden nicht angezeigt. Das ist richtig, da wir im Serverdienst keine Spans instrumentiert haben.
Zusammenfassung
In diesem Schritt haben Sie den Load-Generator-Dienst und den Clientdienst instrumentiert und bestätigt, dass Sie Trace-Kontext erfolgreich an alle Dienste weitergeben und Span-Informationen aus beiden Diensten an Cloud Trace exportieren können.
Nächstes Thema
Im nächsten Schritt instrumentieren Sie den Clientdienst und den Serverdienst, um zu prüfen, wie Trace Context über gRPC weitergegeben wird.
5. Instrumentierung für gRPC
Im vorherigen Schritt haben wir die erste Hälfte der Anfrage in diesen Mikrodiensten instrumentiert. In diesem Schritt versuchen wir, die gRPC-Kommunikation zwischen Client- und Serverdienst zu instrumentieren. (Grünes und lila Rechteck im Bild unten)
Automatische Instrumentierung für den gRPC-Client
OpenTelemetry bietet viele praktische Bibliotheken, mit denen Entwickler Anwendungen instrumentieren können. Im vorherigen Schritt wurde die automatische Instrumentierung für „Anfragen“ verwendet. -Modul. In diesem Schritt verwenden wir die Bibliothek, um Trace-Kontext über gRPC weiterzugeben.
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()
Beim Kundendienst ist der Aufwand für die Instrumentierung ziemlich gering. Wir möchten den Trace-Kontext, die Kombination aus Trace-ID und Span-ID des aktuellen Spans, über gRPC weitergeben. Daher rufen wir GrpcInstrumentatorClient.instrument()
auf, damit der gRPC-Client in der Hander-Funktion den Trace-Kontext in den darunter liegenden HTTP-Header einbetten kann.
Fügen Sie pyproject.toml
unbedingt mit dem Befehl poetry add
neue Abhängigkeiten hinzu:
poetry add "opentelemetry-instrumentation-grpc=^0.20b0"
Automatische Instrumentierung für den gRPC-Server
Wie beim gRPC-Client nennen wir die automatische Instrumentierung für den gRPC-Server. Fügen Sie Importe wie „Folgen“ hinzu und rufen Sie am Anfang der Datei GrpcInstrumentationServer().instrument()
auf.
Achtung: Rufen Sie unbedingt
GrpcInstrumentationServe()
in diesem Schritt und nicht
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()
+
Als Nächstes fügen Sie den Exporter hinzu, um Traceinformationen an das Cloud Trace-Back-End zu senden. Fügen Sie der Funktion serve()
den folgenden Code hinzu.
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)
Achten Sie darauf, dem Serverdienst neu hinzugefügte Pakete hinzuzufügen.
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"
Mikrodienst ausführen und Trace prüfen
Führen Sie dann den geänderten Code mit dem skaffold-Befehl aus.
skaffold run --tail
Jetzt sehen Sie wieder eine Reihe von Traces auf der Seite mit der Trace-Liste von Cloud Trace. Klicken Sie auf einen der Traces. Dieser erstreckt sich über die Anfrage vom Lastgenerator-Dienst zum Serverdienst.
Zusammenfassung
In diesem Schritt haben Sie die gRPC-basierte Kommunikation mit der Unterstützung der Bibliotheken des OpenTelemetry-Ökosystems instrumentiert. Außerdem haben Sie bestätigt, dass der im Load Generator-Dienst generierte Trace-Kontext erfolgreich an den Serverdienst übermittelt wurde.
6. Glückwunsch
Sie haben verteilte Traces mit OpenTelemery erstellt und die Anfragelatenzen für den Mikrodienst in Google Cloud Trace bestätigt.
Für längere Übungen kannst du die folgenden Themen selbst ausprobieren.
- Bei der aktuellen Implementierung werden alle von der Systemdiagnose generierten Spans gesendet. Wie filtern Sie diese Spans aus Cloud Traces heraus? Den Hinweis finden Sie hier.
- Ereignislogs mit Spans korrelieren und ihre Funktionsweise in Google Cloud Trace und Google Cloud Logging sehen Den Hinweis finden Sie hier.
- Ersetzen Sie einen Dienst durch einen Dienst in einer anderen Sprache und instrumentieren Sie ihn mit OpenTelemetry für diese Sprache
Achtung: Google Kubernetes Engine und Google Artifact Registry verbrauchen die Ressource ständig.
Aufräumen
Beenden Sie nach diesem Codelab den Kubernetes-Cluster und löschen Sie das Projekt, damit keine unerwarteten Kosten für Google Kubernetes Engine, Google Cloud Trace und Google Artifact Registry anfallen.
Löschen Sie zuerst den Cluster mit dem folgenden Befehl:
skaffold delete
Befehlsausgabe
Cleaning up... - deployment.apps "clientservice" deleted - service "clientservice" deleted - deployment.apps "loadgen" deleted - deployment.apps "serverservice" deleted - service "serverservice" deleted
Wählen Sie nach dem Löschen des Clusters im Menübereich die Option „IAM & Admin“ > „Einstellungen“ und dann auf „Beenden“. Schaltfläche.
Geben Sie dann die Projekt-ID (nicht den Projektnamen) in das Formular im Dialogfeld ein und bestätigen Sie das Herunterfahren.