使用記錄檔分析工作

本文說明如何為 Batch 工作啟用、產生及查看 Cloud Logging記錄

您可以透過記錄取得有助於分析工作的資訊。舉例來說,記錄檔可協助您偵錯失敗的工作。

請注意,只有在工作開始執行,且工作已啟用記錄功能時,系統才會產生記錄檔。如要分析沒有記錄檔的工作,請改為查看狀態事件

事前準備

  1. 如果您是第一次使用 Batch,請先參閱「開始使用 Batch」,並完成專案和使用者的必要條件,啟用 Batch。
  2. 如要取得使用記錄檔分析作業所需的權限,請要求管理員授予下列 IAM 角色:

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

    您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

啟用工作的記錄功能

如要允許系統為工作產生記錄,請在建立工作時,從 Cloud Logging 啟用記錄功能:

  • 如果您使用 Google Cloud 控制台建立工作,系統一律會啟用 Cloud Logging 的記錄。
  • 如果您使用 gcloud CLI 或 Batch API 建立工作,系統預設會停用 Cloud Logging 的記錄。如要啟用 Cloud Logging 的記錄,請在建立工作時,為 logsPolicy 欄位加入下列設定:

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

為工作撰寫及產生記錄

為工作啟用 Cloud Logging 記錄後,Cloud Logging 會自動產生為工作寫入的任何記錄。具體來說,Batch 工作可有下列記錄類型:

  • 代理程式記錄 (batch_agent_logs):Batch 服務代理程式活動的記錄。

    如果工作已啟用記錄功能,Batch 會自動為每個工作寫入代理程式記錄。

  • 工作記錄 (batch_task_logs):您已將工作可執行檔設定為寫入標準輸出 (stdout) 串流或標準錯誤 (stderr) 串流的任何資料記錄。

    您可以選擇為已啟用記錄功能的每個工作撰寫工作記錄

查看工作的記錄

您可以使用 Google Cloud 控制台、gcloud CLI、Logging API、Go、Java、Python 或 C++ 查看工作記錄。

控制台

如要使用 Google Cloud 控制台查看工作的記錄,請執行下列操作:

  1. 前往 Google Cloud 控制台的「Job list」(工作清單) 頁面。

    前往工作清單

  2. 在「Job name」(工作名稱) 欄中,按一下工作名稱。 「工作詳細資料」頁面隨即開啟。

  3. 按一下「記錄」分頁標籤。Batch 會顯示與工作相關聯的所有記錄。

  4. 選用:如要篩選記錄,請執行下列任一操作:

    • 在「篩選條件」 欄位中輸入篩選條件

    • 在「嚴重程度」清單中,選取嚴重程度

    • 按一下「在 Logs Explorer 查看」,即可使用「批次篩選器參數」在 Logs Explorer 中建構查詢

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

詳情請參閱 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)

C++

C++

詳情請參閱 Batch C++ API 參考文件

如要向 Batch 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

#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 記錄

您可以編寫查詢,加入一或多個下列篩選參數,以及零或多個布林運算子 (ANDORNOT),篩選批次記錄。

  • 如要篩選特定工作的記錄,請指定該工作的專屬 ID (UID):

    labels.job_uid=JOB_UID
    

    其中 JOB_UID 是工作 UID。如要取得工作 UID,請查看工作詳細資料

  • 如要篩選特定類型的 Batch 記錄,請指定記錄類型:

    logName=projects/PROJECT_ID/logs/BATCH_LOG_TYPE
    

    更改下列內容:

    • PROJECT_ID:您要查看記錄的專案的專案 ID
    • BATCH_LOG_TYPE:要查看的批次記錄類型,可以是工作記錄的 batch_task_logs,也可以是代理程式記錄的 batch_agent_logs
  • 如要篩選含有自訂狀態事件的記錄,請指定記錄必須定義 jsonPayload.batch/custom/event 欄位:

    jsonPayload.batch"/"custom"/"event!=NULL_VALUE
    
  • 如要篩選一或多個特定嚴重程度的記錄,請指定下列比較

    severityCOMPARISON_OPERATORSEVERITY_ENUM
    

    更改下列內容:

如需更多篩選選項,請參閱 Cloud Logging 查詢語言說明文件。

後續步驟