このドキュメントでは、Cloud Logging から BigQuery テーブルにルーティングされたログエントリを見つける方法について説明します。Logging シンクは、ロギングデータを小さなバッチで BigQuery にストリーミングし、読み込みジョブを実行せずにデータをクエリできるようにします。クエリを作成し、BigQuery テーブルの形式を理解できるように、このドキュメントでは、ルーティングされたログの BigQuery スキーマについても説明します。
Cloud Logging は、以前のストリーミング API を使用してログエントリを BigQuery にストリーミングします。通常、ログエントリは 1 分以内に BigQuery に表示されます。ただし、新しいテーブルを作成した場合、最初のログエントリが使用可能になるまでに数分かかることがあります。
始める前に
シンクのコンセプトについては、ルーティングと保存のモデルの概要: シンクをご覧ください。
ログをルーティングする方法については、サポートされている宛先にログをルーティングするをご覧ください。
ルーティングされるログエントリ フィールドの命名法については、ルーティングされるログの BigQuery スキーマをご覧ください。
ログを表示
BigQuery にルーティングされたログを表示する手順は次のとおりです。
- 
Google Cloud コンソールで、[BigQuery] ページに移動します。 このページは、検索バーを使用して見つけることもできます。 
- [エクスプローラ] パネルでプロジェクトを開いて、データセットを選択します。 - [詳細] タブにログエントリが表示されます。また、テーブルに対するクエリを行ってデータを返すこともできます。 
サンプルクエリ
BigQuery クエリ シンタックスの詳細については、クエリ リファレンスをご覧ください。複数のテーブルへのクエリが可能なテーブル ワイルドカード関数と、繰り返されるフィールドからデータを表示する flatten 演算子は、特に便利です。
Compute Engine クエリのサンプル
次の BigQuery クエリは、複数の日付と複数のログタイプからログエントリを取得します。
- このクエリは過去 3 日間の - syslogと- apache-accessのログを検索します。このクエリは 2020 年 2 月 23 日に作成されたので、2 月 21 日と 2 月 22 日に受け取ったすべてのログエントリと、2 月 23 日のクエリ発行時刻までに受け取ったログエントリを対象とします。
- このクエリは、1 つの Compute Engine インスタンス - 1554300700000000000の結果を取得します。
SELECT timestamp AS Time, logName as Log, textPayload AS Message FROM (TABLE_DATE_RANGE(my_bq_dataset.syslog_, DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())), (TABLE_DATE_RANGE(my_bq_dataset.apache_access_, DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())) WHERE resource.type == 'gce_instance' AND resource.labels.instance_id == '1554300700000000000' ORDER BY time;
出力行の例は次のようになります。
Row | Time                    | Log                                         | Message
--- | ----------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------
 5  | 2020-02-21 03:40:14 UTC | projects/project-id/logs/syslog             | Feb 21 03:40:14 my-gce-instance collectd[24281]: uc_update: Value too old: name = 15543007601548826368/df-tmpfs/df_complex-used; value time = 1424490014.269; last cache update = 1424490014.269;
 6  | 2020-02-21 04:17:01 UTC | projects/project-id/logs/syslog             | Feb 21 04:17:01 my-gce-instance /USR/SBIN/CRON[8082]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
 7  | 2020-02-21 04:49:58 UTC | projects/project-id/logs/apache-access      | 128.61.240.66 - - [21/Feb/2020:04:49:58 +0000] "GET / HTTP/1.0" 200 536 "-" "masscan/1.0 (https://github.com/robertdavidgraham/masscan)"
 8  | 2020-02-21 05:17:01 UTC | projects/project-id/logs/syslog             | Feb 21 05:17:01 my-gce-instance /USR/SBIN/CRON[9104]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
 9  | 2020-02-21 05:30:50 UTC | projects/project-id/log/syslogapache-access | 92.254.50.61 - - [21/Feb/2020:05:30:50 +0000] "GET /tmUnblock.cgi HTTP/1.1" 400 541 "-" "-"
