1. Übersicht
Generative KI-Anwendungen erfordern wie alle anderen Anwendungen Beobachtbarkeit. Sind für generative KI spezielle Verfahren zur Observabilität erforderlich?
In diesem Lab erstellen Sie eine einfache Gen AI-Anwendung. Stellen Sie sie in Cloud Run bereit. Außerdem können Sie sie mit wichtigen Monitoring- und Logging-Funktionen mithilfe der Google Cloud-Dienste und -Produkte für die Beobachtbarkeit ausstatten.
Lerninhalte
- Anwendung mit Vertex AI mit dem Cloud Shell-Editor schreiben
- Anwendungscode in GitHub speichern
- Quellcode Ihrer Anwendung mit der gcloud CLI in Cloud Run bereitstellen
- Ihrer Anwendung mit generativer KI Monitoring- und Logging-Funktionen hinzufügen
- Logbasierte Messwerte verwenden
- Logging und Monitoring mit dem OpenTelemetry SDK implementieren
- Informationen zur verantwortungsbewussten Datenverarbeitung bei KI
2. Vorbereitung
Wenn Sie noch kein Google-Konto haben, müssen Sie ein neues Konto erstellen.
3. Projekt einrichten
- Melden Sie sich mit Ihrem Google-Konto in der Google Cloud Console an.
- Erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Notieren Sie sich die Projekt-ID des Projekts, das Sie gerade erstellt oder ausgewählt haben.
- Aktivieren Sie die Abrechnung für das Projekt.
- Die Durchführung dieses Labs sollte weniger als 5 $in Rechnung stellen.
- Sie können die Schritte am Ende dieses Labs ausführen, um Ressourcen zu löschen und weitere Kosten zu vermeiden.
- Neue Nutzer können das kostenlose Testabo mit einem Guthaben von 300$ nutzen.
- Prüfen Sie, ob die Abrechnung unter Meine Projekte in der Cloud-Abrechnung aktiviert ist.
- Wenn in der Spalte
Billing account
für Ihr neues ProjektBilling is disabled
angezeigt wird:- Klicken Sie in der Spalte
Actions
auf das Dreipunkt-Menü. - Klicken Sie auf Abrechnung ändern.
- Wählen Sie das Rechnungskonto aus, das Sie verwenden möchten.
- Klicken Sie in der Spalte
- Wenn Sie an einer Live-Veranstaltung teilnehmen, lautet der Name des Kontos wahrscheinlich Google Cloud Platform-Testrechnungskonto.
- Wenn in der Spalte
4. Cloud Shell-Editor vorbereiten
- Rufen Sie den Cloud Shell-Editor auf. Wenn Sie die folgende Aufforderung sehen, Cloud Shell zu autorisieren, gcloud mit Ihren Anmeldedaten aufzurufen, klicken Sie auf Autorisieren, um fortzufahren.
- Terminalfenster öffnen
- Klicke auf das Dreistrich-Menü
.
- Klicken Sie auf Terminal.
- Klicken Sie auf Neues Terminal
.
- Klicke auf das Dreistrich-Menü
- Konfigurieren Sie im Terminal Ihre Projekt-ID:
Ersetzen Siegcloud config set project [PROJECT_ID]
[PROJECT_ID]
durch die ID Ihres Projekts. Wenn Ihre Projekt-ID beispielsweiselab-example-project
lautet, lautet der Befehl: Wenn Sie die folgende Meldung erhalten, dass gcloud Ihre Anmeldedaten für die GCPI API anfordert, klicken Sie auf Autorisieren, um fortzufahren.gcloud config set project lab-project-id-example
Nach erfolgreicher Ausführung sollte die folgende Meldung angezeigt werden: Wenn du die MeldungUpdated property [core/project].
WARNING
und die FrageDo you want to continue (Y/N)?
siehst, hast du wahrscheinlich die Projekt-ID falsch eingegeben. Drücken SieN
,Enter
und versuchen Sie dann noch einmal, den Befehlgcloud config set project
auszuführen, nachdem Sie die richtige Projekt-ID gefunden haben. - Optional: Wenn Sie die Projekt-ID nicht finden können, führen Sie den folgenden Befehl aus, um die Projekt-IDs aller Ihrer Projekte in absteigender Reihenfolge nach Erstellungszeit aufzulisten:
gcloud projects list \ --format='value(projectId,createTime)' \ --sort-by=~createTime
5. Google APIs aktivieren
Aktivieren Sie im Terminal die für dieses Lab erforderlichen Google APIs:
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
cloudtrace.googleapis.com
Die Ausführung dieses Befehls kann einige Zeit dauern. Schließlich wird eine Meldung wie diese angezeigt:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
Wenn Sie eine Fehlermeldung erhalten, die mit ERROR: (gcloud.services.enable) HttpError accessing
beginnt und Fehlerdetails wie unten enthält, wiederholen Sie den Befehl nach einer Verzögerung von 1 bis 2 Minuten.
"error": { "code": 429, "message": "Quota exceeded for quota metric 'Mutate requests' and limit 'Mutate requests per minute' of service 'serviceusage.googleapis.com' ...", "status": "RESOURCE_EXHAUSTED", ... }
6. Generative AI-Anwendung erstellen
In diesem Schritt schreiben Sie den Code für die einfache anfragebasierte Anwendung, die mit dem Gemini-Modell 10 lustige Fakten zu einem Tier Ihrer Wahl anzeigt. So erstellen Sie den Anwendungscode:
- Erstellen Sie im Terminal das Verzeichnis
codelab-o11y
:mkdir "${HOME}/codelab-o11y"
- Ändern Sie das aktuelle Verzeichnis in
codelab-o11y
:cd "${HOME}/codelab-o11y"
- Laden Sie den Bootstrap-Code der Java-Anwendung mit dem Spring-Framework-Starter herunter:
curl https://start.spring.io/starter.zip \ -d dependencies=web \ -d javaVersion=17 \ -d type=maven-project \ -d bootVersion=3.4.1 -o java-starter.zip
- Entfernen Sie die Archivierung des Bootstrap-Codes aus dem aktuellen Ordner:
unzip java-starter.zip
- Entfernen Sie die Archivdatei aus dem Ordner:
rm java-starter.zip
- Erstellen Sie eine
project.toml
-Datei, um die Java-Laufzeitversion zu definieren, die beim Bereitstellen des Codes in Cloud Run verwendet werden soll:cat > "${HOME}/codelab-o11y/project.toml" << EOF [[build.env]] name = "GOOGLE_RUNTIME_VERSION" value = "17" EOF
- Fügen Sie der
pom.xml
-Datei Google Cloud SDK-Abhängigkeiten hinzu:- Fügen Sie das Google Cloud Core-Paket hinzu:
sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>com.google.cloud<\/groupId>\ <artifactId>google-cloud-core<\/artifactId>\ <version>2.49.1<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Fügen Sie das Google Cloud Vertex AI-Paket hinzu:
sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>com.google.cloud<\/groupId>\ <artifactId>google-cloud-vertexai<\/artifactId>\ <version>1.16.0<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Fügen Sie das Google Cloud Core-Paket hinzu:
- Öffnen Sie die Datei
DemoApplication.java
im Cloud Shell-Editor: Im Editorfenster über dem Terminal sollte jetzt der gescaffoldte Quellcode der Dateicloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
DemoApplication.java
angezeigt werden. Der Quellcode der Datei sieht in etwa so aus:package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
- Ersetzen Sie den Code im Editor durch die unten stehende Version. Wenn Sie den Code ersetzen möchten, löschen Sie den Inhalt der Datei und kopieren Sie den folgenden Code in den Editor:
Nach einigen Sekunden wird der Code im Cloud Shell-Editor automatisch gespeichert.package com.example.demo; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); return ResponseHandler.getText(response); } }
Code der Gen AI-Anwendung in Cloud Run bereitstellen
- Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
Sie sehen die folgende Aufforderung, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie aufgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. Die Bereitstellung kann einige Minuten dauern. Nach Abschluss des Bereitstellungsvorgangs wird eine Ausgabe wie die folgende angezeigt:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL zu drucken, und dann bei gedrückter Strg-Taste auf die angezeigte URL klicken, um sie zu öffnen:
Wenn die URL geöffnet wird, erhalten Sie möglicherweise den Fehler 500 oder die Meldung:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Die Bereitstellung der Dienste wurde nicht abgeschlossen. Warten Sie einen Moment und aktualisieren Sie die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 lustige Fakten über Hunde enthält.Sorry, this is just a placeholder...
Interagieren Sie mit der App, um interessante Fakten über verschiedene Tiere zu erfahren. Fügen Sie dazu den Parameter animal
an die URL an, z. B. ?animal=[ANIMAL]
, wobei [ANIMAL]
ein Tiername ist. Fügen Sie beispielsweise ?animal=cat
hinzu, um 10 lustige Fakten über Katzen zu erhalten, oder ?animal=sea turtle
, um 10 lustige Fakten über Meeresschildkröten zu erhalten.
7. Vertex API-Aufrufe prüfen
Durch die Analyse von Google API-Aufrufen erhalten Sie Antworten auf Fragen wie „Wer ruft eine bestimmte API wo und wann auf?“. Audits sind wichtig, wenn Sie Probleme mit Ihrer Anwendung beheben, den Ressourcenverbrauch untersuchen oder eine forensische Softwareanalyse durchführen.
Mit Audit-Logs können Sie Administrator- und Systemaktivitäten erfassen sowie Aufrufe von API-Vorgängen vom Typ „Daten lesen“ und „Daten schreiben“ protokollieren. Wenn Sie Vertex AI-Anfragen zum Generieren von Inhalten prüfen möchten, müssen Sie in der Cloud Console Audit-Logs für „Datenlesevorgänge“ aktivieren.
- Klicken Sie auf die Schaltfläche unten, um die Seite „Audit-Logs“ in der Cloud Console zu öffnen.
- Achten Sie darauf, dass auf der Seite das Projekt ausgewählt ist, das Sie für dieses Lab erstellt haben. Das ausgewählte Projekt wird links oben auf der Seite direkt neben dem Dreistrich-Menü angezeigt:
Wählen Sie bei Bedarf das richtige Projekt aus der Drop-down-Liste aus. - Suchen Sie in der Tabelle Konfiguration für Audit-Logs zum Datenzugriff in der Spalte „Dienst“ nach dem Dienst
Vertex AI API
und aktivieren Sie das Kästchen links neben dem Dienstnamen. - Wählen Sie im Infofeld rechts den Analysetyp „Datenlesevorgang“ aus.
- Klicken Sie auf Speichern.
Öffnen Sie die Dienst-URL, um Audit-Logs zu generieren. Aktualisieren Sie die Seite und ändern Sie dabei den Wert des Parameters ?animal=
, um andere Ergebnisse zu erhalten.
Audit-Logs analysieren
- Klicken Sie auf die Schaltfläche unten, um die Seite „Log-Explorer“ in der Cloud Console zu öffnen:
- Fügen Sie den folgenden Filter in den Bereich „Abfrage“ ein.
Der Bereich „Abfrage“ ist ein Editor, der sich oben auf der Seite „Log-Explorer“ befindet:LOG_ID("cloudaudit.googleapis.com%2Fdata_access") AND protoPayload.serviceName="aiplatform.googleapis.com"
- Klicken Sie auf Abfrage ausführen.
- Wählen Sie einen der Einträge im Audit-Log aus und maximieren Sie die Felder, um die im Log erfassten Informationen zu prüfen.
Sie können Details zum Vertex API-Aufruf sehen, einschließlich der verwendeten Methode und des Modells. Außerdem sehen Sie die Identität des Aufrufers und die Berechtigungen, die den Aufruf autorisiert haben.
8. Interaktionen mit generativer KI protokollieren
In Audit-Logs finden Sie keine API-Anfrageparameter oder Antwortdaten. Diese Informationen können jedoch für die Fehlerbehebung bei der Anwendungs- und Workflowanalyse wichtig sein. In diesem Schritt schließen wir diese Lücke, indem wir Anwendungsprotokolle hinzufügen.
Bei der Implementierung wird Logback mit Spring Boot verwendet, um Anwendungsprotokolle in die Standardausgabe zu drucken. Bei dieser Methode werden Informationen, die in die Standardausgabe gedruckt werden, mit Cloud Run erfasst und automatisch in Cloud Logging aufgenommen. Damit Informationen als strukturierte Daten erfasst werden können, sollten die ausgedruckten Protokolle entsprechend formatiert sein. Folgen Sie der Anleitung unten, um der Anwendung Funktionen für strukturiertes Logging hinzuzufügen.
- Kehren Sie im Browser zum Cloud Shell-Fenster (oder -Tab) zurück.
- Erstellen Sie eine neue Datei
LoggingEventGoogleCloudEncoder.java
im Cloud Shell-Editor und öffnen Sie sie:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Kopieren Sie den folgenden Code und fügen Sie ihn ein, um den Logback-Encoder zu implementieren, der das Protokoll als JSON-String im strukturierten Protokollformat von Google Cloud codiert:
package com.example.demo; import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET; import java.time.Instant; import ch.qos.logback.core.encoder.EncoderBase; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import java.util.HashMap; import com.google.gson.Gson; public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> { private static final byte[] EMPTY_BYTES = new byte[0]; private final Gson gson = new Gson(); @Override public byte[] headerBytes() { return EMPTY_BYTES; } @Override public byte[] encode(ILoggingEvent e) { var timestamp = Instant.ofEpochMilli(e.getTimeStamp()); var fields = new HashMap<String, Object>() { { put("timestamp", timestamp.toString()); put("severity", severityFor(e.getLevel())); put("message", e.getMessage()); } }; var params = e.getKeyValuePairs(); if (params != null && params.size() > 0) { params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value)); } var data = gson.toJson(fields) + "\n"; return data.getBytes(UTF_8_CHARSET); } @Override public byte[] footerBytes() { return EMPTY_BYTES; } private static String severityFor(Level level) { switch (level.toInt()) { case Level.TRACE_INT: return "DEBUG"; case Level.DEBUG_INT: return "DEBUG"; case Level.INFO_INT: return "INFO"; case Level.WARN_INT: return "WARNING"; case Level.ERROR_INT: return "ERROR"; default: return "DEFAULT"; } } }
- Erstellen Sie eine neue Datei
logback.xml
im Cloud Shell-Editor und öffnen Sie sie:cloudshell edit "${HOME}/codelab-o11y/src/main/resources/logback.xml"
- Kopieren Sie die folgende XML-Datei und fügen Sie sie ein, um Logback so zu konfigurieren, dass der Encoder mit dem Logback-Appender verwendet wird, der Protokolle auf die Standardausgabe druckt:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="com.example.demo.LoggingEventGoogleCloudEncoder"/> </appender> <root level="info"> <appender-ref ref="Console" /> </root> </configuration>
- Öffnen Sie die Datei
DemoApplication.java
noch einmal im Cloud Shell-Editor:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Ersetzen Sie den Code im Editor durch die unten stehende Version, um Gen AI-Anfrage und ‑Antwort zu protokollieren. Wenn Sie den Code ersetzen möchten, löschen Sie den Inhalt der Datei und kopieren Sie den folgenden Code in den Editor:
package com.example.demo; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class); @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); LOGGER.atInfo() .addKeyValue("animal", animal) .addKeyValue("prompt", prompt) .addKeyValue("response", response) .log("Content is generated"); return ResponseHandler.getText(response); } }
Nach einigen Sekunden werden Ihre Änderungen automatisch im Cloud Shell-Editor gespeichert.
Code der Gen AI-Anwendung in Cloud Run bereitstellen
- Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
Sie sehen die folgende Aufforderung, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie aufgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. Die Bereitstellung kann einige Minuten dauern. Nach Abschluss des Bereitstellungsvorgangs wird eine Ausgabe wie die folgende angezeigt:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL zu drucken, und dann bei gedrückter Strg-Taste auf die angezeigte URL klicken, um sie zu öffnen:
Wenn die URL geöffnet wird, erhalten Sie möglicherweise den Fehler 500 oder die Meldung:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Die Bereitstellung der Dienste wurde nicht abgeschlossen. Warten Sie einen Moment und aktualisieren Sie die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 lustige Fakten über Hunde enthält.Sorry, this is just a placeholder...
Öffnen Sie die Dienst-URL, um Anwendungsprotokolle zu generieren. Aktualisieren Sie die Seite und ändern Sie dabei den Wert des Parameters ?animal=
, um andere Ergebnisse zu erhalten.
So rufen Sie die Anwendungsprotokolle auf:
- Klicken Sie auf die Schaltfläche unten, um die Seite „Log-Explorer“ in der Cloud Console zu öffnen:
- Fügen Sie den folgenden Filter in den Abfragebereich 2 in der Log-Explorer-Benutzeroberfläche ein:
LOG_ID("run.googleapis.com%2Fstdout") AND severity=DEBUG
- Klicken Sie auf Abfrage ausführen.
Das Ergebnis der Abfrage enthält Protokolle mit Prompt und Vertex AI-Antwort, einschließlich Sicherheitsbewertungen.
9. Interaktionen mit generativer KI zählen
Cloud Run schreibt verwaltete Messwerte, mit denen bereitgestellte Dienste überwacht werden können. Von Nutzern verwaltete Monitoring-Messwerte bieten mehr Kontrolle über Daten und Häufigkeit der Aktualisierung der Messwerte. Zur Implementierung eines solchen Messwerts muss Code geschrieben werden, der Daten erfasst und in Cloud Monitoring schreibt. Im nächsten (optionalen) Schritt erfahren Sie, wie Sie dies mit dem OpenTelemetry SDK implementieren.
In diesem Schritt wird eine Alternative zur Implementierung von Nutzermesswerten im Code gezeigt: logbasierte Messwerte. Mit logbasierten Messwerten können Sie Monitoring-Messwerte aus den Logeinträgen generieren, die Ihre Anwendung in Cloud Logging schreibt. Wir verwenden die im vorherigen Schritt implementierten Anwendungsprotokolle, um einen logbasierten Messwert für den Typzähler zu definieren. Der Messwert zählt die Anzahl der erfolgreichen Aufrufe der Vertex API.
- Sehen Sie sich das Fenster des Log-Explorers an, den wir im vorherigen Schritt verwendet haben. Klicken Sie im Bereich „Abfrage“ auf das Drop-down-Menü Aktionen, um es zu öffnen. Im Screenshot unten sehen Sie das Menü:
- Wählen Sie im Menü die Option Messwert erstellen aus, um den Bereich Logbasierten Messwert erstellen zu öffnen.
- So konfigurieren Sie einen neuen Zählermesswert im Bereich Logbasierten Messwert erstellen:
- Legen Sie den Messwerttyp fest: Wählen Sie Zähler aus.
- Legen Sie im Abschnitt Details die folgenden Felder fest:
- Name des Logmesswerts: Legen Sie als Namen
model_interaction_count
fest. Für die Benennung gelten einige Einschränkungen. Weitere Informationen dazu finden Sie unter Fehlerbehebung bei Benennungsbeschränkungen. - Beschreibung: Geben Sie eine Beschreibung für den Messwert ein. z. B.
Number of log entries capturing successful call to model inference.
. - Einheiten: Lassen Sie dieses Feld leer oder geben Sie die Zahl
1
ein.
- Name des Logmesswerts: Legen Sie als Namen
- Lassen Sie die Werte im Abschnitt Filterauswahl unverändert. Beachten Sie, dass im Feld Build-Filter derselbe Filter verwendet wird, mit dem wir die Anwendungsprotokolle aufgerufen haben.
- Optional: Fügen Sie ein Label hinzu, mit dem sich die Anzahl der Anrufe für jedes Tier zählen lässt. HINWEIS: Dieses Label kann die Kardinalität des Messwerts erheblich erhöhen und wird für die Produktion nicht empfohlen:
- Klicken Sie auf Label hinzufügen.
- Legen Sie im Abschnitt Labels die folgenden Felder fest:
- Labelname: Legen Sie als Namen
animal
fest. - Beschreibung: Geben Sie die Beschreibung des Labels ein. Beispiel:
Animal parameter
. - Labeltyp: Wählen Sie
STRING
aus. - Feldname: Geben Sie
jsonPayload.animal
ein. - Regulärer Ausdruck: Lassen Sie das Feld leer.
- Labelname: Legen Sie als Namen
- Klicken Sie auf Fertig.
- Klicken Sie auf Messwert erstellen, um den Messwert zu erstellen.
Sie können einen logbasierten Messwert auch auf der Seite Logbasierte Messwerte, mit dem gcloud logging metrics create
-Befehl oder mit der google_logging_metric
-Terraform-Ressource erstellen.
Öffnen Sie die Dienst-URL, um Messwertdaten zu generieren. Aktualisieren Sie die geöffnete Seite mehrmals, um das Modell mehrmals aufzurufen. Verwenden Sie wie zuvor verschiedene Tiere im Parameter.
Geben Sie die PromQL-Abfrage ein, um nach den logbasierten Messwertdaten zu suchen. So geben Sie eine PromQL-Abfrage ein:
- Klicken Sie auf die Schaltfläche unten, um die Seite „Metrics Explorer“ in der Cloud Console zu öffnen:
- Klicken Sie in der Symbolleiste des Bereichs „Query Builder“ auf die Schaltfläche < > MQL oder < > PromQL. Die Schaltfläche befindet sich an der Stelle, die auf der Abbildung unten markiert ist.
- Prüfen Sie, ob PromQL im Schalter Sprache ausgewählt ist. Die Sprachschaltfläche befindet sich in derselben Symbolleiste, mit der Sie Ihre Abfrage formatieren können.
- Geben Sie die Abfrage in den Editor Abfragen ein:
Weitere Informationen zur Verwendung von PromQL finden Sie unter PromQL in Cloud Monitoring.sum(rate(logging_googleapis_com:user_model_interaction_count{monitored_resource="cloud_run_revision"}[${__interval}]))
- Klicken Sie auf Abfrage ausführen. Sie sehen ein Liniendiagramm, das diesem Screenshot ähnelt:
Wenn die Ein/Aus-Schaltfläche Automatisch ausführen aktiviert ist, wird die Schaltfläche Abfrage ausführen nicht angezeigt.
10. Optional: OpenTelemetry für Monitoring und Tracing verwenden
Wie im vorherigen Schritt erwähnt, ist es möglich, Messwerte mit dem OpenTelemetry (Otel) SDK zu implementieren. Die Verwendung von OTel in Multi-Service-Architekturen wird empfohlen. In diesem Schritt wird gezeigt, wie einer Spring Boot-Anwendung OTel-Instrumentierung hinzugefügt wird. In diesem Schritt gehen Sie so vor:
- Spring Boot-Anwendung mit automatischen Tracing-Funktionen instrumentieren
- Zählermesswert zum Überwachen der Anzahl der erfolgreichen Modellaufrufe implementieren
- Traces mit Anwendungslogs korrelieren
Für Dienste auf Produktebene wird die Verwendung des OTel-Collectors empfohlen, um alle ObservabilitÄtsdaten aus mehreren Diensten zu erfassen und zu verarbeiten. Der Code in diesem Schritt verwendet aus Gründen der Einfachheit keinen Collector. Stattdessen werden OTel-Exporte verwendet, die Daten direkt in Google Cloud schreiben.
Spring Boot-Anwendung mit OTel-Komponenten und automatischem Tracing einrichten
- Kehren Sie im Browser zum Cloud Shell-Fenster (oder -Tab) zurück.
- Aktualisieren Sie im Terminal die Datei
application.permissions
mit zusätzlichen Konfigurationsparametern: Mit diesen Parametern wird der Export von Observabilitӓtsdaten nach Cloud Trace und Cloud Monitoring definiert und die Stichprobenerhebung für alle Traces erzwungen.cat >> "${HOME}/codelab-o11y/src/main/resources/application.properties" << EOF otel.logs.exporter=none otel.traces.exporter=google_cloud_trace otel.metrics.exporter=google_cloud_monitoring otel.resource.attributes.service.name=codelab-o11y-service otel.traces.sampler=always_on EOF
- Fügen Sie der Datei
pom.xml
die erforderlichen OpenTelemetry-Abhängigkeiten hinzu:sed -i 's/<dependencies>/<dependencies>\ \ <dependency>\ <groupId>io.opentelemetry.instrumentation<\/groupId>\ <artifactId>opentelemetry-spring-boot-starter<\/artifactId>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-auto<\/artifactId>\ <version>0.33.0-alpha<\/version>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-trace<\/artifactId>\ <version>0.33.0<\/version>\ <\/dependency>\ <dependency>\ <groupId>com.google.cloud.opentelemetry<\/groupId>\ <artifactId>exporter-metrics<\/artifactId>\ <version>0.33.0<\/version>\ <\/dependency>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Fügen Sie der Datei
pom.xml
die OpenTelemetry-BOM hinzu:sed -i 's/<\/properties>/<\/properties>\ <dependencyManagement>\ <dependencies>\ <dependency>\ <groupId>io.opentelemetry.instrumentation<\/groupId>\ <artifactId>opentelemetry-instrumentation-bom<\/artifactId>\ <version>2.12.0<\/version>\ <type>pom<\/type>\ <scope>import<\/scope>\ <\/dependency>\ <\/dependencies>\ <\/dependencyManagement>\ /g' "${HOME}/codelab-o11y/pom.xml"
- Öffnen Sie die Datei
DemoApplication.java
noch einmal im Cloud Shell-Editor:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/DemoApplication.java"
- Ersetzen Sie den aktuellen Code durch die Version, die einen Leistungsmesswert inkrementiert. Wenn Sie den Code ersetzen möchten, löschen Sie den Inhalt der Datei und kopieren Sie den folgenden Code in den Editor:
package com.example.demo; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.LongCounter; import java.io.IOException; import java.util.Collections; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.google.cloud.ServiceOptions; import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.generativeai.GenerativeModel; import com.google.cloud.vertexai.generativeai.ResponseHandler; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { String port = System.getenv().getOrDefault("PORT", "8080"); SpringApplication app = new SpringApplication(DemoApplication.class); app.setDefaultProperties(Collections.singletonMap("server.port", port)); app.run(args); } } @RestController class HelloController { private final String projectId = ServiceOptions.getDefaultProjectId(); private VertexAI vertexAI; private GenerativeModel model; private final Logger LOGGER = LoggerFactory.getLogger(HelloController.class); private static final String INSTRUMENTATION_NAME = "genai-o11y/java/workshop/example"; private static final AttributeKey<String> ANIMAL = AttributeKey.stringKey("animal"); private final LongCounter counter; public HelloController(OpenTelemetry openTelemetry) { this.counter = openTelemetry.getMeter(INSTRUMENTATION_NAME) .counterBuilder("model_call_counter") .setDescription("Number of successful model calls") .build(); } @PostConstruct public void init() { vertexAI = new VertexAI(projectId, "us-central1"); model = new GenerativeModel("gemini-1.5-flash", vertexAI); } @PreDestroy public void destroy() { vertexAI.close(); } @GetMapping("/") public String getFacts(@RequestParam(defaultValue = "dog") String animal) throws IOException { String prompt = "Give me 10 fun facts about " + animal + ". Return this as html without backticks."; GenerateContentResponse response = model.generateContent(prompt); LOGGER.atInfo() .addKeyValue("animal", animal) .addKeyValue("prompt", prompt) .addKeyValue("response", response) .log("Content is generated"); counter.add(1, Attributes.of(ANIMAL, animal)); return ResponseHandler.getText(response); } }
- Öffnen Sie die Datei
LoggingEventGoogleCloudEncoder.java
noch einmal im Cloud Shell-Editor:cloudshell edit "${HOME}/codelab-o11y/src/main/java/com/example/demo/LoggingEventGoogleCloudEncoder.java"
- Ersetzen Sie den aktuellen Code durch die Version, die den aufgezeichneten Protokollen Trace-Attribute hinzufügt. Durch das Hinzufügen der Attribute können Protokolle mit den richtigen Trace-Bereichen korreliert werden. Wenn Sie den Code ersetzen möchten, löschen Sie den Inhalt der Datei und kopieren Sie den folgenden Code in den Editor:
package com.example.demo; import static ch.qos.logback.core.CoreConstants.UTF_8_CHARSET; import java.time.Instant; import java.util.HashMap; import ch.qos.logback.core.encoder.EncoderBase; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import com.google.cloud.ServiceOptions; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; import com.google.gson.Gson; public class LoggingEventGoogleCloudEncoder extends EncoderBase<ILoggingEvent> { private static final byte[] EMPTY_BYTES = new byte[0]; private final Gson gson; private final String projectId; private final String tracePrefix; public LoggingEventGoogleCloudEncoder() { this.gson = new Gson(); this.projectId = lookUpProjectId(); this.tracePrefix = "projects/" + (projectId == null ? "" : projectId) + "/traces/"; } private static String lookUpProjectId() { return ServiceOptions.getDefaultProjectId(); } @Override public byte[] headerBytes() { return EMPTY_BYTES; } @Override public byte[] encode(ILoggingEvent e) { var timestamp = Instant.ofEpochMilli(e.getTimeStamp()); var fields = new HashMap<String, Object>() { { put("timestamp", timestamp.toString()); put("severity", severityFor(e.getLevel())); put("message", e.getMessage()); SpanContext context = Span.fromContext(Context.current()).getSpanContext(); if (context.isValid()) { put("logging.googleapis.com/trace", tracePrefix + context.getTraceId()); put("logging.googleapis.com/spanId", context.getSpanId()); put("logging.googleapis.com/trace_sampled", Boolean.toString(context.isSampled())); } } }; var params = e.getKeyValuePairs(); if (params != null && params.size() > 0) { params.forEach(kv -> fields.putIfAbsent(kv.key, kv.value)); } var data = gson.toJson(fields) + "\n"; return data.getBytes(UTF_8_CHARSET); } @Override public byte[] footerBytes() { return EMPTY_BYTES; } private static String severityFor(Level level) { switch (level.toInt()) { case Level.TRACE_INT: return "DEBUG"; case Level.DEBUG_INT: return "DEBUG"; case Level.INFO_INT: return "INFO"; case Level.WARN_INT: return "WARNING"; case Level.ERROR_INT: return "ERROR"; default: return "DEFAULT"; } } }
Nach einigen Sekunden werden Ihre Änderungen automatisch im Cloud Shell-Editor gespeichert.
Code der Gen AI-Anwendung in Cloud Run bereitstellen
- Führen Sie im Terminalfenster den Befehl aus, um den Quellcode der Anwendung in Cloud Run bereitzustellen.
Sie sehen die folgende Aufforderung, dass mit dem Befehl ein neues Repository erstellt wird. Klicken Sie aufgcloud run deploy codelab-o11y-service \ --source="${HOME}/codelab-o11y/" \ --region=us-central1 \ --allow-unauthenticated
Enter
. Die Bereitstellung kann einige Minuten dauern. Nach Abschluss des Bereitstellungsvorgangs wird eine Ausgabe wie die folgende angezeigt:Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created. Do you want to continue (Y/n)?
Service [codelab-o11y-service] revision [codelab-o11y-service-00001-t2q] has been deployed and is serving 100 percent of traffic. Service URL: https://codelab-o11y-service-12345678901.us-central1.run.app
- Kopieren Sie die angezeigte Cloud Run-Dienst-URL in einen separaten Tab oder ein separates Fenster in Ihrem Browser. Alternativ können Sie den folgenden Befehl im Terminal ausführen, um die Dienst-URL zu drucken, und dann bei gedrückter Strg-Taste auf die angezeigte URL klicken, um sie zu öffnen:
Wenn die URL geöffnet wird, erhalten Sie möglicherweise den Fehler 500 oder die Meldung:gcloud run services list \ --format='value(URL)' \ --filter='SERVICE:"codelab-o11y-service"'
Die Bereitstellung der Dienste wurde nicht abgeschlossen. Warten Sie einen Moment und aktualisieren Sie die Seite. Am Ende sehen Sie einen Text, der mit Fun Dog Facts beginnt und 10 lustige Fakten über Hunde enthält.Sorry, this is just a placeholder...
Wenn Sie Telemetry-Daten generieren möchten, öffnen Sie die Dienst-URL. Aktualisieren Sie die Seite und ändern Sie dabei den Wert des Parameters ?animal=
, um andere Ergebnisse zu erhalten.
Anwendungs-Traces untersuchen
- Klicken Sie auf die Schaltfläche unten, um die Seite „Trace Explorer“ in der Cloud Console zu öffnen:
- Wählen Sie einen der letzten Protokolle aus. Sie sollten fünf oder sechs Bereiche sehen, die wie im Screenshot unten aussehen.
- Suchen Sie den Span, der den Aufruf an den Ereignis-Handler (die Methode
fun_facts
) nachverfolgt. Es ist die letzte Span-Element mit dem Namen/
. - Wählen Sie im Bereich Trace-Details die Option Protokolle und Ereignisse aus. Sie sehen Anwendungslogs, die mit diesem bestimmten Span übereinstimmen. Die Korrelation wird anhand der Trace- und Span-IDs im Trace und im Log erkannt. Sie sollten das Anwendungsprotokoll sehen, in dem der Prompt geschrieben wurde, und die Antwort der Vertex API.
Zählermesswert untersuchen
- Klicken Sie auf die Schaltfläche unten, um die Seite „Metrics Explorer“ in der Cloud Console zu öffnen:
- Klicken Sie in der Symbolleiste des Bereichs „Query Builder“ auf die Schaltfläche < > MQL oder < > PromQL. Die Schaltfläche befindet sich an der Stelle, die auf der Abbildung unten markiert ist.
- Prüfen Sie, ob PromQL im Schalter Sprache ausgewählt ist. Die Sprachschaltfläche befindet sich in derselben Symbolleiste, mit der Sie Ihre Abfrage formatieren können.
- Geben Sie die Abfrage in den Editor Abfragen ein:
sum(rate(workload_googleapis_com:model_call_counter{monitored_resource="generic_task"}[${__interval}]))
- Klicken Sie auf Abfrage ausführen.Wenn die Ein/Aus-Schaltfläche Automatisch ausführen aktiviert ist, wird die Schaltfläche Abfrage ausführen nicht angezeigt.
11. (Optional) Verschleierte vertrauliche Informationen aus Protokollen
In Schritt 10 haben wir Informationen zur Interaktion der Anwendung mit dem Gemini-Modell protokolliert. Dazu gehörten der Name des Tieres, der eigentliche Prompt und die Antwort des Modells. Das Speichern dieser Informationen im Protokoll sollte zwar sicher sein, ist aber für viele andere Szenarien nicht unbedingt erforderlich. Der Prompt kann personenbezogene oder anderweitig vertrauliche Daten enthalten, die ein Nutzer nicht gespeichert haben möchte. Sie können die sensiblen Daten, die in Cloud Logging geschrieben werden, unkenntlich machen. Um Codeänderungen zu minimieren, wird die folgende Lösung empfohlen.
- Pub/Sub-Thema zum Speichern eingehender Logeinträge erstellen
- Erstellen Sie eine Log-Senke, die aufgenommene Protokolle an das Pub/Sub-Thema weiterleitet.
- So erstellen Sie eine Dataflow-Pipeline, die Logs, die an ein Pub/Sub-Thema weitergeleitet werden, ändert:
- Logeintrag aus dem Pub/Sub-Thema lesen
- Mit der DLP Inspection API die Nutzlast des Eintrags auf vertrauliche Informationen prüfen
- Entfernen Sie die sensiblen Daten in der Nutzlast mit einer der DLP-Entfernungsmethoden.
- Verschleierten Logeintrag in Cloud Logging schreiben
- Stellen Sie die Pipeline bereit.
12. (Optional) Bereinigen
Um zu vermeiden, dass Ihnen Kosten für die im Codelab verwendeten Ressourcen und APIs in Rechnung gestellt werden, sollten Sie nach Abschluss des Labs eine Bereinigung durchführen. Am einfachsten vermeiden Sie weitere Kosten, indem Sie das für das Codelab erstellte Projekt löschen.
- Führen Sie zum Löschen des Projekts den Befehl „delete project“ im Terminal aus:
Wenn Sie Ihr Cloud-Projekt löschen, wird die Abrechnung für alle in diesem Projekt verwendeten Ressourcen und APIs beendet. Es sollte folgende Meldung angezeigt werden, wobeiPROJECT_ID=$(gcloud config get-value project) gcloud projects delete ${PROJECT_ID} --quiet
PROJECT_ID
Ihre Projekt-ID ist:Deleted [https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID]. You can undo this operation for a limited period by running the command below. $ gcloud projects undelete PROJECT_ID See https://cloud.google.com/resource-manager/docs/creating-managing-projects for information on shutting down projects.
- Optional: Wenn Sie eine Fehlermeldung erhalten, sehen Sie in Schritt 5 nach, wie Sie die Projekt-ID ermitteln, die Sie während des Labs verwendet haben. Ersetzen Sie ihn durch den Befehl in der ersten Anweisung. Wenn Ihre Projekt-ID beispielsweise
lab-example-project
lautet, lautet der Befehl:gcloud projects delete lab-project-id-example --quiet
13. Glückwunsch
In diesem Lab haben Sie eine Anwendung für generative KI erstellt, die mit dem Gemini-Modell Vorhersagen trifft. und die Anwendung mit wichtigen Monitoring- und Logging-Funktionen ausgestattet. Sie haben die Anwendung und die Änderungen aus dem Quellcode in Cloud Run bereitgestellt. Anschließend können Sie mit den Google Cloud-Produkten zur Beobachtbarkeit die Leistung der Anwendung im Blick behalten und so für deren Zuverlässigkeit sorgen.
Wenn Sie an einer UX-Forschungsstudie teilnehmen möchten, um die Produkte zu verbessern, mit denen Sie heute gearbeitet haben, registrieren Sie sich hier.
Hier sind einige Möglichkeiten, wie Sie Ihr Wissen vertiefen können:
- Codelab Gemini-gestützte Chat-App in Cloud Run bereitstellen
- Codelab Gemini-Funktionsaufrufe mit Cloud Run verwenden
- Videos mit der Video Intelligence API in Cloud Run-Jobs sturzweise verarbeiten
- On-Demand-Workshop Google Kubernetes Engine einrichten
- Weitere Informationen zum Konfigurieren von Zähler- und Verteilungsmesswerten mithilfe von Anwendungsprotokollen
- OTLP-Messwerte mit einem OpenTelemetry-Sidecar schreiben
- Referenz zur Verwendung von OpenTelemetry in Google Cloud