Journaliser et afficher des journaux dans Cloud Run

Cette page décrit les journaux disponibles lors de l'utilisation de Cloud Run et explique comment les écrire et les afficher.

Cloud Run comporte deux types de journaux qui sont automatiquement envoyés à Cloud Logging :

  • Journaux de requête (services uniquement) : journaux des requêtes envoyées aux services Cloud Run. Ces journaux sont créés automatiquement.
  • Journaux de conteneur (services, jobs et pools de nœuds de calcul) : journaux émis par les instances, généralement à partir de votre propre code, écrits dans les emplacements compatibles, comme décrit dans la section Écrire des journaux de conteneur.

Afficher les journaux

Vous pouvez afficher les journaux de votre service, de votre job ou de votre pool de nœuds de calcul de plusieurs manières :

Les deux méthodes de console d'affichage des journaux examinent les mêmes journaux stockés dans Cloud Logging, mais l'explorateur de journaux de Cloud Logging fournit plus de détails et davantage de fonctionnalités de filtrage.

Afficher les journaux dans Cloud Run

Vous pouvez afficher les journaux sur la page Cloud Run pour les ressources suivantes :

Afficher les journaux d'un service

Pour afficher les journaux dans la page Cloud Run, procédez comme suit :

  1. Accédez à Cloud Run

  2. Cliquez sur le service dans la liste affichée.

  3. Cliquez sur l'onglet JOURNAUX pour obtenir les journaux de requête et de conteneur pour toutes les révisions de ce service. Vous pouvez filtrer les journaux par niveau de gravité.

Afficher les journaux d'un job

Pour afficher les journaux d'un job dans la page Cloud Run, procédez comme suit :

  1. Accédez à Cloud Run

  2. Cliquez sur Jobs (Tâches).

  3. Localisez le job dans la liste des jobs et cliquez dessus.

  4. Cliquez sur l'onglet JOURNAUX pour obtenir les journaux de conteneur pour toutes les exécutions de ce job. Vous pouvez filtrer les journaux par niveau de gravité.

  5. Si vous souhaitez afficher les journaux préfiltrés pour une exécution de job spécifique, cliquez sur l'exécution du job, puis sur l'onglet JOURNAUX.

Afficher les journaux d'un pool de nœuds de calcul

Pour afficher les journaux d'un pool de nœuds de calcul sur la page Cloud Run :

  1. Accédez à Cloud Run

  2. Cliquez sur Pools de nœuds de calcul.

  3. Cliquez sur le pool de nœuds de calcul dans la liste affichée.

  4. Cliquez sur l'onglet JOURNAUX pour obtenir les journaux de requête et de conteneur pour toutes les révisions de ce pool de nœuds de calcul. Vous pouvez filtrer les journaux par niveau de gravité.

Afficher les journaux à l'aide de Google Cloud CLI

Vous pouvez utiliser Google Cloud CLI pour afficher les journaux d'affichage ou afficher les journaux existants d'un service Cloud Run dans la ligne de commande. Par défaut, les journaux sont formatés sur une seule ligne optimisée pour la console.

Pour afficher les dernières lignes des journaux, vous devez installer le composant log-streaming dans Google Cloud CLI. Si le composant n'est pas installé, vous serez invité à l'installer en temps utile.

Afficher les dernières lignes des journaux dans la ligne de commande

Pour un service Cloud Run, vous pouvez afficher les journaux en temps réel depuis votre service Cloud Run directement dans la ligne de commande :

gcloud beta run services logs tail SERVICE --project PROJECT-ID

Remplacez :

  • SERVICE par le nom du service Cloud Run.
  • PROJECT-ID par l'ID du projet Google Cloud . Vous pouvez afficher votre ID de projet en exécutant la commande gcloud config get-value project.

Lire des journaux dans la ligne de commande

Pour un service Cloud Run, vous pouvez lire les journaux existants de deux manières :

  • Dans un format optimisé pour la console :
    gcloud run services logs read SERVICE --limit=10 --project PROJECT-ID
  • Directement depuis Cloud Logging :
    gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=SERVICE" --project PROJECT-ID --limit 10

