Job mithilfe von Logs analysieren

In diesem Dokument wird beschrieben, wie Sie Logs aus Cloud Logging für einen Batch-Job aktivieren, generieren und aufrufen.

Mithilfe von Logs können Sie Informationen abrufen, die für die Analyse Ihrer Jobs nützlich sind. Logs können Ihnen beispielsweise dabei helfen, fehlgeschlagene Jobs zu debuggen.

Logs werden erst generiert, nachdem ein Job ausgeführt wurde und wenn Logging für den Job aktiviert wurde. Wenn Sie einen Job ohne Logs analysieren müssen, rufen Sie stattdessen Statusereignisse auf.

Hinweise

Logging für einen Job aktivieren

Damit Logs für einen Job generiert werden können, müssen Sie beim Erstellen des Jobs Logs von Cloud Logging aktivieren:

  • Wenn Sie einen Job über die Google Cloud Console erstellen, sind Logs von Cloud Logging immer aktiviert.
  • Wenn Sie einen Job über die gcloud CLI oder Batch API erstellen, sind Logs von Cloud Logging standardmäßig deaktiviert. Wenn Sie Logs aus Cloud Logging aktivieren möchten, fügen Sie beim Erstellen des Jobs die folgende Konfiguration für das Feld logsPolicy hinzu:

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

Logs für einen Job schreiben und generieren

Wenn Logs von Cloud Logging für einen Job aktiviert sind, generiert Cloud Logging automatisch alle Logs, die für den Job geschrieben werden. Batchjobs können insbesondere die folgenden Logtypen haben:

Logs für einen Job ansehen

Sie können die Logs eines Jobs mit der Google Cloud Console, der gcloud CLI, der Logging API, Go, Java, Python oder C++ ansehen.

Console

So rufen Sie die Logs eines Jobs mit der Google Cloud Console auf:

  1. Rufen Sie in der Google Cloud Console die Seite Jobliste auf.

    Zur Jobliste

  2. Klicken Sie in der Spalte Jobname auf den Namen eines Jobs. Die Seite Jobdetails wird geöffnet.

  3. Klicken Sie auf den Tab Logs. Batch zeigt alle Logs an, die mit dem Job verknüpft sind.

  4. Optional: Führen Sie einen der folgenden Schritte aus, um die Protokolle zu filtern:

gcloud

Verwenden Sie den Befehl gcloud logging read, um Logs über die gcloud CLI aufzurufen:

gcloud logging read "QUERY"

Dabei ist QUERY eine Abfrage für Batch-Logs, die Batchfilterparameter enthalten.

API

Verwenden Sie zum Aufrufen von Logs mit der Logging API die Methode entries.list:

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

Ersetzen Sie Folgendes:

Einfach loslegen (Go)

Go

Weitere Informationen findest du in der Referenzdokumentation zur Batch Go API.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Batch zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

import (
	"context"
	"fmt"
	"io"

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

// 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

Weitere Informationen findest du in der Referenzdokumentation zur Batch Java API.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Batch zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Weitere Informationen findest du in der Referenzdokumentation zur Batch Python API.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Batch zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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++

Weitere Informationen findest du in der Referenzdokumentation zur Batch C++ API.

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Batch zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

#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";
    }
  }

Batch-Logs filtern

Zum Filtern von Batch-Logs schreiben Sie eine Abfrage, die einen oder mehrere der folgenden Filterparameter und null oder mehr boolesche Operatoren (AND, OR und NOT) enthält.

  • Geben Sie die eindeutige ID (UID) des Jobs an, um nach Logs eines bestimmten Jobs zu filtern:

    labels.job_uid=JOB_UID
    

    Dabei ist JOB_UID die UID des Jobs. Wenn Sie die UID eines Jobs abrufen möchten, rufen Sie die Details des Jobs auf.

  • Geben Sie den Logtyp an, um nach einem bestimmten Typ von Batch-Logs zu filtern:

    logName=projects/PROJECT_ID/logs/BATCH_LOG_TYPE
    

    Ersetzen Sie Folgendes:

    • PROJECT_ID: die Projekt-ID des Projekts, für das Sie Logs aufrufen möchten.
    • BATCH_LOG_TYPE: der Typ der Batchlogs, die Sie ansehen möchten, entweder batch_task_logs für Aufgabenlogs oder batch_agent_logs für Agent-Logs.
  • Wenn Sie nach Logs mit benutzerdefinierten Statusereignissen filtern möchten, müssen Sie das Feld jsonPayload.batch/custom/event im Log definieren:

    jsonPayload.batch"/"custom"/"event!=NULL_VALUE
    
  • Geben Sie den folgenden Vergleich an, um nach Logs mit einem oder mehreren bestimmten Schweregraden zu filtern:

    severityCOMPARISON_OPERATORSEVERITY_ENUM
    

    Ersetzen Sie Folgendes:

Weitere Filteroptionen finden Sie in der Dokumentation zur Cloud Logging-Abfragesprache.

Nächste Schritte