App Engine クエリのサンプル
次の BigQuery クエリは、過去 1 か月の失敗した App Engine リクエストを取得します。
SELECT timestamp AS Time, protoPayload.host AS Host, protoPayload.status AS Status, protoPayload.resource AS Path FROM (TABLE_DATE_RANGE(my_bq_dataset.appengine_googleapis_com_request_log_, DATE_ADD(CURRENT_TIMESTAMP(), -1, 'MONTH'), CURRENT_TIMESTAMP())) WHERE protoPayload.status != 200 ORDER BY time
結果の例は次のようになります。
Row | Time                    | Host                                  | Status | Path
--- | ----------------------- | ------------------------------------- | ------ | ------
 6  | 2020-02-12 19:35:02 UTC | default.my-gcp-project-id.appspot.com |    404 | /foo?thud=3
 7  | 2020-02-12 19:35:21 UTC | default.my-gcp-project-id.appspot.com |    404 | /foo
 8  | 2020-02-16 20:17:19 UTC | my-gcp-project-id.appspot.com         |    404 | /favicon.ico
 9  | 2020-02-16 20:17:34 UTC | my-gcp-project-id.appspot.com         |    404 | /foo?thud=%22what???%22
ルーティングされたログの BigQuery スキーマ
ルーティングされたログに対する BigQuery テーブル スキーマは、LogEntry タイプの構造とログのペイロードの内容に基づいています。また、Cloud Logging では、監査ログと特定の構造化ペイロード フィールドの BigQuery スキーマ フィールド名を短縮するルールも適用されます。テーブル スキーマを表示するには、BigQuery インターフェース でルーティングされたログエントリのテーブルを選択します。
フィールド命名規則
BigQuery にログを送信するときに、ログエントリ フィールドに適用される命名規則がいくつかあります。
- ログエントリ フィールドの名前は 128 文字以下にする必要があります。 
- ログエントリのフィールド名は、英数字のみにする必要があります。サポートされていない文字はフィールド名から削除され、アンダースコア文字に置き換えられます。たとえば、 - jsonPayload.foo%%は- jsonPayload.foo__に変換されます。- ログエントリのフィールド名は、変換後も英数字で始める必要があります。先頭のアンダースコアはすべて削除されます。 
- LogEntry型の一部であるログエントリ フィールドの場合、対応する BigQuery フィールド名はログエントリ フィールドとまったく同じです。
- ユーザー指定のログエントリ フィールドの場合、対応する BigQuery フィールド名は小文字に正規化されますが、それ以外は名前は保持されます。 
- 構造化ペイロードのフィールドの場合、 - @type指定子が存在しない限り、対応する BigQuery フィールド名は小文字に正規化されますが、それ以外は名前は保持されます。- @type指定子が存在する構造化ペイロードについては、- @typeを含むペイロード フィールドをご覧ください。
次の例は、これらの命名規則がどのように適用されるかを示しています。
| ログエントリ フィールド | LogEntry型のマッピング | BigQuery フィールド名 | 
|---|---|---|
| insertId | insertId | insertId | 
| textPayload | textPayload | textPayload | 
| httpRequest.status | httpRequest.status | httpRequest.status | 
| httpRequest.requestMethod.GET | httpRequest.requestMethod.[ABC] | httpRequest.requestMethod.get | 
| resource.labels.moduleid | resource.labels.[ABC] | resource.labels.moduleid | 
| jsonPayload.MESSAGE | jsonPayload.[ABC] | jsonPayload.message | 
| jsonPayload.myField.mySubfield | jsonPayload.[ABC].[XYZ] | jsonPayload.myfield.mysubfield | 
@type でのペイロード フィールド
このセクションでは、ペイロードに指定子 @type が含まれるログエントリ用の特別な BigQuery スキーマ フィールド名について説明します。監査ログの命名規則については、このページの監査ログのフィールドをご覧ください。
ログエントリのペイロードには構造化データを含めることができます。すべての構造化フィールドには、オプションの型指定子を次の形式で含めることができます。
@type: type.googleapis.com/[TYPE]
@type の命名規則
型指定子を含む構造化フィールドには、フィールド名に [TYPE] が付いた BigQuery フィールド名が指定されます。[TYPE] の値は、任意の文字列にできます。
@type 指定子を持つフィールドの命名規則は、ログエントリのタイプによって決まります。監査ログ以外のログエントリの場合、命名規則は jsonPayload または protoPayload の最上位レベルにのみ適用され、ネストされたフィールドは無視されます。監査ログの命名規則については、このページの監査ログのフィールド セクションをご覧ください。
Logging で最上位の構造化ペイロード フィールドが処理されるとき、接頭辞 type.googleapis.com は削除されます。
たとえば、次の表は、監査ログ以外のログエントリにおける、最上位の構造化ペイロード フィールドの BigQuery フィールド名へのマッピングを示しています。
| ペイロード | ペイロード @type | ペイロード フィールド | BigQuery フィールド名 | 
|---|---|---|---|
| jsonPayload | (なし) | statusCode | jsonPayload.statusCode | 
| jsonPayload | type.googleapis.com/abc.Xyz | statusCode | jsonpayload_abc_xyz.statuscode | 
| protoPayload | (なし) | statusCode | protoPayload.statuscode | 
| protoPayload | type.googleapis.com/abc.Xyz | statusCode | protopayload_abc_xyz.statuscode | 
型指定子を含むフィールドでは、上記のルールにいくつかの例外が適用されます。
- App Engine のリクエストログでは、ペイロードに型指定子が含まれる場合でも、BigQuery にルーティングされたログのペイロード名は - protoPayloadになります。
- 上記の表は監査ログには適用されません。Cloud Logging では、監査ログの BigQuery スキーマ フィールド名を短縮するための特別な規則が適用されます。これについては、このページの監査ログのフィールド セクションで説明します。 
例
この例は、構造化ペイロード フィールドが BigQuery に受信されたときに、どのような名前になり、どのように使用されるかを示しています。
ログエントリのペイロードが次のように構成されているとします。
jsonPayload: {
  @type: "type.googleapis.com/google.cloud.v1.CustomType"
    name_a: {
      sub_a: "A value"
    }
    name_b: {
      sub_b: 22
    }
  }
