カスタム インデックス フィールドの構成とクエリ

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

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

概要

クエリのパフォーマンスは、どのロギング ソリューションにおいても重要です。ワークロードがスケールアップされ、対応するログ容量が増加すると、使用頻度の高いログデータをインデックスに登録することで、クエリ時間を短縮できます。

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

Logging によって自動的にインデックスに登録されるフィールドに加えて、バケットのカスタム インデックスを作成して、他の LogEntry フィールドをインデックスに登録するようにログバケットに指示できます。

たとえば、クエリ式に jsonPayload.request.status フィールドが含まれているとします。jsonPayload.request.status を含むバケットのカスタム インデックスを構成できます。そのバケットのデータに対する後続のクエリは、クエリ式にそのフィールドが含まれている場合、インデックス付き jsonPayload.request.status データを参照します。

Google Cloud CLI または Logging API を使用して、既存のログバケットや新しいログバケットにカスタム インデックスを追加できます。カスタム インデックスに含める追加のフィールドを選択するときは、次の制限事項に注意してください。

  • カスタム インデックスごとに最大 20 個のフィールドを追加できます。
  • バケットのカスタム インデックスを構成または更新した後、変更がクエリに適用されるまで 1 時間待ちます。このレイテンシにより、クエリ結果の正確性が保証され、過去に書き込まれたログも受け入れられます。
  • Logging は、インデックスの作成または変更後に取り込まれたデータにカスタム インデックスを適用します。カスタム インデックスへの変更は、過去にさかのぼってログに適用されることはありません。

始める前に

カスタム インデックスの構成を開始する前に、次の操作を行います。

カスタム インデックスを定義する

バケットのカスタム インデックスに追加するフィールドごとに、フィールドパスとフィールド タイプの 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=BUCKET_LOCATION \
--description="BUCKET 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=BUCKET_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=BUCKET_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=BUCKET_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=BUCKET_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=BUCKET_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=BUCKET_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 を返すため、これは 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 も一致しません。