Analyser une tâche à l'aide des journaux

Ce document explique comment activer, générer et afficher les journaux de Cloud Logging pour une tâche de traitement par lot.

Vous pouvez utiliser les journaux pour obtenir des informations utiles pour analyser vos tâches. Par exemple, les journaux peuvent vous aider à déboguer des tâches ayant échoué.

Notez que les journaux ne sont générés qu'après le démarrage d'une tâche et uniquement si la journalisation a été activée pour la tâche. Si vous devez analyser une tâche sans journaux, affichez plutôt les événements d'état.

Avant de commencer

  1. Si vous n'avez jamais utilisé Batch, consultez Premiers pas avec Batch et activez Batch en remplissant les conditions préalables pour les projets et les utilisateurs.
  2. Pour obtenir les autorisations nécessaires pour analyser un job à l'aide des journaux, demandez à votre administrateur de vous accorder les rôles IAM suivants:

    Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

    Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

Activer la journalisation pour une tâche

Pour permettre la génération de journaux pour une tâche, activez les journaux à partir de Cloud Logging lorsque vous créez la tâche:

  • Si vous créez une tâche à l'aide de la console Google Cloud, les journaux de Cloud Logging sont toujours activés.
  • Si vous créez une tâche à l'aide de la CLI gcloud ou de l'API Batch, les journaux de Cloud Logging sont désactivés par défaut. Pour activer les journaux de Cloud Logging, incluez la configuration suivante pour le champ logsPolicy lors de la création de la tâche:

    {
        ...
        "logsPolicy": {
            "destination": "CLOUD_LOGGING"
        }
        ...
    }
    

Écrire et générer des journaux pour une tâche

Lorsque les journaux de Cloud Logging sont activés pour une tâche, Cloud Logging génère automatiquement tous les journaux écrits pour la tâche. Plus précisément, les tâches par lot peuvent avoir les types de journaux suivants:

  • Journaux de l'agent (batch_agent_logs): journaux des activités de l'agent de service Batch.

    Le traitement par lot écrit automatiquement les journaux de l'agent pour chaque tâche ayant activé la journalisation.

  • Journaux de tâche (batch_task_logs): journaux de toutes les données que vous avez configurées pour que les exécutables d'une tâche soient écrits dans le flux de sortie standard (stdout) ou le flux d'erreur standard (stderr).

    Vous pouvez éventuellement écrire des journaux de tâches pour chaque tâche pour laquelle la journalisation est activée.

Afficher les journaux d'un job

Vous pouvez afficher les journaux d'un job à l'aide de la console Google Cloud, de la gcloud CLI, de l'API Logging, de Go, de Java, de Python ou de C++.

Console

Pour afficher les journaux d'une tâche à l'aide de la console Google Cloud, procédez comme suit:

  1. Dans la console Google Cloud, accédez à la page Liste des jobs.

    Accéder à la liste des tâches

  2. Dans la colonne Nom de la tâche, cliquez sur le nom d'une tâche. La page Job details (Informations sur la tâche) s'ouvre.

  3. Cliquez sur l'onglet Journaux. Le traitement par lot affiche tous les journaux associés à la tâche.

  4. Facultatif: Pour filtrer les journaux, effectuez l'une des opérations suivantes:

gcloud

Pour afficher les journaux à l'aide de gcloud CLI, exécutez la commande gcloud logging read:

gcloud logging read "QUERY"

QUERY est une requête pour les journaux de lot contenant des paramètres de filtre de lot.

API

Pour afficher les journaux à l'aide de l'API Logging, utilisez la méthode entries.list:

POST https://logging.googleapis.com/v2/entries:list
{
    "resourceNames": [
        "projects/PROJECT_ID"
    ],
    "filter": "QUERY"
    "orderBy": "timestamp desc"
}

Remplacez les éléments suivants :

Go

Go

Pour en savoir plus, consultez la documentation de référence de l'API Go par lot.

Pour vous authentifier auprès de Batch, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import (
	"context"
	"fmt"
	"io"

	batch "cloud.google.com/go/batch/apiv1"
	"cloud.google.com/go/batch/apiv1/batchpb"
	"cloud.google.com/go/logging"
	"cloud.google.com/go/logging/logadmin"
	"google.golang.org/api/iterator"
)

// Retrieve the logs written by the given job to Cloud Logging
func printJobLogs(w io.Writer, projectID string, job *batchpb.Job) error {
	// projectID := "your_project_id"

	ctx := context.Background()
	batchClient, err := batch.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %w", err)
	}
	defer batchClient.Close()

	adminClient, err := logadmin.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("Failed to create logadmin client: %w", err)
	}
	defer adminClient.Close()

	const name = "batch_task_logs"

	iter := adminClient.Entries(ctx,
		// Only get entries from the "batch_task_logs" log for the job with the given UID
		logadmin.Filter(fmt.Sprintf(`logName = "projects/%s/logs/%s" AND labels.job_uid=%s`, projectID, name, job.Uid)),
	)

	var entries []*logging.Entry

	for {
		logEntry, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("unable to fetch log entry: %w", err)
		}
		entries = append(entries, logEntry)
		fmt.Fprintf(w, "%s\n", logEntry.Payload)
	}

	fmt.Fprintf(w, "Successfully fetched %d log entries\n", len(entries))

	return nil
}

