透過自訂索引改善查詢時間

Cloud Logging 的自訂索引可讓您為記錄檔 bucket 中經常查詢的 LogEntry 欄位建立索引,加快查詢大量記錄檔資料的速度。除了 Logging 自動建立索引的欄位外,您也可以在新 bucket 或現有 bucket 的字串或整數欄位上設定自訂索引。

總覽

查詢效能對任何記錄解決方案都至關重要。隨著工作負載擴充,相應的記錄量也會增加,為最常用的記錄資料建立索引,可縮短查詢時間。

為提高查詢效能,Logging 會自動為下列 LogEntry 欄位建立索引:

除了 Logging 自動建立索引的欄位外,您也可以為 bucket 建立自訂索引,指示記錄檔 bucket 為其他 LogEntry 欄位建立索引。

舉例來說,假設查詢運算式經常包含 jsonPayload.request.status 欄位。您可以為包含 jsonPayload.request.status 的 bucket 設定自訂索引,如果查詢運算式包含該欄位,則對該 bucket 資料的任何後續查詢都會參照已建立索引的 jsonPayload.request.status 資料。

您可以使用 Google Cloud CLI 或 Logging API,在現有或新的記錄檔 bucket 中新增自訂索引。選取要加入自訂索引的其他欄位時,請注意下列限制:

  • 每個自訂索引最多可新增 20 個欄位。
  • 設定或更新 bucket 的自訂索引後,必須等待一小時,變更才會套用至查詢。這項延遲可確保查詢結果正確無誤,並接受過去寫入的記錄。
  • Logging 會對建立或變更索引後,儲存在記錄檔 bucket 中的資料套用自訂索引;自訂索引的變更不會溯及既往。

事前準備

開始設定自訂索引前,請先完成下列事項:

定義自訂索引

針對新增至 bucket 自訂索引的每個欄位,您必須定義兩個屬性:欄位路徑和欄位類型:

  • fieldPath:說明記錄項目中 LogEntry 欄位的特定路徑。例如:jsonPayload.req_status。
  • type:指出欄位是字串或整數類型。可能的值為 INDEX_TYPE_STRING 和 INDEX_TYPE_INTEGER。

您可以建立新值區或更新現有值區,藉此新增自訂索引。如要進一步瞭解如何設定 bucket,請參閱「設定記錄檔 bucket」。

如要在建立 bucket 時設定自訂索引,請按照下列步驟操作:

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

如要建立 bucket,請使用 Logging API 中的 projects.locations.buckets.create。請按照下列方式準備方法的引數:

  1. 將 parent 參數設為要建立 bucket 的資源:projects/PROJECT_ID/locations/LOCATION

    變數 LOCATION 是指要儲存記錄檔的區域。

    舉例來說,如要為 asia-east2 區域中的專案 my-project 建立 bucket,parent 參數會如下所示:projects/my-project/locations/asia-east2

  2. 設定 bucketId 參數,例如 my-bucket。

  3. 在 LogBucket 要求主體中,設定 IndexConfig 物件,建立自訂索引。

  4. 呼叫 projects.locations.buckets.create 建立 bucket。

如要更新現有 bucket 以納入自訂索引,請按照下列步驟操作:

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 要求主體中,設定 IndexConfig 物件,加入要建立索引的 LogEntry 欄位。

刪除自訂索引欄位

如要從 bucket 的自訂索引中刪除欄位,請按照下列步驟操作:

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 欄位提供正確的欄位路徑。

列出 bucket 的所有索引欄位

如要列出 bucket 的詳細資料 (包括自訂索引欄位),請按照下列步驟操作:

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。

清除自訂索引欄位

如要從 bucket 移除所有自訂索引欄位,請按照下列步驟操作:

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 物件。

查詢及查看已建立索引的資料

如要查詢自訂索引欄位中的資料,請將查詢範圍限制在包含自訂索引欄位的 bucket,並指定適當的記錄檔檢視:

gcloud

如要讀取記錄檔 bucket 中的記錄檔,請使用 gcloud logging read 指令,並新增 LOG_FILTER 來納入索引資料:

gcloud logging read LOG_FILTER --bucket=BUCKET_ID --location=LOCATION --view=LOG_VIEW_ID

API

如要讀取記錄檔 bucket 中的記錄檔,請使用 entries.list 方法。設定 resourceNames 來指定適當的值區和記錄檔檢視,並設定 filter 來選取索引資料。

如要進一步瞭解篩選語法,請參閱「Logging 查詢語言」。

索引和欄位類型

自訂欄位索引的設定方式,可能會影響記錄檔在記錄檔 bucket 中的儲存方式,以及查詢的處理方式。

寫入時

Logging 會嘗試對索引建立後儲存在記錄 bucket 中的資料使用自訂索引。

索引欄位會指定類型,這會影響記錄項目的時間戳記。記錄項目儲存在記錄檔 bucket 時,系統會根據下列規則,依據索引類型評估記錄欄位:

  • 如果欄位類型與索引類型相同,資料就會逐字新增至索引。
  • 如果欄位的類型與索引的類型不同,Logging 會嘗試將其強制轉型為索引的類型 (例如,將整數轉換為字串)。
    • 如果類型強制轉型失敗,系統就不會為資料建立索引。如果類型強制轉型成功,系統就會為資料建立索引。

查詢時

在欄位上啟用索引後,查詢該欄位的方式會有所不同。根據預設,Logging 會根據要評估的每個記錄項目中的資料類型,將篩選器限制套用至欄位。啟用索引功能後,系統會根據索引類型,對欄位套用篩選器限制。在欄位上新增索引會對該欄位施加結構定義。

如果 bucket 設定了自訂索引,且同時符合下列兩項條件,結構定義比對行為就會有所不同:

  • 欄位的來源資料類型與該欄位的索引類型不符。
  • 使用者對該欄位套用限制。

請參考下列 JSON 酬載:

{"jsonPayload": {"name": "A", "value": 12345}}
{"jsonPayload": {"name": "B", "value": "3"}}

現在,請將這項篩選條件套用至各個項目:

jsonPayload.value > 20

如果 jsonPayload.value 欄位缺少自訂索引,Logging 會套用彈性類型比對:

  • 對於「A」,Logging 會觀察到「value」鍵的值實際上是整數,且限制「20」可以轉換為整數。Logging 接著會評估 12345 > 20,並傳回「true」,因為數值上確實如此。

  • 對於「B」,Logging 會發現「value」鍵的值實際上是字串。接著評估 "3" > "20",並傳回「true」,因為英數字元確實符合這個條件。

如果自訂索引包含 jsonPayload.value 欄位,Logging 會使用索引評估這項限制,而非一般的 Logging 邏輯。行為異動:

  • 如果索引是字串類型,則所有比較都是字串比較。
    • 「A」項目不符合,因為「12345」在英數字元順序上不大於「20」。「B」項目符合條件,因為字串「3」大於「20」。
  • 如果索引是整數類型,則所有比較都是整數比較。
    • 「B」項目不符合,因為「3」在數值上不大於「20」。「A」項目符合條件,因為「12345」大於「20」。

這種行為差異很細微,在定義及使用自訂索引時應加以考量。

篩選極端案例

對於 jsonPayload.value 整數類型索引,假設篩選字串值:

jsonPayload.value = "hello"

如果查詢值無法強制轉型為索引類型,系統會忽略索引。

不過,假設您為字串類型索引傳遞整數值:

jsonPayload.value > 50

A 和 B 都不符合,因為「12345」和「3」的英數字元值都不大於「50」。