このドキュメントでは、インデックス付きの LogEntry フィールドを Cloud Logging バケットに追加して、ログデータのクエリを高速化する方法について説明します。
概要
クエリのパフォーマンスは、どのロギング ソリューションでも重要です。ワークロードがスケールアップし、対応するログボリュームが増加するに従い、最も頻繁に使用するログデータをインデックスに登録すると、クエリ時間を短縮できます。
クエリのパフォーマンスを向上させるため、Logging は次の LogEntry フィールドに自動的にインデックスを作成します。
- resource.type
- resource.labels.*
- logName
- severity
- timestamp
- insertId
- operation.id
- trace
- httpRequest.status
- labels。*
- split.uid
Logging によって自動的にインデックスに登録されるフィールドに加えて、バケットのカスタム インデックスを作成して、他の LogEntry フィールドをインデックスに登録するようにログバケットに指示できます。
たとえば、クエリ式に jsonPayload.request.status
フィールドが頻繁に含まれているとします。jsonPayload.request.status
を含むバケットにカスタム インデックスを構成できます。そのバケットのデータに対する後続のクエリは、クエリ式にそのフィールドが含まれている場合、インデックスに登録された jsonPayload.request.status
データを参照します。
Google Cloud CLI または Logging API を使用して、既存または新しいログバケットにカスタム インデックスを追加できます。カスタム インデックスに含める追加のフィールドを選択する際は、次の制限事項に注意してください。
- カスタム インデックスごとに最大 20 個のフィールドを追加できます。
- バケットのカスタム インデックスを構成または更新した後、変更がクエリに適用されるまで 1 時間ほど待つ必要があります。このレイテンシによりクエリ結果の正確性が保証され、過去に書き込まれたログを受け入れます。
- Logging は、インデックスの作成または変更後にログバケットに保存されたデータにカスタム インデックスを適用します。カスタム インデックスへの変更は、過去にさかのぼってログに適用されることはありません。
準備
カスタム インデックスの構成を開始する前に、次の操作を行います。
gcloud CLI の最新バージョンを使用していることを確認します。詳細については、Google Cloud CLI コンポーネントの管理をご覧ください。
次の権限を持つ Identity and Access Management ロールが付与されていることを確認します。
これらのロールの詳細については、IAM によるアクセス制御をご覧ください。
カスタム インデックスを定義する
バケットのカスタム インデックスに追加するフィールドごとに、フィールドパスとフィールドタイプという 2 つの属性を定義します。
fieldPath
: ログエントリの LogEntry フィールドへの具体的なパスを記述します。例:jsonPayload.req_status
type
: フィールドが文字列型か整数型かを示します。指定できる値はINDEX_TYPE_STRING
とINDEX_TYPE_INTEGER
です。
カスタム インデックスは、新しいバケットを作成するか、既存のバケットを更新することで追加できます。バケットの構成の詳細については、ログバケットを構成するをご覧ください。
バケットを作成するときにカスタム インデックスを構成するには、次の手順を実行します。
gcloud
gcloud logging buckets create
コマンドを使用して、--index
フラグを指定します。
gcloud logging buckets create BUCKET_NAME\ --location=LOCATION\ --description="DESCRIPTION" \ --index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE
コマンドの例:
gcloud logging buckets create int_index_test_bucket \ --location=global \ --description="Bucket with integer index" \ --index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER
API
バケットを作成するには、Logging API で projects.locations.buckets.create を使用します。次のように、メソッドの引数を準備します。
parent
パラメータを、バケットを作成するリソース(projects/PROJECT_ID/locations/LOCATION
)に設定します。変数 LOCATION は、ログを保存するリージョンを指します。
たとえば、リージョン
asia-east2
にプロジェクトmy-project
用のバケットを作成する場合、parent
パラメータは次のようになります:projects/my-project/locations/asia-east2
bucketId
パラメータを設定します(例:my-bucket
)。LogBucket
リクエスト本文で IndexConfig オブジェクトを構成して、カスタム インデックスを作成します。projects.locations.buckets.create を呼び出してバケットを作成します。
既存のバケットを更新してカスタム インデックスを含めるには、次の操作を行います。
gcloud
gcloud logging buckets update
コマンドを使用して、--add-index
フラグを設定します。
gcloud logging buckets update BUCKET_NAME\ --location=LOCATION\ --add-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE
コマンドの例:
gcloud logging buckets update \ int_index_test_bucket \ --location=global \ --add-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER
API
Logging API で projects.locations.buckets.patch を使用します。LogBucket リクエストの本文で、インデックスに登録する LogEntry フィールドを含めるように IndexConfig オブジェクトを構成します。
カスタム インデックス フィールドを削除する
バケットのカスタム インデックスからフィールドを削除するには、次のようにします。
gcloud
gcloud logging buckets update
コマンドを使用して、--remove-indexes
フラグを設定します。
gcloud logging buckets update BUCKET_NAME\ --location=LOCATION\ --remove-indexes=INDEX_FIELD_NAME
コマンドの例:
gcloud logging buckets update int_index_test_bucket \ --location=global \ --remove-indexes=jsonPayload.req_status
API
Logging API で projects.locations.buckets.patch を使用します。LogBucket リクエストの本文で、IndexConfig オブジェクトから LogEntry フィールドを削除します。
カスタム インデックス フィールドのデータ型を更新する
カスタム インデックス フィールドのデータ型を修正する必要がある場合は、次の操作を行います。
gcloud
gcloud logging buckets update
コマンドを使用して、--update-index
フラグを設定します。
gcloud logging buckets update BUCKET_NAME\ --location=LOCATION\ --update-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE
コマンドの例:
gcloud logging buckets update \ int_index_test_bucket \ --location=global \ --update-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER
API
Logging API で projects.locations.buckets.patch を使用します。LogBucket リクエスト本文で IndexConfig オブジェクトを更新し、LogEntry フィールドに正しいデータ型を指定します。
カスタム インデックス フィールドのパスを更新する
カスタム インデックス フィールドのフィールドパスを修正する必要がある場合は、次の操作を行います。
gcloud
gcloud logging buckets update
コマンドを使用して、--remove-indexes
フラグと --update-index
フラグを設定します。
gcloud logging buckets update BUCKET_NAME\ --location=LOCATION\ --remove-indexes=OLD_INDEX_FIELD_NAME \ --update-index=fieldPath=NEW_INDEX_FIELD_NAME,type=INDEX_TYPE
コマンドの例:
gcloud logging buckets update \ int_index_test_bucket \ --location=global \ --remove-indexes=jsonPayload.req_status_old_path \ --add-index=fieldPath=jsonPayload.req_status_new_path,type=INDEX_TYPE_INTEGER
API
Logging API で projects.locations.buckets.patch を使用します。LogBucket リクエスト本文で IndexConfig オブジェクトを更新し、LogEntry フィールドに正しいフィールドパスを指定します。
バケットのインデックス化されたすべてのフィールドを一覧表示する
カスタム インデックス フィールドを含むバケットの詳細を一覧表示するには、次の操作を行います。
gcloud
gcloud logging buckets describe
コマンドを実行します。
gcloud logging buckets describe BUCKET_NAME\ --location=LOCATION
コマンドの例:
gcloud logging buckets describe indexed-bucket \ --location global
API
Logging API で projects.locations.buckets.get を使用します。
カスタム インデックス フィールドをクリアする
バケットからすべてのカスタム インデックス フィールドを消去するには、次のようにします。
gcloud
gcloud logging buckets update
コマンドを使用して、--clear-indexes
フラグを指定します。
gcloud logging buckets update BUCKET_NAME\ --location=LOCATION\ --clear-indexes
コマンドの例:
gcloud logging buckets update \ int_index_test_bucket \ --location=global \ --clear-indexes
API
Logging API で projects.locations.buckets.patch を使用します。LogBucket リクエストの本文で、IndexConfig オブジェクトを削除します。
インデックス付きデータのクエリ実行と表示
カスタム インデックス フィールドに含まれるデータのクエリを実行するには、クエリのスコープをカスタム インデックス フィールドを含むバケットに制限し、適切なログビューを指定します。
gcloud
ログバケットからログを読み取るには、gcloud logging read コマンドに LOG_FILTER
を追加して、インデックス化されたデータを含めます。
gcloud logging read LOG_FILTER --bucket=BUCKET_ID --location=LOCATION --view=VIEW_ID
API
ログバケットからログを読み取るには、entries.list
メソッドを使用します。resourceNames
を設定して適切なバケットとログビューを指定し、filter
でインデックス付きデータを選択します。
フィルタリング構文の詳細については、Logging のクエリ言語をご覧ください。
インデックス タイプとフィールド タイプ
カスタム フィールド インデックスの構成方法は、ログのログバケットへの保存方法やクエリの処理の方法に影響します。
書き込み時
Logging は、インデックスの作成後にログバケットに保存されたデータにカスタム インデックスの使用を試みます。
インデックス付きフィールドが入力されますが、これはログエントリのタイムスタンプに影響します。ログエントリがログバケットに保存されるとき、次のルールを使用してログフィールドがインデックス タイプに対して評価されます。
- フィールド タイプがインデックス タイプと同じ場合、データはインデックスとしてすぐに追加されます。
- フィールド タイプがインデックス タイプと異なる場合、Logging はフィールド タイプをインデックス タイプ(整数から文字列など)に強制変換しようとします。
- タイプの強制変換が失敗した場合、データはインデックスに登録されません。タイプの強制変換が成功すると、データはインデックスに登録されます。
クエリ時
フィールドでインデックスを有効にすると、そのフィールドをクエリする方法が変わります。デフォルトでは、Logging は評価対象の各ログエントリのデータ型に基づいて、フィールドにフィルタ制約を適用します。インデックスが有効な場合、フィールドに対するフィルタ制約はインデックスのタイプに基づいて適用されます。フィールドにインデックスを追加すると、そのフィールドにスキーマが適用されます。
バケット用にカスタム インデックスが構成されている場合、次の条件の両方が満たされると、スキーマを一致させる動作が変わります。
- フィールドのソースデータ型がそのフィールドのインデックス型と一致しない。
- ユーザーが、このフィールドに制約を適用している。
次の JSON ペイロードについて考えてみましょう。
{"jsonPayload": {"name": "A", "value": 12345}} {"jsonPayload": {"name": "B", "value": "3"}}
次は、このフィルタをそれぞれに適用します。
jsonPayload.value > 20
jsonPayoad.value
フィールドにカスタム インデックスがない場合、Logging では柔軟なタイプのマッチングが適用されます。
「A」の場合、Logging は「value」キーの値が実際には整数であり、制約「20」を整数に変換できることを確認します。Logging は
12345 > 20
を評価し、この場合は数値であるため「true」を返します。「B」の場合、Logging は「value」キーの値が実際には文字列であることを確認します。次に、
"3" > "20"
を評価し、この場合は英数字に該当するため「true」を返します。
フィールド jsonPayload.value
がカスタム インデックスに含まれている場合、Logging は通常の Logging ロジックではなく、インデックスを使用してこの制約を評価します。この動作は次のように変更されます。
- インデックスが文字列型の場合、すべての比較は文字列比較です。
- 「12345」は英数字の「20」以下のため、「A」のエントリは一致しません。文字列「3」が「20」より大きいため、「B」のエントリが一致します。
- インデックスが整数型の場合、すべての比較は整数比較になります。
- 「3」が数値的に「20」よりも大きくないため、「B」エントリは一致しません。「12345」は「20」より大きいため、「A」エントリは一致します。
この動作の違いはごくわずかであるため、カスタム インデックスを定義して使用する際は、この点を考慮する必要があります。
フィルタリング エッジケース
jsonPayload.value
整数型インデックスについて、文字列値がフィルタリングされたとします。
jsonPayload.value = "hello"
クエリ値をインデックス タイプに強制変換できない場合、インデックスは無視されます。
ただし、文字列型のインデックスに整数値を渡すとします。
jsonPayload.value > 50
「12345」も「3」も英数字の「50」より大きくないため、A も B も一致しません。