Remplacez :

  • SERVICE par le nom du service Cloud Run.
  • PROJECT-ID par l'ID du projet Google Cloud . Vous pouvez afficher votre ID de projet en exécutant la commande gcloud config get-value project.

Afficher les journaux dans Cloud Logging

Pour afficher vos journaux Cloud Run dans l'explorateur de journaux Cloud Logging, procédez comme suit :

  1. Accédez à la page "Explorateur de journaux" dans la consoleGoogle Cloud  :

    Accéder à la page "Explorateur de journaux"

  2. Sélectionnez un projet Google Cloud existant en haut de la page ou créez-en un.

  3. À l'aide des menus déroulants, sélectionnez la ressource :

    • Révision Cloud Run pour un service
    • Job Cloud Run pour un job
    • Pool de nœuds de calcul Cloud Run pour un pool de nœuds de calcul

Pour en savoir plus, consultez la page Utiliser l'explorateur de journaux.

Afficher les journaux dans Cloud Code

Pour afficher vos journaux dans Cloud Code, consultez les guides IntelliJ et Visual Studio Code.

Lire les journaux de manière automatisée

Si vous souhaitez lire les journaux de manière automatisée, vous pouvez utiliser l'une des méthodes suivantes :

Écrire des journaux de conteneur

Lorsque vous écrivez des journaux à partir de votre service, job ou pool de nœuds de calcul, ils sont automatiquement récupérés par Cloud Logging à condition qu'ils soient écrits dans l'un des emplacements suivants :

La plupart des développeurs sont censés écrire des journaux à l'aide des flux de résultat standard et d'erreur standard.

Les journaux de conteneur écrits dans ces emplacements compatibles sont automatiquement associés au service, à la révision et à l'emplacement Cloud Run, au pool de nœuds de calcul, à la révision et à l'emplacement Cloud Run, ou au job Cloud Run. Les exceptions contenues dans ces journaux sont capturées et signalées dans Error Reporting.

La journalisation intégrée permet d'équilibrer la fiabilité et l'utilisation des ressources. Elle devrait fonctionner pour la plupart des applications. L'écriture d'entrées de journal à l'aide de la journalisation intégrée ne consomme pas de quota pour le nombre de requêtes entries.write par minute de l'API Cloud Logging.

Si votre application présente des exigences plus drastiques en termes de volume ou de fiabilité, nous vous recommandons d'utiliser directement l'API Cloud Logging, soit en tant que bibliothèque au sein de votre application, soit en tant que conteneur side-car distinct.

Utiliser du texte simple au lieu des données JSON structurées dans les journaux

Lorsque vous écrivez des journaux, vous pouvez envoyer une simple chaîne de texte ou une seule ligne de données JSON sérialisées, également appelées données "structurées". Ces données sont récupérées et analysées par Cloud Logging, puis placées dans jsonPayload. En revanche, le message en texte simple est placé dans textPayload.

Écrire des journaux structurés

L'extrait suivant montre comment écrire des entrées de journal structurées. Il montre également comment mettre en corrélation les messages de journal avec le journal de requête correspondant.

Node.js


// Uncomment and populate this variable in your code:
// const project = 'The project ID of your function or Cloud Run service';

// Build structured log messages as an object.
const globalLogFields = {};

// Add log correlation to nest all log messages beneath request log in Log Viewer.
// (This only works for HTTP-based invocations where `req` is defined.)
if (typeof req !== 'undefined') {
  const traceHeader = req.header('X-Cloud-Trace-Context');
  if (traceHeader && project) {
    const [trace] = traceHeader.split('/');
    globalLogFields['logging.googleapis.com/trace'] =
      `projects/${project}/traces/${trace}`;
  }
}

// Complete a structured log entry.
const entry = Object.assign(
  {
    severity: 'NOTICE',
    message: 'This is the default display field.',
    // Log viewer accesses 'component' as 'jsonPayload.component'.
    component: 'arbitrary-property',
  },
  globalLogFields
);

