Journaliser un agent

Pour utiliser Cloud Logging dans les agents lorsqu'ils sont déployés, utilisez l'une des méthodes suivantes:

  • stdout / stderr: par défaut (sans configuration supplémentaire), les journaux écrits dans stdout et stderr sont acheminés vers les ID de journal reasoning_engine_stdout et reasoning_engine_stderr, respectivement. La seule restriction est qu'ils doivent être au format texte.
  • Journalisation Python: le journalisateur Python intégré peut être intégré à Cloud Logging. Par rapport à l'écriture dans stdout ou stderr, cette méthode prend en charge les journaux structurés et nécessite une configuration minimale.
  • Client Cloud Logging: les utilisateurs peuvent écrire des journaux structurés et ont un contrôle total sur le journalisateur (par exemple, en définissant le logName et le type de ressource).

Écrire des journaux pour un agent

Lorsque vous écrivez des journaux pour un agent, déterminez les éléments suivants:

  • severity: par exemple, "info", "warn" ou "error"
  • charge utile: contenu du journal (par exemple, texte ou JSON)
  • Champs supplémentaires: pour la mise en corrélation entre les journaux (par exemple, trace/intervalle, tags, libellés)

Par exemple, pour consigner l'entrée de chaque requête lorsque vous développez un agent:

stdout ou stderr

from typing import Dict

class MyAgent:

    def set_up(self):
        # No set up required. The logs from stdout and stderr are routed to
        # `reasoning_engine_stdout` and `reasoning_engine_stderr` respectively.
        pass

    def query(self, input: Dict):
        import sys

        print(
            f"input: {input}",
            file=sys.stdout,  # or sys.stderr
        )

Journalisation Python

from typing import Dict

class MyAgent:

    def set_up(self):
        import os
        import google.cloud.logging

        self.logging_client = google.cloud.logging.Client(project="PROJECT_ID")
        self.logging_client.setup_logging(
            name="LOG_ID",  # the ID of the logName in Cloud Logging.
            resource=google.cloud.logging.Resource(
                type="aiplatform.googleapis.com/ReasoningEngine",
                labels={
                    "location": "LOCATION",
                    "resource_container": "PROJECT_ID",
                    "reasoning_engine_id": os.environ.get("K_SERVICE", "").split("-")[-1],
                },
            ),
        )

    def query(self, input: Dict):
        import logging
        import json

        logging_extras = {
            "labels": {"foo": "bar"},
            "trace": "TRACE_ID",
        }

        logging.info( # or .warning(), .error()
            json.dumps(input),
            extra=logging_extras,
        )

Client Cloud Logging

from typing import Dict

class MyAgent:

    def set_up(self):
        import os
        import google.cloud.logging

        self.logging_client = google.cloud.logging.Client(project="PROJECT_ID")
        self.logger = self.logging_client.logger(
            name="LOG_ID",  # the ID of the logName in Cloud Logging.
            resource=google.cloud.logging.Resource(
                type="aiplatform.googleapis.com/ReasoningEngine",
                labels={
                    "location": "LOCATION",
                    "resource_container": "PROJECT_ID",
                    "reasoning_engine_id": os.environ.get("K_SERVICE", "").split("-")[-1],
                },
            ),
        )

    def query(self, input: Dict):
        logging_extras = {
            "labels": {"foo": "bar"},
            "trace": "TRACE_ID",
        }

        self.logger.log_struct(
            input,
            severity="INFO",  # or "DEBUG", "WARNING", "ERROR", "CRITICAL"
            **logging_extras,
        )

Lorsque l'agent est déployé et interrogé, il génère des entrées de journal. Par exemple, le code

remote_agent = agent_engines.create(
    MyAgent(),
    requirements=["cloudpickle==3", "google-cloud-logging"],
)

remote_agent.query(input={"hello": "world"})

génère une entrée de journal semblable à la suivante:

stdout ou stderr

{
  "insertId": "67a3bb3b000cc2df444361ab",
  "textPayload": "input: {'hello': 'world'}",
  "resource": {
    "type": "aiplatform.googleapis.com/ReasoningEngine",
    "labels": {
      "location": "LOCATION",
      "resource_container": "PROJECT_ID",
      "reasoning_engine_id": "RESOURCE_ID"
    }
  },
  "timestamp": "2025-02-05T19:25:47.836319Z",
  "logName": "projects/PROJECT_ID/logs/aiplatform.googleapis.com%2Freasoning_engine_stdout",  # or `*_stderr`
  "receiveTimestamp": "2025-02-05T19:25:47.842550772Z"
}

Journalisation Python

{
  "insertId": "1ek9a2jfqh777z",
  "jsonPayload": {"hello": "world"},
  "resource": {
    "type": "aiplatform.googleapis.com/ReasoningEngine",
    "labels": {
      "location": "LOCATION",
      "resource_container": "PROJECT_ID",
      "reasoning_engine_id": "RESOURCE_ID",
    }
  },
  "timestamp": "2025-02-05T20:30:19.348067Z",
  "severity": "INFO",
  "labels": {
    "foo": "bar",
    "python_logger": "root",
  },
  "logName": "projects/PROJECT_ID/logs/LOG_ID",
  "trace": "TRACE_ID",
  "receiveTimestamp": "2025-01-30T21:38:50.776813191Z"
}

