Trace 的 SQL 查詢範例

本文包含的範例查詢,專門用於查詢儲存在 Google Cloud 專案中的追蹤資料。

支援的 SQL 語言

「記錄檔分析」頁面中使用的查詢支援 GoogleSQL 函式,但有部分例外情況。

透過「記錄檔分析」頁面發出的 SQL 查詢,不支援下列 SQL 指令:

  • DDL 和 DML 指令
  • JavaScript 使用者定義函式
  • BigQuery ML 函式
  • SQL 變數

只有透過 BigQuery StudioLooker Studio 頁面,或使用 bq 指令列工具查詢連結的資料集時,才支援下列項目:

  • JavaScript 使用者定義函式
  • BigQuery ML 函式
  • SQL 變數

最佳做法

如要設定查詢的時間範圍,建議使用時間範圍選取器。舉例來說,如要查看過去一週的資料,請從時間範圍選取器選取「過去 7 天」。你也可以使用時間範圍選取器指定開始和結束時間、指定要查看的時間,以及變更時區。

如果在 WHERE 子句中加入 start_time 欄位,系統就不會使用時間範圍選取器設定。下列範例會使用 TIMESTAMP_SUB 函式篩選資料,讓您指定從目前時間回溯的時間間隔:

WHERE
  start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

如要進一步瞭解如何依時間篩選,請參閱「時間函式」和「時間戳記函式」。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Observability API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Observability API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  8. 如要取得載入「記錄分析」頁面、在追蹤記錄資料上撰寫、執行及儲存私人查詢所需的權限,請要求管理員授予您下列 IAM 角色:

    • 觀測檢視畫面存取者 (roles/observability.viewAccessor) 在您要查詢的觀測檢視畫面中,這個角色支援 IAM 條件,可讓您將授權限制在特定檢視區塊。如果未將條件附加至角色授權,主體就能存取所有可觀測性檢視畫面。
    • 您專案的「Observability Analytics User」 (roles/observability.analyticsUser) 權限。這個角色具備儲存及執行私人查詢,以及執行共用查詢所需的權限。
    • 記錄檢視器 (roles/logging.viewer) 專案。

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

    您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

如何使用這個頁面上的查詢

  1. 在 Google Cloud 控制台中,前往 「Log Analytics」(記錄檔分析) 頁面:

    前往「Log Analytics」(記錄檔分析)

    如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

  2. 在「查詢」窗格中,按一下 「SQL」,然後複製查詢並貼到 SQL 查詢窗格。

    以下顯示查詢 _AllSpans 檢視區塊時,FROM 原因的格式:

    FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
    

    FROM 子句包含下列欄位:

    • PROJECT_ID:專案的 ID。
    • LOCATION可觀測性 bucket 的位置
    • _Trace 是可觀測性值區的名稱
    • Spans 是資料集名稱。
    • _AllSpans 是視圖的名稱。

如要在 BigQuery Studio 頁面使用本文顯示的查詢,或使用 bq 指令列工具,請編輯 FROM 子句,然後輸入連結資料集的路徑。舉例來說,如要查詢專案 myproject 中名為 my_linked_dataset 的連結資料集上的 _AllSpans 檢視區塊,路徑為 `myproject.my_linked_dataset._AllSpans`

常見用途

本節列出幾個常見用途,協助您建立自訂查詢。

顯示所有追蹤記錄資料

如要查詢 _AllSpans 檢視區塊,請執行下列查詢:

-- Display all data.
SELECT *
FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
-- Limit to 10 entries.
LIMIT 10

顯示常見範圍資訊

如要顯示常見的範圍資訊 (例如開始時間和持續時間),請執行下列查詢:

SELECT
  start_time,
  -- Set the value of service name based on the first non-null value in the list.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
  name AS span_name,
  duration_nano,
  status.code AS status,
  trace_id,
  span_id
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
LIMIT 10

詳情請參閱「條件運算式」。

顯示時距的第 50 和第 99 個百分位數延遲時間

如要顯示每個 RPC 服務的延遲時間第 50 和第 99 個百分位數,請執行下列查詢:

SELECT
  -- Compute 50th and 99th percentiles for each service
  STRING(attributes['rpc.service']) || '/' || STRING(attributes['rpc.method']) AS rpc_service_method,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS duration_nano_p50,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS duration_nano_p99
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans whose kind field has a value of 2 (SPAN_KIND_SERVER).
  kind = 2
GROUP BY rpc_service_method

如要進一步瞭解列舉,請參閱 OpenTelemetry:SpanKind 說明文件。

如要以圖形方式查看結果,可以建立圖表,並將維度設為 rpc_service_method。您可以新增兩項指標,分別是 duration_nano_p50 值的平均值,以及 duration_nano_p99 欄位的平均值。

篩選追蹤記錄項目