// Serialize to a JSON string and output.
console.log(JSON.stringify(entry));

Python

# Uncomment and populate this variable in your code:
# PROJECT = 'The project ID of your Cloud Run service';

# Build structured log messages as an object.
global_log_fields = {}

# Add log correlation to nest all log messages.
# This is only relevant in HTTP-based contexts, and is ignored elsewhere.
# (In particular, non-HTTP-based Cloud Functions.)
request_is_defined = "request" in globals() or "request" in locals()
if request_is_defined and request:
    trace_header = request.headers.get("X-Cloud-Trace-Context")

    if trace_header and PROJECT:
        trace = trace_header.split("/")
        global_log_fields[
            "logging.googleapis.com/trace"
        ] = f"projects/{PROJECT}/traces/{trace[0]}"

# Complete a structured log entry.
entry = dict(
    severity="NOTICE",
    message="This is the default display field.",
    # Log viewer accesses 'component' as jsonPayload.component'.
    component="arbitrary-property",
    **global_log_fields,
)

print(json.dumps(entry))

Go

La structure de chaque entrée de journal est fournie par un type Entry :


// Entry defines a log entry.
type Entry struct {
	Message  string `json:"message"`
	Severity string `json:"severity,omitempty"`
	Trace    string `json:"logging.googleapis.com/trace,omitempty"`

	// Logs Explorer allows filtering and display of this as `jsonPayload.component`.
	Component string `json:"component,omitempty"`
}

// String renders an entry structure to the JSON format expected by Cloud Logging.
func (e Entry) String() string {
	if e.Severity == "" {
		e.Severity = "INFO"
	}
	out, err := json.Marshal(e)
	if err != nil {
		log.Printf("json.Marshal: %v", err)
	}
	return string(out)
}

Lorsqu'une structure Entry est journalisée, la méthode String est appelée pour la convertir au format JSON attendu par Cloud Logging :


func init() {
	// Disable log prefixes such as the default timestamp.
	// Prefix text prevents the message from being parsed as JSON.
	// A timestamp is added when shipping logs to Cloud Logging.
	log.SetFlags(0)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	// Uncomment and populate this variable in your code:
	// projectID = "The project ID of your Cloud Run service"

	// Derive the traceID associated with the current request.
	var trace string
	if projectID != "" {
		traceHeader := r.Header.Get("X-Cloud-Trace-Context")
		traceParts := strings.Split(traceHeader, "/")
		if len(traceParts) > 0 && len(traceParts[0]) > 0 {
			trace = fmt.Sprintf("projects/%s/traces/%s", projectID, traceParts[0])
		}
	}

	log.Println(Entry{
		Severity:  "NOTICE",
		Message:   "This is the default display field.",
		Component: "arbitrary-property",
		Trace:     trace,
	})

	fmt.Fprintln(w, "Hello Logger!")
}

Java

Activez la journalisation JSON avec Logback et SLF4J en activant l'encodeur JSON Logstash dans votre configuration logback.xml.

// Build structured log messages as an object.
Object globalLogFields = null;

// Add log correlation to nest all log messages beneath request log in Log Viewer.
// TODO(developer): delete this code if you're creating a Cloud
//                  Function and it is *NOT* triggered by HTTP.
String traceHeader = req.headers("x-cloud-trace-context");
if (traceHeader != null && project != null) {
  String trace = traceHeader.split("/")[0];
  globalLogFields =
      kv(
          "logging.googleapis.com/trace",
          String.format("projects/%s/traces/%s", project, trace));
}
// -- End log correlation code --

// Create a structured log entry using key value pairs.
// For instantiating the "logger" variable, see
// https://cloud.google.com/run/docs/logging#run_manual_logging-java
logger.error(
    "This is the default display field.",
    kv("component", "arbitrary-property"),
    kv("severity", "NOTICE"),
    globalLogFields);

