このドキュメントでは、Cloud Logging から BigQuery テーブルに転送したログエントリを見つける方法について説明します。Logging シンクは、ロギングデータを小さなバッチで BigQuery にストリーミングし、読み込みジョブを実行せずにデータをクエリできるようにします。クエリを作成して BigQuery テーブルの形式を理解できるように、このドキュメントではルーティングされたログの BigQuery スキーマについても説明します。
通常、ログエントリは 1 分以内に BigQuery に表示されます。ただし、新しいテーブルが作成されてから最初のログエントリが利用可能になるまでに数分かかることがあります。
始める前に
シンクのコンセプトについては、ルーティングとストレージ モデルの概要: シンクをご覧ください。
ログをルーティングする方法については、サポートされている宛先にログを転送するをご覧ください。
ルーティングされるログエントリ フィールドの命名法については、ルーティングされるログの BigQuery スキーマをご覧ください。
ログの表示
BigQuery にルーティングされたログを表示する方法は次のとおりです。
-
Google Cloud コンソールのナビゲーション パネルで [BigQuery] を選択します。
[エクスプローラ] パネルでプロジェクトを開いて、データセットを選択します。
[詳細] タブにログエントリが表示されます。また、テーブルに対するクエリを行ってデータを返すこともできます。
サンプルクエリ
BigQuery クエリ シンタックスの詳細については、クエリ リファレンスをご覧ください。複数のテーブルをまたぐクエリが可能なテーブル ワイルドカード関数と、繰り返しフィールドのデータが表示できるようになるフラット化演算子は特に有用です。
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 スキーマ フィールド名について説明します。これには、BigQuery にルーティングされる監査ログエントリも含まれます。
ログエントリのペイロードには構造化データを含めることができます。すべての構造化フィールドには、オプションの型指定子を次の形式で含めることができます。
@type: type.googleapis.com/[TYPE]
命名規則は、監査ログエントリの protoPayload
フィールドが BigQuery スキーマ フィールド protopayload_auditlog
にマッピングされる理由を説明しています。
@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 にルーティングされた監査ログを扱わない場合は、このセクションをスキップできます。
監査ログのペイロード フィールドである protoPayload.request
、protoPayload.response
、protoPayload.metadata
には、@type
型指定子が付与されていますが、JSON データとして扱われます。つまり、それらの BigQuery スキーマ名は、フィールド名に Json
が追加され、JSON 形式の文字列データを含む形式になります。
次の表に、これら 2 つの監査ログのペイロード フィールド名を示します。
ログエントリ フィールド | BigQuery フィールド名 |
---|---|
protoPayload |
protopayload_auditlog |
protopayload.metadata |
protopayload_auditlog.metadataJson |
protoPayload.serviceData |
protopayload_auditlog.servicedata_v1_bigquery 例: protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest |
protoPayload.request |
protopayload_auditlog.requestJson |
protoPayload.response |
protopayload_auditlog.responseJson |
serviceData
命名規則は、BigQuery によって生成され、Cloud Logging から BigQuery にルーティングされる監査ログに固有です。これらの監査ログエントリには、次のような @type 指定子がある serviceData
フィールドが含まれています。type.googleapis.com/google.cloud.bigquery.logging.v1.auditdata
例
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 のテーブル名にマップする例を示しています。
ログ名 | ログエントリ timestamp 1 |
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 Console の [アクティビティ] ページにエラー
Stackdriver Config error
が表示されます。詳細には、シンク名と宛先、エラーの原因となったログエントリの例へのリンクが含まれます。
今後のフィールド タイプの不一致を防ぐ
後のログエントリのフィールド タイプの不一致を修正するには、現在のスキーマに一致するようにフィールド タイプを修正します。
たとえば、Google Cloud サービスによって自動的に生成されるログのフィールド タイプを変更できないときは、フィールド タイプを変更できません。フィールド タイプを変更できない場合のスキーマの不一致を防ぐため、テーブルの名前を変更するか、シンクのパラメータを変更して、Logging で別のデータセットのテーブルを再作成します。手順については、シンクを管理するをご覧ください。
トラブルシューティング
シンクの宛先にログがないように見える場合や、シンクがログを正しくルーティングしていないと思われる場合は、ログのルーティングのトラブルシューティングをご覧ください。
料金
Cloud Logging では、サポートされている宛先にログが転送されることはありませんが、転送先での請求が適用されることがあります。宛先の費用については、BigQuery の料金をご覧ください。
Cloud Logging から Virtual Private Cloud フローログを送信して除外した場合は、宛先料金に加え VPC フローログの生成料金が適用されます。