BigQuery フィールドへのマッピングは次のとおりです。
- 最上位の構造化フィールド - jsonPayloadには、- @type指定子が含まれています。 BigQuery での名前は- jsonpayload_v1_customtypeです。
- ネストされたフィールドは、標準の BigQuery 命名規則として扱われます。ネストされたフィールドには、型指定子ルールが適用されないためです。 
つまり、このログエントリのペイロードに対しては次の BigQuery 名が定義されます。
  jsonpayload_v1_customtype
  jsonpayload_v1_customtype._type
  jsonpayload_v1_customtype.name_b
  jsonpayload_v1_customtype.name_b.sub_b
  jsonpayload_v1_customtype.name_a
  jsonpayload_v1_customtype.name_a.sub_a
監査ログのフィールド
BigQuery にルーティングされた監査ログを扱わない場合は、このセクションをスキップできます。
このセクションは、オプションの型指定子を次の形式で含めることができる構造化フィールドに適用されます。
@type: type.googleapis.com/[TYPE]
フィールド名の変更
監査ログに @type 指定子を含むペイロードが含まれている場合、Cloud Logging で BigQuery フィールド名が生成される前に、指定子に追加される [TYPE] 値が変更されることがあります。この変更により、BigQuery フィールド名は短くなります。
Logging では、[TYPE] 値に存在する接頭辞 type.googleapis.com が常に削除されます。次の表に、Logging によってフィールド名が短縮されるケースを示します。
| 元の [TYPE]値 | 変更後の [TYPE]値 | 
|---|---|
| google.cloud.audit.AuditLog | AuditLog | 
| google.appengine.legacy.AuditData | legacy.appengine | 
| google.appengine.v1alpha.AuditData | v1alpha.appengine | 
| google.appengine.v1beta.AuditData | v1beta.appengine | 
| google.appengine.v1beta4.AuditData | v1beta4.appengine | 
| google.appengine.v1beta5.AuditData | v1beta5.appengine | 
| google.appengine.v1.AuditData | v1.appengine | 
| google.cloud.bigquery.logging.v1.AuditData | v1.bigquery | 
| google.iam.v1.logging.AuditData | v1.iam | 
| google.iam.admin.v1.AuditData | v1.iam.admin | 
| google.type.Money | money | 
| google.appengine.logging.v1.RequestLog | 
たとえば、監査ログエントリに次の内容が含まれているとします。
{
  logName: "projects/REDACTED/logs/cloudaudit.googleapis.com%2Factivity"
  protoPayload: {
    @type: "type.googleapis.com/google.cloud.audit.AuditLog"
    serviceData: {
      @type: "type.googleapis.com/google.appengine.legacy.AuditData"
      eventData: {
        timezone: "UTC"
      }
    }
  }
}
BigQuery フィールド名は、次のように変更されたログエントリから取得されます。
{
  logName: "projects/REDACTED/logs/cloudaudit.googleapis.com%2Factivity"
  protoPayload: {
    @type: "AuditLog"
    serviceData: {
      @type: "legacy.appengine"
      eventData: {
        timezone: "UTC"
      }
    }
  }
}
@type の命名規則
監査ログには、@type 指定子を持つことができるフィールドがいくつかあります。
- protoPayload
- protoPayload.serviceData
- protoPayload.request
- protoPayload.response
- protoPayload.metadata
request、response、metadata の各フィールドは JSON データとして扱われます。つまり、BigQuery スキーマでフィールド名に Json が追加され、文字列データが JSON 形式で含められます。
次の表に、監査ログのペイロードが持つ 2 種類のフィールド名を示します。
| ログエントリ フィールド | BigQuery フィールド名 | 
|---|---|
| protoPayload | protopayload_auditlog | 
| protopayload.metadata | protopayload_auditlog.metadataJson | 
| protoPayload.request | protopayload_auditlog.requestJson | 
| protoPayload.response | protopayload_auditlog.responseJson | 
| protoPayload.serviceData | protopayload_auditlog.servicedata_v1_bigquery例: protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest | 
| protoPayload.status.code | protoPayload_auditlog.statuscode | 
serviceData の命名規則は、BigQuery によって生成され、Cloud Logging から BigQuery にルーティングされる監査ログに適用されます。このような監査ログエントリには、@type 指定子が type.googleapis.com/google.cloud.bigquery.logging.v1.auditdata である serviceData フィールドが含まれています。
例
BigQuery によって生成された監査ログエントリには、次の名前のフィールドがあります。
protoPayload.serviceData.tableInsertRequest
このログエントリが BigQuery にルーティングされた場合、tableInsertRequest フィールドはどのように参照されますか。名前を短縮する前は、BigQuery の対応するフィールド名は次のようになります。
protopayload_google_cloud_audit_auditlog.servicedata_google_cloud_bigquery_logging_v1_auditdata.tableInsertRequest
名前の短縮後、同じフィールドが BigQuery テーブルでは次のように参照されます。
protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest
テーブルの構成
このセクションでは、BigQuery にルーティングされるログのパーティション分割テーブルの概要について説明します。
BigQuery データセットにログをルーティングすると、Logging はログエントリを保持するテーブルを作成します。宛先 BigQuery テーブルのスキーマは、BigQuery で最初に受信するログエントリによって決定されます。BigQuery は、最初のログエントリのフィールドとそのタイプに基づいた列を持つテーブルを作成します。後続のログエントリでスキーマの不一致が発生する可能性があります。不一致が発生するタイミングとその処理方法については、スキーマの不一致をご覧ください。
Logging がエクスポートするデータを整理する 2 つのテーブルタイプ(日付別シャーディング テーブルとパーティション分割テーブル)があります。どちらのテーブルタイプも、ログエントリの timestamp フィールドに基づいてログデータを分割します。ただし、テーブルタイプ間には次の 2 つの主な違いがあります。
- パフォーマンス: パーティション分割テーブルは、大きいテーブルを小さいパーティションに分割するため、クエリのパフォーマンスを向上させ、クエリの読み込みバイト数を減らすことで BigQuery の費用をより効率的に管理できます。 
- テーブルの命名法: 次のセクションで説明するように、テーブルタイプで異なる命名規則が使用されます。 
テーブルの構成
ログエントリは、エントリのログ名とタイムスタンプに基づく組織と BigQuery テーブルにシャーディングされます。
テーブル名には、ログエントリの UTC タイムスタンプ(ISO 8601 の基本形式である YYYYMMDD を使用)のカレンダー日付が末尾に付加されます。
次の表は、ログ名とサンプルのタイムスタンプを BigQuery のテーブル名にマップする例を示しています。
| ログ名 | ログエントリ timestamp1 | BigQuery テーブル名 (日付別) | BigQuery テーブル名 (パーティション分割) | 
|---|---|---|---|
| syslog | 2017-05-23T18:19:22.135Z | syslog_20170523 | syslog | 
| apache-access | 2017-01-01T00:00:00.000Z | apache_access_20170101 | apache_access | 
| compute.googleapis.com/activity_log | 2017-12-31T23:59:59.999Z | compute_googleapis_com_activity_log_20171231 | compute_googleapis_com_activity_log | 
1 ログエントリのタイムスタンプは UTC(協定世界時)で表されます。
パーティション分割テーブルの作成
シンクを作成して BigQuery にログをルーティングする場合は、日付別シャーディング テーブルまたはパーティション分割テーブルを使用できます。デフォルトの選択は、日付別シャーディング テーブルです。
シンクの作成方法については、次のリソースをご覧ください。
- Google Cloud コンソール: サポートされている宛先にログをルーティングする。 
- Google Cloud CLI: - gcloud logging sinks create。
スキーマの不一致
宛先 BigQuery テーブルのスキーマは、BigQuery で最初に受信するログエントリによって決定されます。BigQuery は、最初のログエントリのフィールドとそのタイプに基づいた列を持つテーブルを作成します。
スキーマの不一致が発生するのは、ログエントリが宛先テーブルに書き込まれ、次のいずれかのエラーが発生した場合です。
- 後のログエントリで、テーブル内の既存のフィールドのフィールド タイプが変更されます。 - たとえば、最初のログエントリの - jsonPayload.user_idフィールドが- stringの場合、そのログエントリは、そのフィールドの文字列型を持つテーブルを生成します。後になって- jsonPayload.user_idを- arrayとしてロギングを開始した場合、スキーマの不一致が発生します。
- 新しいログエントリに、現在のスキーマにないフィールドが含まれていて、そのフィールドを宛先テーブルに挿入すると、BigQuery の列の上限を超えます。 - 列の上限を超えない限り、宛先テーブルは新しいフィールドを受け入れることができます。 
BigQuery はスキーマの不一致を識別すると、対応するデータセット内にテーブルを作成し、エラー情報を保存します。テーブル名はテーブルのタイプによって決まります。日付別テーブルの場合、命名形式は export_errors_YYYYMMDD です。パーティション分割テーブルの場合、命名形式は export_errors です。詳細については、テーブルの構成をご覧ください。
ログエントリをルーティングするときに、Logging はメッセージをバッチとして BigQuery に送信します。BigQuery は、次のルールを使用して、現在のメッセージ バッチのログエントリがどのテーブルに書き込まれるかを決定します。
- フィールド タイプが変更された場合、スキーマの不一致の原因となったログエントリのみがエラーテーブルに書き込まれます。スキーマの不一致を引き起こさない現在のバッチ内のログエントリは、元の宛先テーブルに書き込まれます。 
- 列の上限を超えると、現在のメッセージ バッチのすべてのログエントリがエラーテーブルに書き込まれます。 
エラーテーブルのスキーマ
エラーテーブルには、LogEntry のデータと不一致に関する情報が含まれます。
- logEntry: 完全なログエントリが含まれます。ただし、ログエントリは JSON から文字列に変換されます。
- schemaErrorDetail: BigQuery から返された完全なエラー メッセージが含まれます。
- sink: ログシンクの完全なリソースパスが含まれます。
- logName:- LogEntryから抽出されます。
- timestamp:- LogEntryから抽出されます。
- receiveTimestamp:- LogEntryから抽出されます。
- severity:- LogEntryから抽出されます。
- insertId:- LogEntryから抽出されます。
- trace:- LogEntryから抽出されます。
- resourceType:- LogEntryから抽出されます。
Logging は、次の方法でルーティング シンクを含むGoogle Cloud プロジェクトにスキーマの不一致を通知します。
- プロジェクト オーナーにメールを送信します。詳細には、 Google Cloud のプロジェクト ID、シンク名、宛先が含まれます。
-  Google Cloud コンソールの [アクティビティ] ページにエラー Stackdriver Config errorが表示されます。詳細には、シンク名と宛先、エラーの原因となったログエントリの例へのリンクが含まれます。
今後のフィールド タイプの不一致を防ぐ
後のログエントリのフィールド タイプの不一致を修正するには、現在のスキーマに一致するようにフィールド タイプを修正します。フィールド タイプを修正する方法については、列のデータ型を変更するをご覧ください。
フィールド タイプを変更できない場合があります。たとえば、 Google Cloudサービスによって自動生成されたログのフィールド タイプは変更できません。フィールド タイプを変更できない場合にスキーマの不一致を防ぐには、テーブルの名前を変更するか、シンクのパラメータを変更して、Logging で別のデータセットのテーブルを再作成します。手順については、シンクを管理するをご覧ください。
トラブルシューティング
シンクの宛先にログがないように見える場合や、シンクがログを正しくルーティングしていないと思われる場合は、ログのルーティングのトラブルシューティングをご覧ください。
料金
Cloud Logging では、サポートされている宛先へのログの転送で料金を請求されることはありませんが、宛先で料金が発生する場合があります。_Required ログバケットを除き、Cloud Logging では、ログバケットへのログのストリーミングと、ログバケットのデフォルト保持期間よりも長い保存に対して料金が請求されます。
Cloud Logging では、ログのコピー、ログスコープまたは分析ビューの作成、ログ エクスプローラまたはログ分析のページから発行されたクエリには課金されません。
詳細については、次のドキュメントをご覧ください。
- Google Cloud Observability の料金ページの Cloud Logging セクション。
- ログデータを他の Google Cloud サービスに転送する場合の費用: 
- Virtual Private Cloud フローログを送信した後で Cloud Logging から除外した場合は、VPC フローログの生成料金が適用されます。