Java

Java

Pour en savoir plus, consultez la documentation de référence de l'API Java par lot.

Pour vous authentifier auprès de Batch, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import com.google.cloud.batch.v1.Job;
import com.google.cloud.logging.v2.LoggingClient;
import com.google.logging.v2.ListLogEntriesRequest;
import com.google.logging.v2.LogEntry;
import java.io.IOException;

public class ReadJobLogs {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project hosting the job.
    String projectId = "YOUR_PROJECT_ID";

    // The job which logs you want to print.
    Job job = Job.newBuilder().build();

    readJobLogs(projectId, job);
  }

  // Prints the log messages created by given job.
  public static void readJobLogs(String projectId, Job job) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `loggingClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (LoggingClient loggingClient = LoggingClient.create()) {

      ListLogEntriesRequest request = ListLogEntriesRequest.newBuilder()
          .addResourceNames(String.format("projects/%s", projectId))
          .setFilter(String.format("labels.job_uid=%s", job.getUid()))
          .build();

      for (LogEntry logEntry : loggingClient.listLogEntries(request).iterateAll()) {
        System.out.println(logEntry.getTextPayload());
      }
    }
  }
}

Python

Python

Pour en savoir plus, consultez la documentation de référence de l'API Python par lot.

Pour vous authentifier auprès de Batch, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

from __future__ import annotations

from typing import NoReturn

from google.cloud import batch_v1
from google.cloud import logging


def print_job_logs(project_id: str, job: batch_v1.Job) -> NoReturn:
    """
    Prints the log messages created by given job.

    Args:
        project_id: name of the project hosting the job.
        job: the job which logs you want to print.
    """
    # Initialize client that will be used to send requests across threads. This
    # client only needs to be created once, and can be reused for multiple requests.
    log_client = logging.Client(project=project_id)
    logger = log_client.logger("batch_task_logs")

    for log_entry in logger.list_entries(filter_=f"labels.job_uid={job.uid}"):
        print(log_entry.payload)

C++

C++

Pour en savoir plus, consultez la documentation de référence de l'API C++ par lot.

Pour vous authentifier auprès de Batch, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

#include "google/cloud/batch/v1/batch_client.h"
#include "google/cloud/logging/v2/logging_service_v2_client.h"
#include "google/cloud/location.h"
#include "google/cloud/project.h"

  [](std::string const& project_id, std::string const& location_id,
     std::string const& job_id) {
    auto const project = google::cloud::Project(project_id);
    auto const location = google::cloud::Location(project, location_id);
    auto const name = location.FullName() + "/jobs/" + job_id;
    auto batch = google::cloud::batch_v1::BatchServiceClient(
        google::cloud::batch_v1::MakeBatchServiceConnection());
    auto job = batch.GetJob(name);
    if (!job) throw std::move(job).status();

    auto logging = google::cloud::logging_v2::LoggingServiceV2Client(
        google::cloud::logging_v2::MakeLoggingServiceV2Connection());
    auto const log_name = project.FullName() + "/logs/batch_task_logs";
    google::logging::v2::ListLogEntriesRequest request;
    request.mutable_resource_names()->Add(project.FullName());
    request.set_filter("logName=\"" + log_name +
                       "\" labels.job_uid=" + job->uid());
    for (auto l : logging.ListLogEntries(request)) {
      if (!l) throw std::move(l).status();
      std::cout << l->text_payload() << "\n";
    }
  }

Filtrer les journaux de lot

Vous pouvez filtrer les journaux de lot en écrivant une requête qui inclut un ou plusieurs des paramètres de filtre suivants et zéro ou plusieurs opérateurs booléens (AND, OR et NOT).

  • Pour filtrer les journaux d'une tâche spécifique, spécifiez son ID unique (UID):

    labels.job_uid=JOB_UID
    

    JOB_UID est l'UID de la tâche. Pour obtenir l'UID d'une tâche, affichez les détails de la tâche.

  • Pour filtrer les journaux de lot d'un type spécifique, spécifiez le type de journal:

    logName=projects/PROJECT_ID/logs/BATCH_LOG_TYPE
    

    Remplacez les éléments suivants :

    • PROJECT_ID: ID du projet pour lequel vous souhaitez afficher les journaux.
    • BATCH_LOG_TYPE: type de journaux de traitement par lot que vous souhaitez afficher, batch_task_logs pour les journaux de tâche ou batch_agent_logs pour les journaux de l'agent.
  • Pour filtrer les journaux avec des événements d'état personnalisés, spécifiez que le journal doit définir le champ jsonPayload.batch/custom/event:

    jsonPayload.batch"/"custom"/"event!=NULL_VALUE
    
  • Pour filtrer les journaux d'un ou de plusieurs niveaux de gravité spécifiques, spécifiez la comparaison suivante:

    severityCOMPARISON_OPERATORSEVERITY_ENUM
    

    Remplacez les éléments suivants :

Pour découvrir d'autres options de filtrage, consultez la documentation sur le langage de requête Cloud Logging.

Étape suivante