カスタム インデックスを構成する

このドキュメントでは、インデックス付きの LogEntry フィールドを Cloud Logging バケットに追加して、ログデータのクエリを高速化する方法について説明します。

概要

クエリのパフォーマンスは、どのロギング ソリューションにとっても重要です。ワークロードがスケールアップし、対応するログボリュームが増加するに従い、最も頻繁に使用するログデータをインデックスに登録すると、クエリ時間を短縮できます。

クエリのパフォーマンスを向上させるため、Logging は次の LogEntry フィールドを自動的にインデックスに登録します。

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_STRINGINDEX_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 を使用します。次のように、メソッドの引数を準備します。

  1. parent パラメータを、バケットを作成するリソース(projects/PROJECT_ID/locations/LOCATION)に設定します。

    変数 LOCATION は、ログを保存するリージョンを指します。

    たとえば、リージョン asia-east2 にプロジェクト my-project 用のバケットを作成する場合、parent パラメータは次のようになります: projects/my-project/locations/asia-east2

  2. bucketId パラメータを設定します(例: my-bucket)。

  3. LogBucket リクエスト本文で、IndexConfig オブジェクトを構成してカスタム インデックスを作成します。

  4. 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 も一致しません。