使用日志分析作业

本页面介绍如何为 Cloud Logging 启用和查看作业日志

您可以使用日志来获取对分析作业有用的信息。例如,日志可帮助您调试失败的作业。 为作业启用 Cloud Logging 后,Cloud Logging 会生成以下类型的日志供您查看:

  • 任务日志 (batch_task_logs):写入标准输出 (stdout) 和标准错误 (stderr) 流的所有数据的日志。如需为作业生成任务日志,请配置任务,以写入数据以用于分析和调试这些数据流。
  • 代理日志 (batch_agent_logs):来自 Batch 服务代理的活动日志。Batch 会自动为您的作业生成这些日志。

请注意,Cloud Logging 仅在作业开始运行后生成日志。如需验证作业是否已开始运行,请描述作业并确认作业的状态RUNNING 或更晚状态。如果您需要分析未生成日志的作业(例如,作业在 RUNNING 状态之前失败),请使用 gcloud CLI 或 Batch API 描述该作业,并检查 statusEvents 字段

准备工作

为作业启用日志

如需为作业生成日志,请在创建作业时启用 Cloud Logging:

  • 如果您使用 Google Cloud 控制台创建作业,则 Cloud Logging 始终处于启用状态。
  • 如果您使用 gcloud CLI 或 Batch API 创建作业,Cloud Logging 默认处于停用状态。如需启用 Cloud Logging,请在创建作业时为 logsPolicy 字段添加以下配置:

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

查看作业的日志

您可以使用 Google Cloud 控制台、gcloud CLI、Logging API、Go、Java 或 Python 在 Cloud Logging 中查看作业的日志。

控制台

如需使用 Google Cloud 控制台查看作业日志,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到作业列表页面。

    转到作业列表

  2. 作业名称列中,点击作业的名称。 作业详情页面随即打开。

  3. 点击事件标签页。

  4. 日志部分中,点击  Cloud Logging日志浏览器页面会打开。

    默认情况下,日志浏览器会显示此作业的所有任务日志。

    建议:如需过滤要显示哪些日志,请构建查询;例如,在查询编辑器字段中输入批量日志查询

gcloud

如需使用 gcloud CLI 查看日志,请使用 gcloud logging read 命令

gcloud logging read "QUERY"

其中 QUERY批量日志的查询

API

如需使用 Logging API 查看日志,请使用 entries.list 方法

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

请替换以下内容:

Go

Go

如需了解详情,请参阅 Batch Go API 参考文档

如需向 Batch 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

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

如需了解详情,请参阅 Batch Java API 参考文档

如需向 Batch 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证


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

如需了解详情,请参阅 Batch Python API 参考文档

如需向 Batch 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证

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)

编写查询以过滤批量日志

您可以通过编写包含以下一个或多个过滤条件参数以及零个或零个以上布尔值运算符(ANDORNOT的查询来过滤 Batch 日志。

  • 如需过滤来自特定作业的日志,请指定该作业的唯一 ID (UID):

    labels.job_uid=JOB_UID
    

    其中 JOB_UID 是作业的 UID。如需获取作业的 UID,请描述相应作业

  • 如需过滤特定类型的批处理日志,请指定日志类型:

    logName=projects/PROJECT_ID/logs/BATCH_LOG_TYPE
    

    请替换以下内容:

    • PROJECT_ID:您要查看其日志的项目的项目 ID
    • BATCH_LOG_TYPE:您要查看的批量日志类型,其中 batch_task_logs 表示任务日志,batch_agent_logs 表示代理日志。

后续步骤