如要對查詢套用篩選器,請新增 WHERE 子句。您在這個子句中使用的語法取決於欄位的資料類型。本節提供幾種不同資料類型的範例。

依字串資料類型篩選

欄位 name 會儲存為 String

  • 如要只分析指定 name 的範圍,請使用下列子句:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • 如要只分析 name 的值為 "POST" 的範圍,請使用下列子句:

    -- Matches spans whose name is POST.
    WHERE STRPOS(name, "POST") > 0
    
  • 如要只分析 name 包含 "POST" 值的範圍,請使用 LIKE 運算子和萬用字元:

    -- Matches spans whose name contains POST.
    WHERE name LIKE "%POST%"
    

依整數資料類型篩選

欄位 kind 是整數,可接受介於零到五之間的值:

  • 如要只分析指定 kind 的範圍,請使用下列子句:

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • 如要分析 kind 值為一或二的範圍,請使用下列子句:

    -- Matches spans whose kind value is 1 or 2.
    WHERE kind IN (1, 2)
    

依 RECORD 資料類型篩選

追蹤記錄架構中的部分欄位資料類型為 RECORD。這些欄位可以儲存一或多個資料結構,也可以儲存相同資料結構的重複項目。

依狀態或狀態碼篩選

status 欄位是資料類型為 RECORD 的欄位範例。這個欄位會儲存一個資料結構,成員標示為 codemessage

  • 如要只在 status.code 欄位的值為 1 時分析範圍,請新增下列子句:

    -- Matches spans that have a status.code field that has a value of 1.
    WHERE status.code = 1
    

    status.code 欄位會儲存為整數。

  • 如要分析 status 欄位不是 EMPTY 的跨度,請新增下列子句:

    -- Matches spans that have status field. When the status field exists, it
    -- must contain a subfield named code.
    -- Don't compare status to NULL, because this field has a data type of RECORD.
    WHERE status.code IS NOT NULL
    

eventslinks 欄位會以 RECORD 資料類型儲存,但這些是重複欄位。

  • 如要比對至少有一個事件的範圍,請使用下列子句:

    -- Matches spans that have at least one event. Don't compare events to NULL.
    -- The events field has data type of RECORD and contains a repeated fields.
    WHERE ARRAY_LENGTH(events) > 0
    
  • 如要比對具有事件的範圍,且事件的 name 欄位值為 message,請使用下列子句:

    WHERE
      -- Exists is true when any event in the array has a name field with the
      -- value of message.
      EXISTS(
        SELECT 1
        FROM UNNEST(events) AS ev
        WHERE ev.name = 'message'
      )
    

依 JSON 資料類型篩選

attributes 欄位的類型為 JSON。每個屬性都是鍵/值組合。

  • 如要只分析指定 attributes 的範圍,請使用下列子句:

    -- Matches spans where at least one attribute is specified.
    WHERE attributes IS NOT NULL
    
  • 如要只分析屬性鍵名為 component 且值為 "proxy" 的範圍,請使用下列子句:

    -- Matches spans that have an attribute named component with a value of proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') = 'proxy'
    

    您也可以搭配使用 LIKE 陳述式和萬用字元,執行包含測試:

    -- Matches spans that have an attribute named component whose value contains proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') LIKE '%proxy%'
    

將追蹤記錄資料分組及匯總

本節說明如何分組及彙整範圍。如果您未指定分組,但指定了匯總,則系統會列印一個結果,因為 SQL 會將滿足 WHERE 子句的所有項目視為一個群組。

每個 SELECT 運算式都必須包含在群組欄位中,或經過匯總。

依開始時間將範圍分組

如要依開始時間將資料分組,請使用 TIMESTAMP_TRUNC 函式,將時間戳記截斷為指定精細度,例如 HOUR

SELECT
  -- Truncate the start time to the hour. Count the number of spans per group.
  TIMESTAMP_TRUNC(start_time, HOUR) AS hour,
  status.code AS code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans shows start time is within the previous 12 hours.
  start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)
GROUP BY
  -- Group by hour and status code.
  hour, code
ORDER BY hour DESC

詳情請參閱 TIMESTAMP_TRUNC 說明文件日期時間函式

依狀態碼計算範圍數量

如要顯示具有特定狀態碼的範圍數量,請執行下列查詢:

SELECT
  -- Count the number of spans for each status code.
  status.code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE status.code IS NOT NULL
GROUP BY status.code

如果將 status.code 替換為 kind,則先前的查詢會回報 kind 列舉中每個值的範圍數量。同樣地,如果將 status.code 替換為 name,查詢結果會列出每個跨度名稱的項目數量。

計算所有範圍的平均時間長度

如要顯示平均時間長度,請依 span 名稱分組 span 資料,然後執行下列查詢:

SELECT
  -- Group by name, and then compute the average duration for each group.
  name,
  AVG(duration_nano) AS nanosecs,
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY name
ORDER BY nanosecs DESC