Personnalisez les noms de champs standards pour exclure le contenu indésirable de l'ingestion dans la charge utile des journaux. Pour obtenir la liste des noms de champs et des formats de données attendus, consultez la page Utiliser l'agent Logging.

<configuration>
  <appender name="jsonConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <!-- Ignore default logging fields -->
      <fieldNames>
        <timestamp>[ignore]</timestamp>
        <version>[ignore]</version>
        <logger>[ignore]</logger>
        <thread>[ignore]</thread>
        <level>[ignore]</level>
        <levelValue>[ignore]</levelValue>
      </fieldNames>
    </encoder>
  </appender>
  <root level="INFO">
    <appender-ref ref="jsonConsoleAppender"/>
  </root>
</configuration>

Champs JSON spéciaux dans les messages

Lorsque vous fournissez un journal structuré sous forme de dictionnaire JSON, certains champs spéciaux sont supprimés de jsonPayload et écrits dans le champ correspondant de la LogEntry générée, comme décrit dans la documentation sur les champs spéciaux.

Par exemple, si vos données JSON incluent une entrée severity, celle-ci est supprimée de jsonPayload et apparaît en tant que propriété severity de l'entrée de journal. La propriété message est utilisée comme texte d'affichage principal de l'entrée de journal, le cas échéant. Pour en savoir plus sur les propriétés spéciales, consultez la section Ressource de journalisation ci-dessous.

Corréler les journaux de conteneur avec un journal de requêtes (services uniquement)

Dans l'explorateur de journaux, les journaux corrélés par la même propriété trace sont visualisables au format "parent-enfant". Lorsque vous cliquez sur l'icône en forme de triangle située à gauche de l'entrée de journal de requête, les journaux de conteneur associés à cette requête sont imbriqués sous le journal de requête.

Les journaux de conteneur ne sont pas automatiquement corrélés avec les journaux de requête, sauf si vous utilisez une bibliothèque cliente Cloud Logging. Pour mettre en corrélation des journaux de conteneur avec des journaux de requête sans utiliser de bibliothèque cliente, vous pouvez utiliser une ligne de journal JSON structurée contenant un champ logging.googleapis.com/trace avec l'identifiant de trace extrait de l'en-tête X-Cloud-Trace-Context, comme indiqué dans l'exemple ci-dessus pour la journalisation structurée.

Contrôler l'utilisation des ressources de journal de requêtes (services uniquement)

Les journaux de requête sont créés automatiquement. Bien que vous ne puissiez pas contrôler la quantité de journaux de requête directement à partir de Cloud Run, vous pouvez utiliser la fonctionnalité d'exclusion de journaux de Cloud Logging.

Remarque concernant les agents de journalisation

Si vous avez utilisé Cloud Logging avec certains produits Google Cloud , tels que Compute Engine, vous avez peut-être utilisé des agents de journalisation Cloud Logging. Cloud Run n'utilise pas d'agents de journalisation, car il possède une compatibilité intégrée avec la collecte de journaux.

Noms de ressources de journalisation

Les noms des ressources de journalisation pour Cloud Run sont les suivants :

Ressources de journalisation

Lorsque vous cliquez sur une entrée de journal dans l'explorateur de journaux, une entrée de journal au format JSON s'ouvre. Vous pouvez ainsi accéder aux informations dont vous avez besoin.

Tous les champs d'une entrée de journal, tels que les horodatages, la gravité et httpRequest, sont standards. Ils sont décrits dans la documentation concernant les entrées de journal.

Cloud Run ajoute des métadonnées supplémentaires pour vous permettre d'identifier la source d'un journal. Cela inclut les libellés que vous définissez sur votre service Cloud Run et les libellés de ressources spécifiques à Cloud Run.

Champs d'entrées de journal pour un service

Voici une liste des champs disponibles dans l'entrée de journal pour un service Cloud Run :

