Cloud Run でのログの記録と表示

このページでは、Cloud Run で使用可能なログと、ログの表示方法、作成方法について説明します。

Cloud Run には 2 種類のログがあります。これらのログは、Cloud Logging に自動的に送信されます。

  • リクエストログ(サービスのみ): Cloud Run サービスに送信されたリクエストのログ。これらのログは自動的に作成されます。
  • コンテナログ(サービスとジョブ): インスタンス(通常は独自のコード)から出力されたログです。コンテナログを作成するで説明されているように、サポートされているロケーションに書き込まれます。

ログを表示する

サービスまたはジョブのログは、いくつかの方法で表示できます。

コンソールでログを表示する場合、いずれの方法でも Cloud Logging に保存されている同じログが使用されますが、Cloud Logging のログ エクスプローラを使用した場合は、表示される詳細情報や使用可能なフィルタリング機能が多くなります。

Cloud Run でログを表示する

サービスとジョブのログは、対応するサービスとジョブのページで表示できます。

サービスのログを表示する

Cloud Run ページでサービスのログを表示するには:

  1. Cloud Run に移動します

  2. 表示されたリストで、必要なサービスをクリックします。

  3. このサービスのすべてのリビジョンのリクエストログとコンテナログを取得するには、[ログ] タブをクリックします。ログの重大度でフィルタリングできます。

ジョブのログを表示する

Cloud Run ページでジョブのログを表示するには:

  1. Cloud Run に移動します

  2. [ジョブ] タブをクリックします。

  3. ジョブリストでジョブを見つけてクリックします。

  4. [ログ] タブをクリックして、このジョブのすべての実行に関するコンテナログを取得します。ログの重大度でフィルタリングできます。

  5. また、特定のジョブ実行について事前にフィルタリングされたログを表示するには、ジョブ実行をクリックしてから、[ログ] タブをクリックします。

Google Cloud CLI を使用してサービスログを表示する

Google Cloud CLI を使用すると、コマンドラインでテーリングログを表示したり、Cloud Run サービスの既存のログを読み取ることができます。デフォルトでは、ログはコンソール用に最適化された 1 行形式になっています。

ログをテーリングする場合は、Google Cloud CLI に log-streaming コンポーネントをインストールする必要があります。このコンポーネントがインストールされていないと、インストールするように求められます。

コマンドラインでテーリングログを表示する

Cloud Run サービスの場合は、コマンドラインで直接、Cloud Run サービスからのログをリアルタイムでテーリングできます。

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

次のように置き換えます。

  • SERVICE は Cloud Run サービスの名前に置き換えます。
  • PROJECT-ID は、Google Cloud プロジェクト ID に置き換えます。プロジェクト ID を表示するには、gcloud config get-value project コマンドを実行します。

コマンドラインでログを読み取る

Cloud Run サービスの場合は、次のいずれかの方法で既存のログを読み取ることができます。

  • コンソール用に最適化された形式:
    gcloud run services logs read SERVICE --limit=10 --project PROJECT-ID
  • Cloud Logging から直接:
    gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=SERVICE" --project PROJECT-ID --limit 10

次のように置き換えます。

  • SERVICE は Cloud Run サービスの名前に置き換えます。
  • PROJECT-ID は、Google Cloud プロジェクト ID に置き換えます。プロジェクト ID を表示するには、gcloud config get-value project コマンドを実行します。

Cloud Logging でログを確認する

Cloud Logging のログ エクスプローラで Cloud Run のログを表示するには:

  1. Google Cloud コンソールの [ログ エクスプローラ] ページに移動します。

    [ログ エクスプローラ] ページに移動

  2. ページの上部で既存の Google Cloud プロジェクトを選択するか、新しいプロジェクトを作成します。

  3. プルダウン メニューを使用して、リソースの Cloud Run リビジョン(サービスの場合)または Cloud Run ジョブ(ジョブの場合)を選択します。

詳細については、ログ エクスプローラの使用をご覧ください。

Cloud Code でサービスログを表示する

Cloud Code でログを表示するには、IntelliJVisual Studio Code のガイドをご覧ください。

プログラムでログを読み取る

プログラムでログを読み取るには、次のいずれかの方法を使用します。

コンテナログを書き込む

サービスまたはジョブからログを作成する場合、ログの出力先が次のいずれかであれば、Cloud Logging によってログが自動的に取得されます。

ほとんどのデベロッパーは、ログの出力先として標準出力と標準エラーを想定しています。

サポートされているロケーションに書き込まれたコンテナログは、Cloud Run サービス、リビジョン、ロケーション、または Cloud Run ジョブに自動的に関連付けられます。これらのログに含まれる例外が Error Reporting でキャプチャされ、報告されます。

統合ロギングは、信頼性とリソース使用量のバランスをとるもので、ほとんどのアプリケーションで機能します。アプリケーションでより大きなボリュームやより高い信頼性が必要な場合は、アプリケーション内のライブラリまたは個別のサイドカー コンテナとして Cloud Logging API を直接使用することをおすすめします。

ログでの単純なテキストと構造化 JSON の使用を比較する

ログに出力するときに、単純なテキスト文字列を送信することも、シリアル化された JSON(構造化データ)の 1 行を送信することもできます。これは Cloud Logging によって取得され、解析された後、jsonPayload に配置されます。単純なテキスト メッセージは textPayload に配置されます。

構造化ログを書き込む

次のスニペットは、構造化ログエントリを書き込む方法を示しています。また、ログメッセージを対応するリクエストログと関連付ける方法も示しています。

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

各ログエントリの構造は、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)
}

Entry 構造体がログに記録されると、String メソッドが呼び出され、Cloud Logging で想定されている JSON 形式にマーシャリングされます。


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

logback.xml の構成で Logstash JSON Encoder を有効にして、LogbackSLF4J での JSON ロギングを有効にします。

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

標準フィールド名をカスタマイズして、ログペイロードでの取り込みから不要なコンテンツを除外します。フィールド名と想定されるデータ形式の一覧については、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>

メッセージ内の特別な JSON フィールド

特殊フィールドのドキュメントで説明されているように、構造化ログを JSON ディクショナリとして提供すると、いくつかの特殊フィールドが jsonPayload から削除され、生成された LogEntry の対応フィールドに書き込まれます。

たとえば、JSON に severity プロパティが含まれている場合、jsonPayload から削除され、代わりにログエントリの severity として表示されます。message プロパティが存在する場合は、ログエントリのメイン表示テキストとして使用されます。特別なプロパティの詳細については、以下のロギング リソース セクションをご覧ください。

コンテナログとリクエストログを関連付ける(サービスのみ)

ログ エクスプローラでは、同じ trace で関連付けられたログを「親子」形式で表示できます。リクエスト ログエントリの左側にある三角形のアイコンをクリックすると、該当するリクエストに関連付けられたコンテナログが、リクエストログの下にネストされた状態で表示されます。

Cloud Logging クライアント ライブラリを使用しない限り、コンテナログは自動的にリクエストログに関連付けられません。クライアント ライブラリを使用せずにコンテナログをリクエストログに関連付けるには、上記の構造化ロギングのサンプルで示した X-Cloud-Trace-Context ヘッダーから抽出された、トレース ID を持つ logging.googleapis.com/trace フィールドを含む構造化 JSON ログの行を使用します。

リクエストログのリソース使用量を制御する(サービスのみ)

リクエストログは自動的に作成されます。Cloud Run から直接リクエストログの量を制御することはできませんが、Cloud Logging のログの除外機能を利用できます。

ロギング エージェントに関する注意事項

Compute Engine などの特定の Google Cloud プロダクトで Cloud Logging を使用している場合は、Cloud Logging のロギング エージェントを使用した可能性があります。ログ収集のサポートが組み込まれているため、Cloud Run はロギング エージェントを使用しません。

ロギング リソース名

Cloud Run のロギング リソース名は次のとおりです。

ロギング リソース

ログ エクスプローラでログエントリをクリックすると、JSON 形式のログエントリが表示され、必要な詳細を確認できます。

タイムスタンプ、重大度、httpRequest など、ログエントリ内のすべてのフィールドが標準で表示されます。詳しくは、ログエントリのドキュメントをご覧ください。

Cloud Run によってメタデータが追加されるため、ログのソースを識別できます。これには、Cloud Run サービスに設定したラベルと Cloud Run に固有のリソースラベルが含まれます。

サービスのログエントリ フィールド

Cloud Run サービスのログエントリで確認できるフィールドは次のとおりです。

フィールド 値とメモ
LogEntry.labels.instanceId リクエストを処理したインスタンス。
LogEntry.labels.mylabel
LogEntry.labels.mysecondlabel
サービスで設定したラベル
LogEntry.logName リクエストログ、標準エラー、標準出力など、ログの種類を表します。
LogEntry.resource.labels.location サービスの Google Cloud のロケーションを指定します。
LogEntry.resource.labels.project_id サービスがデプロイされているプロジェクト。
LogEntry.resource.labels.revision_name リクエストを処理したリビジョン。
LogEntry.resource.labels.service_name リクエストを処理したサービス。
LogEntry.resource.type cloud_run_revision。Cloud Run リソースタイプ。

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:  "us-central1"
   project_id:  "my-project"
   revision_name:  "myservice-00002"
   service_name:  "myservice"
  }
  type:  "cloud_run_revision"
 }
 severity:  "INFO"
 timestamp:  "2019-03-08T18:26:25.970397Z"
}

ジョブのログエントリ フィールド

Cloud Run ジョブのログエントリで確認できるフィールドは次のとおりです。

フィールド 値とメモ
LogEntry.labels.instanceId インスタンス。
LogEntry.labels.mylabel、

LogEntry.labels.mysecondlabel

ジョブで設定したラベル
LogEntry.logName リクエストログ、標準エラー、標準出力など、ログの種類を表します。
LogEntry.resource.labels.location サービスの Google Cloud のロケーションを指定します。
LogEntry.resource.labels.project_id サービスがデプロイされているプロジェクト。
LogEntry.resource.labels.job_name ジョブの名前。
LogEntry.labels.execution_name ジョブ実行の名前。
LogEntry.labels.task_index タスクのインデックス。
LogEntry.labels.task_attempt このタスクの試行回数。
LogEntry.resource.type cloud_run_job。Cloud Run リソースタイプ。