計算每個服務名稱的平均時間和百分位數

下列查詢會計算每個服務的範圍計數和各種統計資料:

SELECT
  -- Set the service name by the first non-null value.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,

  -- Count the number spans for each service name. Also compute statistics.
  COUNT(*) AS span_count,
  AVG(duration_nano) AS avg_duration_nano,
  MIN(duration_nano) AS min_duration_nano,
  MAX(duration_nano) AS max_duration_nano,

  -- Calculate percentiles for duration
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS p50_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(95)] AS p95_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS p99_duration_nano,

  -- Count the number of unique trace IDs. Also, collect up to 5 unique
  -- span names and status codes.
  COUNT(DISTINCT trace_id) AS distinct_trace_count,
  ARRAY_AGG(DISTINCT name IGNORE NULLS LIMIT 5) AS sample_span_names,
  ARRAY_AGG(DISTINCT status.code IGNORE NULLS LIMIT 5) AS sample_status_codes
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY service_name
ORDER BY span_count DESC

本節說明兩種方法,可用於搜尋所查詢檢視區塊的多個資料欄:

  • 以權杖為準的搜尋:指定搜尋位置和搜尋查詢,然後使用 SEARCH 函式。由於 SEARCH 函式有特定的資料搜尋規則,建議您參閱 SEARCH 說明文件

  • 以子字串為準的搜尋:您提供搜尋位置和字串常值,然後使用 CONTAINS_SUBSTR 函式。系統會執行不區分大小寫的測試,判斷運算式中是否存在字串常值。如果字串常值存在,CONTAINS_SUBSTR 函式會傳回 TRUE,否則會傳回 FALSE。搜尋值必須是 STRING 常值,但不得為 NULL 常值。

查詢多個檢視區塊

查詢陳述式可掃描一或多個資料表或運算式,然後傳回運算的結果資料列。舉例來說,您可以使用查詢陳述式,以各種方式合併不同資料表或資料集中的 SELECT 陳述式結果,然後從合併的資料中選取資料欄。

如要聯結檢視區塊,請遵守下列限制:

  1. 檢視區塊的位置符合下列其中一項條件:

    • 所有檢視區都有相同的位置。
    • 所有檢視畫面都位於 globalus 位置。
  2. 如果儲存空間資源使用客戶自行管理的加密金鑰 (CMEK),則必須符合下列其中一項條件:

    • 使用 CMEK 的儲存空間資源會使用相同的 Cloud KMS 金鑰。
    • 使用 CMEK 的儲存空間資源具有共同祖系,而該祖系會指定與儲存空間資源位於相同位置的預設 Cloud KMS 金鑰。

    當一或多個儲存空間資源使用 CMEK 時,系統會使用通用 Cloud KMS 金鑰或上層的預設 Cloud KMS 金鑰,加密聯結產生的暫時資料。

舉例來說,假設您有兩個位於相同位置的檢視區塊。接著,在符合下列任一條件時,即可聯結這些檢視畫面:

  • 儲存空間資源不會使用 CMEK。
  • 一個儲存空間資源使用 CMEK,另一個則否。
  • 兩個儲存空間資源都使用 CMEK,且都使用相同的 Cloud KMS 金鑰。
  • 這兩種儲存空間資源都使用 CMEK,但使用的金鑰不同。不過,這些資源共用一個祖先,該祖先會指定與儲存空間資源位於相同位置的預設 Cloud KMS 金鑰。

    舉例來說,假設記錄檔 bucket 和可觀測性 bucket 的資源階層包含相同的機構。如果已為機構設定 Cloud Logging 的預設資源設定,並為可觀測性 bucket 設定儲存位置的預設 Cloud KMS 金鑰,即可加入這些 bucket 的檢視畫面。

使用追蹤記錄 ID 彙整追蹤記錄和記錄資料

下列查詢會使用時距和追蹤記錄 ID,聯結記錄和追蹤記錄資料:

SELECT
  T.trace_id,
  T.span_id,
  T.name,
  T.start_time,
  T.duration_nano,
  L.log_name,
  L.severity,
  L.json_payload
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans` AS T
JOIN
  `PROJECT_ID.LOCATION._Default._AllLogs` AS L
ON
  -- Join log and trace data by both the span ID and trace ID.
  -- Don't join only on span ID, this field isn't globally unique.
  T.span_id = L.span_id
  -- A regular expression is required because the storage format of the trace ID
  -- differs between a log view and a trace view.
  AND T.trace_id = REGEXP_EXTRACT(L.trace, r'/([^/]+)$')
WHERE T.duration_nano > 1000000
LIMIT 10

查詢的回應會列出追蹤記錄和時距 ID,方便您個別查詢這些 ID,以收集更多資訊。此外,結果會列出記錄項目的嚴重程度和 JSON 酬載。

後續步驟

如需 SQL 參考說明文件或其他範例,請參閱下列文件: