🚧

Cloud Runから構造化ログを出力する方法

2021/01/09に公開

Cloud RunにホストしているサービスからStackdriver Loggingへ構造化ログを出力する方法を紹介します。TypeScriptでの例になります。

構造化ログというのは以下の画像のように、jsonPayload に構造化された情報を持つものです。また、ログ出力時にログレベル(Severity)を設定できます。Stackdriver Loggingに流れてくるログはこちらから見ることができます。

ログを出力する方法

Stackdriverへ直接ログを流し込むライブラリが存在します。これを使うと毎回Stackdriver LoggingのAPIを叩いてログをPOSTする形になり、非同期通信を待つ必要があるので使い勝手があまりよくありません。

Cloud Run(やCloud functions)では、標準出力にログを出力するとStackdriver Loggingへ流れるようになっています。TypeScriptでは console.log() を呼べば標準出力にログを出してくれます。

私が試しに作ったLoggerは下記です。

type Severity = 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR' | 'ALERT'

type Payload = { [key: string]: any }

export class Logger {
  static output(severity: Severity, payload: Payload, error?: Error) {
    const entry: any = {
      severity,
      ...payload,
    }
    if (error) {
      entry.errorMessage = error.message
      entry.errorName = error.name
    }
    console.log(JSON.stringify(entry))
  }
}

ポイントは以下です。

  • console.log() に文字列化したJSONを渡す
  • JSONにはseverityフィールドを設定する
    • 設定できる文字列の一覧はこちら
  • 特殊なフィールドがあり、それらはpayloadからは削除されるので注意すること

例えばseverityをERRORにして出力するとこのように表示されます。左上のマークが !! になっています(ERRORの場合のマーク)。ちなみに、payloadにmessageフィールドが指定されていると、Stackdriver Loggingのコンソールでのログエントリのテキストとして使用されます(画像の一番上のメッセージとjsonPayload.messageが同じ)。

エラーログが流れてきたらメールで通知する

Stackdriver Loggingへ正しくログレベルを設定したログを流していると、特定のレベル以上のログが流れてきた場合にメールを送ることができます。これはStackdriver Error Reportingから設定できます。

Stackdriver Error Reportingのページへ行き、右上のほうに「通知をオンにする」というボタンがあるのでそれを押すだけです。非常に簡単ですね。本番環境に設定することはもちろん、開発環境でも設定しておくと誰かが試しに触っているときに発生したエラーにも気づくことができるのでおすすめです。

Discussion