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

本文說明如何將已編入索引的 LogEntry 欄位新增至 Cloud Logging 值區,加快查詢記錄資料的速度。

總覽

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

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

除了 Logging 自動建立索引的欄位外,您也可以為值區建立自訂索引,讓記錄值區索引其他 LogEntry 欄位。

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

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

  • 每個自訂索引最多可新增 20 個欄位。
  • 設定或更新值區的自訂索引後,您必須等待一小時,變更才能套用至查詢。這可確保查詢結果正確無誤,並接受先前寫入的記錄。
  • 記錄會在建立或變更索引後,將自訂索引套用至儲存在記錄值區中的資料;自訂索引的變更不會回溯套用至記錄。

事前準備

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

定義自訂索引

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

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

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

如要在建立 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

如要建立值區,請在 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 來建立值區。

如要更新現有 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 欄位。

刪除自訂索引欄位

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

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=LOG_VIEW_ID

API

如要讀取記錄值,請使用 entries.list 方法。設定 resourceNames 以指定適當的桶和記錄檢視畫面,並設定 filter 選取已編入索引的資料。

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

索引和欄位類型

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

在寫入時

記錄會在建立索引後,嘗試在儲存在記錄值區的資料上使用自訂索引。

已編入索引的欄位會加上類型,這會影響記錄項目上的時間戳記。當記錄項目儲存在記錄桶中時,系統會根據下列規則,根據索引類型評估記錄欄位:

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

在查詢時

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

為分層設定自訂索引時,如果同時符合下列兩個條件,結構定義比對行為會有所不同:

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

請參考下列 JSON 酬載:

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

接著,將這個篩選器套用到每個項目:

jsonPayload.value > 20

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

  • 針對「A」,Logging 觀察到「value」鍵的值其實是整數,且限制「20」可轉換為整數。記錄功能接著會評估 12345 > 20,並傳回「true」,因為這是數值上的情況。

  • 在「B」中,記錄功能會觀察到「value」鍵的值其實是字串。接著,系統會評估 "3" > "20" 並傳回「true」,因為這是以英數字母為基礎的情況。

如果自訂索引包含 jsonPayload.value 欄位,記錄會使用該索引評估這項限制,而非使用一般記錄邏輯。行為變更:

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

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

篩選邊緣情況

針對 jsonPayload.value 整數類型索引,假設字串值已篩除:

jsonPayload.value = "hello"

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

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

jsonPayload.value > 50

由於「12345」和「3」的數字/字母大於「50」,因此 A 和 B 都不符合條件。