Client Cloud Logging

{
  "insertId": "1ek9a2jfqh777z",
  "jsonPayload": {"hello": "world"},
  "resource": {
    "type": "aiplatform.googleapis.com/ReasoningEngine",
    "labels": {
      "location": "LOCATION",
      "resource_container": "PROJECT_ID",
      "reasoning_engine_id": "RESOURCE_ID",
    }
  },
  "timestamp": "2025-01-30T21:38:50.776813191Z",
  "severity": "INFO",
  "labels": {"foo": "bar"},
  "logName": "projects/PROJECT_ID/logs/LOG_ID",
  "trace": "TRACE_ID",
  "receiveTimestamp": "2025-01-30T21:38:50.776813191Z"
}

Afficher les journaux d'un agent

Vous pouvez afficher les entrées de votre journal à l'aide de l'explorateur de journaux:

  1. Accédez à l'Explorateur de journaux dans la console Google Cloud :

    Accéder à l'explorateur de journaux

  2. Sélectionnez votre projet Google Cloud (correspondant à PROJECT_ID) en haut de la page.

  3. Dans Type de ressource, sélectionnez Vertex AI Reasoning Engine.

Créer des requêtes

Vous pouvez utiliser l'explorateur de journaux pour créer des requêtes de manière incrémentielle. Les requêtes sont généralement créées en fonction des considérations suivantes:

  • timeline: pour rechercher des entrées de journal pertinentes en fonction de l'heure
  • scope: permet de rechercher des entrées de journal pertinentes en fonction des attributs canoniques.
    • resource: séparez-le des autres types de ressources de votre projet.
      • type: apparaît sous le nom "Vertex AI Reasoning Engine" dans l'explorateur de journaux et "aiplatform.googleapis.com/ReasoningEngine" dans l'entrée de journal.
      • labels: pour l'emplacement (LOCATION), le projet PROJECT_ID et la ressource RESOURCE_ID.
    • logName: journal auquel l'entrée de journal appartient :
      • Les entrées de journal au moment de la compilation ont l'ID de journal reasoning_engine_build.
      • Les entrées de journal pour stdout et stderr ont respectivement les ID de journal reasoning_engine_stdout et reasoning_engine_stderr.
      • Les entrées de journal de la journalisation Python ou du client Cloud Logging auront des ID de journal personnalisés en fonction de votre code dans Écrire des journaux pour un agent.
    • trace et span: pour les journaux lors du traçage des requêtes.
    • severity: pour la gravité de l'entrée de journal.
    • insertId: identifiant unique d'une entrée de journal.
  • labels: mappage de paires clé-valeur qui fournit des informations supplémentaires sur l'entrée de journal. Les libellés peuvent être définis par l'utilisateur ou par le système. Ils permettent de classer les journaux et de les rechercher plus facilement dans l'explorateur de journaux.
  • charge utile: contenu de l'entrée de journal.

Voici un exemple de requête pour tous les journaux INFO d'un agent déployé avec RESOURCE_ID:

resource.labels.reasoning_engine_id=RESOURCE_ID AND
severity=INFO

Vous pouvez l'afficher dans l'explorateur de journaux à l'adresse

https://console.cloud.google.com/logs/query;query=severity%3DINFO%0Aresource.labels.reasoning_engine_id%3D%22RESOURCE_ID%22;duration=DURATION?project=PROJECT_ID

où la requête a été correctement encodée en URL et où les autres paramètres sont les suivants:

  • DURATION: par exemple, PT30M pour les 30 dernières minutes (ou PT10M pour les 10 dernières minutes), et
  • PROJECT_ID: Google Cloud projet.

Pour en savoir plus, consultez Créer et enregistrer des requêtes à l'aide du langage de requête Logging.

Interroger les journaux d'un agent

Pour une approche programmatique des requêtes de journaux, deux options courantes s'offrent à vous:

Python

from google.cloud import logging

logging_client = logging.Client(project="PROJECT_ID")
logger = logging_client.logger("LOG_ID")  # E.g. "logging_client"
print("Listing entries for logger {}:".format(logger.name))
for entry in logger.list_entries(
    filter_="resource.labels.reasoning_engine_id=RESOURCE_ID"  # Optional
):
    timestamp = entry.timestamp.isoformat()
    print("* {}: {}".format(timestamp, entry.payload))

Chaque entry correspond à une LogEntry. Pour en savoir plus sur les arguments d'entrée de logger.list_entries, consultez la documentation de référence de l'API.

SQL

Vue des journaux:

SELECT *
FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`

Vue Analytics:

SELECT *
FROM `analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`