Champ Valeurs et notes
LogEntry.labels.instanceId Instance qui a traité la requête.
LogEntry.labels.run.googleapis.com/base_image_versions Version de l'image de base utilisée par le service. N'apparaît que pour les services déployés à partir de la source et si les mises à jour de sécurité automatiques sont activées.
LogEntry.labels.run.googleapis.com/cloud_event_id ID CloudEvent. N'apparaît que pour les services recevant des événements d'Eventarc.
LogEntry.labels.run.googleapis.com/cloud_event_source Source CloudEvent. N'apparaît que pour les services recevant des événements d'Eventarc.
LogEntry.labels.mylabel,
LogEntry.labels.mysecondlabel
Les libellés que vous définissez sur le service.
LogEntry.logName Identifie le journal, par exemple, le journal de requête, l'erreur standard, le résultat standard, etc.
LogEntry.resource.labels.location Identifie l'emplacement Google Cloud du service.
LogEntry.resource.labels.project_id Projet sur lequel le service est déployé.
LogEntry.resource.labels.revision_name Révision qui a desservi la requête.
LogEntry.resource.labels.service_name Service qui a desservi la requête.
LogEntry.resource.type cloud_run_revision. Type de ressource Cloud Run.

Voici un exemple d'entrée de journal de requêtes pour un service Cloud Run :

{
 httpRequest: {}
 insertId:  "5c82b3d1000ece0000000000"
 labels: {
  instanceId:  "00bf4bf00000fb59c906a00000c9e29c2c4e06dce91500000000056008d2b6460f163c0057b97b2345f2725fb2423ee5f0bafd36df887fdb1122371563cf1ff453717282afe000001"
  mylabel: "mylabelvalue"
  mysecondlabel: "mysecondlabelvalue"
 }
 logName:  "projects/my-project/logs/run.googleapis.com%2Frequests"
 receiveTimestamp:  "2019-03-08T18:26:25.981686167Z"
 resource: {
  labels: {
   configuration_name:  "myservice"
   location:  "europe-west1"
   project_id:  "my-project"
   revision_name:  "myservice-00002"
   service_name:  "myservice"
  }
  type:  "cloud_run_revision"
 }
 severity:  "INFO"
 timestamp:  "2019-03-08T18:26:25.970397Z"
}

Champs d'entrées de journal pour les jobs

Voici une liste des champs disponibles dans l'entrée de journal pour un job Cloud Run :

Champ Valeurs et notes
LogEntry.labels.instanceId Instance.
LogEntry.labels.mylabel,

LogEntry.labels.mysecondlabel

Les libellés que vous définissez sur le job.
LogEntry.logName Identifie le journal, par exemple, l'erreur standard, le résultat standard, etc.
LogEntry.resource.labels.location Identifie l'emplacement du job. Google Cloud
LogEntry.resource.labels.project_id Projet sur lequel le job est déployé.
LogEntry.resource.labels.job_name Nom du job.
LogEntry.labels.execution_name Nom de l'exécution du job.
LogEntry.labels.task_index Index de la tâche.
LogEntry.labels.task_attempt Nombre de tentatives d'exécution de cette tâche.
LogEntry.resource.type cloud_run_job. Type de ressource Cloud Run.

Champs d'entrées de journal pour les pools de nœuds de calcul

Voici une liste des champs disponibles dans l'entrée de journal pour un pool de nœuds de calcul Cloud Run :

Champ Valeurs et notes
LogEntry.labels.instanceId Instance.
LogEntry.labels.mylabel,

LogEntry.labels.mysecondlabel

Les libellés que vous définissez sur le pool de nœuds de calcul.
LogEntry.logName Identifie le journal, par exemple, l'erreur standard, le résultat standard, etc.
LogEntry.resource.labels.location Emplacement Google Cloud du pool de nœuds de calcul.
LogEntry.resource.labels.project_id Projet sur lequel le pool de nœuds de calcul est déployé.
LogEntry.resource.labels.workerpool_name Nom du pool de nœuds de calcul.
LogEntry.resource.type cloud_run_workerpool. Type de ressource Cloud Run.