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

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

總覽

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

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

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

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

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

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

事前準備

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

定義自訂索引

為每個新增至 Bucket 自訂索引的欄位定義兩個屬性:欄位路徑和欄位類型:

  • 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

如要建立 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 的所有已建立索引的欄位

如要列出值區的詳細資料 (包括自訂索引欄位),請執行下列操作:

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

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

如要查詢自訂索引欄位中包含的資料,請將查詢範圍限制在包含自訂索引欄位的 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 指定適當的 bucket 和記錄檢視畫面,並設定 filter 選取已建立索引的資料。

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

索引和欄位類型

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

寫入時

記錄嘗試在建立索引後,對儲存在記錄值區中的資料使用自訂索引的行為。

建立索引的欄位會經過型別化,這會影響記錄項目的時間戳記。記錄項目儲存在記錄檔 bucket 時,系統會使用下列規則,根據索引類型評估記錄檔欄位:

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

查詢時

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

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

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

請參考下列 JSON 酬載:

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

現在,請對每個項目套用這個篩選器:

jsonPayload.value > 20

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

  • 對於「A」,記錄會觀察到「value」鍵的值實際上是整數,且「20」這個限制可以轉換為整數。記錄檔接著會評估 12345 > 20,並傳回「true」,因為以數值來看,這就是實際情況。

  • 對於「B」,記錄會觀察到「value」鍵的值實際上是字串。接著評估 "3" > "20",並傳回「true」,因為這是字母數字的情況。

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

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

這種行為差異很細微,但在定義及使用自訂索引時,請務必留意。

篩選特殊情況

假設針對 jsonPayload.value 整數型別的索引篩選字串值:

jsonPayload.value = "hello"

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

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

jsonPayload.value > 50

A 和 B 都不相符,因為「12345」和「3」在英數方面都不大於「50」。