SQL 查詢示例

您可以在 Observability Analytics 中使用 SQL 查詢範例,分析記錄項目、擷取酬載欄位,以及匯總各項服務的記錄資料。您可以在 Google Cloud 控制台的「Observability Analytics」頁面,對已升級為使用 Observability Analytics 的記錄檔 bucket 執行這些查詢。如需更多範例,請參閱 logging-analytics-samples 和 security-analytics GitHub 存放區。如要瞭解 SQL 語法,或如何轉送及儲存記錄項目,請參閱「後續步驟」一節。

SQL 語言支援

「Observability Analytics」頁面中使用的查詢支援 GoogleSQL 函式,但有一些例外狀況。

使用「Observability Analytics」頁面發出的 SQL 查詢不支援下列 SQL 指令:

  • DDL 和 DML 指令
  • JavaScript user-defined function
  • BigQuery ML 函式
  • SQL 變數

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

  • JavaScript user-defined function
  • BigQuery ML 函式
  • SQL 變數

最佳做法

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

如果您在 WHERE 子句中加入 timestamp 欄位,系統就不會使用日期範圍選取器設定。以下範例說明如何依時間戳記篩選:

-- Matches log entries whose timestamp is within the most recent 1 hour.
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

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

事前準備

本節說明使用 Observability Analytics 前必須完成的步驟。

設定記錄檔 bucket

確認記錄檔 bucket 已升級為使用 Observability Analytics:

  1. 在 Google Cloud 控制台中,前往「Logs Storage」(記錄檔儲存空間) 頁面:

    前往「Logs Storage」(記錄檔儲存空間)

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

  2. 針對要查詢記錄檔檢視表的每個記錄檔 bucket,確認「可使用 Observability Analytics」欄顯示「開啟」。如果畫面上顯示「Upgrade」(升級),請按一下「Upgrade」(升級),然後完成對話方塊。

設定 IAM 角色和權限

本節說明使用 Observability Analytics 所需的 IAM 角色或權限:

  • 如要取得使用 Observability Analytics 和查詢記錄檢視表所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

    • 如要查詢 _Required 和 _Default 記錄檔 bucket,請按照下列步驟操作: 記錄檢視器 (roles/logging.viewer)
    • 如要查詢專案中的所有記錄檢視表:記錄檢視表存取子 (roles/logging.viewAccessor)

    如要限制主體只能存取特定記錄檢視,您可以在專案層級授予「記錄檢視存取子」角色時,新增 IAM 條件,或是在記錄檢視的政策檔案中新增 IAM 繫結。詳情請參閱「控管記錄檔檢視畫面的存取權」。

    這些權限與在「Logs Explorer」頁面查看記錄項目所需的權限相同。如要瞭解查詢使用者定義 bucket 上的檢視表,或查詢 _Default 記錄檔 bucket 的 _AllLogs 檢視表時,需要哪些其他角色,請參閱「Cloud Logging 角色」。

  • 如要取得查詢分析檢視表所需的權限,請要求管理員授予您專案的 Observability Analytics 使用者 (roles/observability.analyticsUser) IAM 角色。

如何使用這個頁面的查詢

  1. 在 Google Cloud 控制台中,前往 「Observability Analytics」(觀測能力分析) 頁面:

    前往「Observability Analytics」(觀測能力分析) 頁面

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

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

    複製查詢前,請在 FROM 子句中替換下列欄位

    • PROJECT_ID:專案 ID。
    • LOCATION:記錄檔檢視表或分析檢視表的位置。
    • BUCKET_ID:記錄檔 bucket 的名稱或 ID。
    • LOG_VIEW_ID:記錄檔檢視畫面的 ID,長度上限為 100 個字元,且只能包含英文字母、數字、底線和連字號。

    以下是記錄檢視的 FROM 子句格式:

    FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`

    本頁面的記錄範例會查詢記錄檢視。如要查詢分析檢視表,請使用下列路徑格式:`analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`。在上述運算式中,PROJECT_ID 是專案 ID,LOCATION 和 ANALYTICS_VIEW_ID 則是分析檢視表的位置和名稱。

如要在「BigQuery Studio」頁面使用本文件中的查詢,或使用 bq 指令列工具,請編輯 FROM 子句,並輸入連結的 BigQuery 資料集路徑。舉例來說,如要查詢專案 myproject 中名為 mydataset 的連結 BigQuery 資料集上的 _AllLogs 檢視表,路徑為 myproject.mydataset._AllLogs。

常見用途

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

顯示預設記錄檔 bucket 中的記錄項目

如要查詢 _Default bucket,請執行下列查詢:

SELECT
  timestamp, severity, resource.type, log_name, text_payload, proto_payload, json_payload
FROM
  `PROJECT_ID.LOCATION._Default._AllLogs`
-- Limit to 1000 entries
LIMIT 1000

依規則運算式擷取欄位值

如要使用規則運算式從字串中擷取值,請使用 REGEXP_EXTRACT 函式:

SELECT
  -- Display the timestamp, and the part of the name that begins with test.
  timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Get the value of jobName, which is a subfield in a JSON structure.
  JSON_VALUE(json_payload.jobName) IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20

詳情請參閱 REGEXP_EXTRACT 說明文件。

如要比對子字串 (例如前一個查詢),使用 CONTAINS_SUBSTR 函式可提高查詢效率。

篩選記錄項目

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

依酬載類型篩選記錄項目

記錄項目可採用三種酬載類型之一。如要依酬載類型篩選記錄項目,請使用下列其中一個子句:

  • 文字酬載

    -- Matches log entries that have a text payload.
    WHERE text_payload IS NOT NULL
    
  • JSON 酬載

    -- Matches log entries that have a JSON payload.
    WHERE json_payload IS NOT NULL
    
  • Proto 酬載

    -- Matches log entries that have a proto payload.
    -- Because proto_payload has a data type of RECORD, this statement tests
    -- whether a mandatory subfield exists.
    WHERE proto_payload.type IS NOT NULL
    

在查詢結果中,json_payload 和 proto_payload 欄位都會以 JSON 格式呈現,您可以瀏覽這些欄位。

依時間戳記篩選記錄資料

如要依時間戳記篩選記錄項目,建議使用時間範圍選取器。不過,您也可以在 WHERE 子句中指定 timestamp:

-- Matches log entries whose timestamp is within the most recent hour
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

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

依資源篩選

如要依資源篩選記錄資料,請在 WHERE 子句中加入 resource.type 陳述式:

-- Matches log entries whose resource type is gce_instance
WHERE resource.type = "gce_instance"

依據嚴重性篩選

如要依嚴重性篩選記錄資料,請在 WHERE 子句中新增 severity 陳述式:

-- Matches log entries whose severity is INFO or ERROR
WHERE severity IS NOT NULL AND severity IN ('INFO', 'ERROR')

您也可以依 severity_number (整數) 篩選記錄項目。例如,下列子句會比對嚴重性等級至少為 NOTICE 的所有記錄項目:

-- Matches log entries whose severity level is at least NOTICE
WHERE severity_number IS NOT NULL AND severity_number > 200

如要瞭解列舉值,請參閱 LogSeverity。

依記錄檔名稱篩選

如要依記錄檔名稱篩選記錄檔資料,請在 WHERE 子句中加入 log_name 或 log_id 陳述式:

  • 記錄名稱會指定資源路徑:

    -- Matches log entries that have the following log ID.
    WHERE log_name="projects/cloud-logs-test-project/logs/cloudaudit.googleapis.com%2Factivity"
    
  • 記錄 ID 會省略資源路徑:

    -- Matches log entries that have the following log id.
    WHERE log_id = "cloudaudit.googleapis.com/data_access"
    

依據資源標籤篩選記錄項目

資源標籤會以 JSON 結構儲存。如要依 JSON 結構中的欄位值篩選,請使用 JSON_VALUE 函式:

SELECT
  timestamp, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries whose resource type is gce_instance and whose zone is
  -- us-central1-f. Because resource has data type JSON, you must use JSON_VALUE
  -- to get the value for subfields, like zone.
  resource.type = "gce_instance" AND
  JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC

上述查詢會依據資源標籤的格式,因為這些標籤會儲存在記錄項目中。以下是資源欄位的範例:

{
   type: "gce_instance"
   labels: {
      instance_id: "1234512345123451"
      project_id: "my-project"
      zone: "us-central1-f"
   }
}

如要瞭解可擷取及轉換 JSON 資料的所有函式,請參閱「JSON 函式」。

依 HTTP 要求篩選

如要只查詢含有 HTTP 要求欄位的記錄項目,請使用下列子句:

-- Matches log entries that have a HTTP request_method field.
-- Don't compare http_request to NULL. This field has a data type of RECORD.
WHERE http_request.request_method IS NOT NULL

您也可以使用 IN 陳述式:

-- Matches log entries whose HTTP request_method is GET or POST.
WHERE http_request.request_method IN ('GET', 'POST')

依 HTTP 狀態篩選

如要只查詢含有 HTTP 狀態的記錄項目,請使用下列子句:

-- Matches log entries that have an http_request.status field.
WHERE http_request.status IS NOT NULL

依 JSON 資料類型中的欄位篩選

如要僅在 JSON 資料類型欄位的子欄位具有特定值時查詢記錄項目,請使用 JSON_VALUE 函式擷取該值:

-- Compare the value of the status field to NULL.
WHERE JSON_VALUE(json_payload.status) IS NOT NULL

前一個子句與下列子句略有不同:

-- Compare the status field to NULL.
WHERE json_payload.status IS NOT NULL

第一個子句會測試狀態欄位的值是否為 NULL。第二個子句會測試狀態欄位是否存在。假設記錄檢視包含兩個記錄項目。記錄項目的 json_payload 欄位格式如下:

{
    status: {
        measureTime: "1661517845"
    }
}

另一個記錄項目的 json_payload 欄位則有不同的結構:

{
    @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jobName: "projects/my-project/locations/us-central1/jobs/test1"
    relativeUrl: "/food=cake"
    status: "NOT_FOUND"
    targetType: "APP_ENGINE_HTTP"
}

子句 WHERE json_payload.status IS NOT NULL 與這兩個記錄項目都相符。不過,WHERE JSON_VALUE(json_payload.status) IS NOT NULL 子句只會比對第二個記錄項目。

將記錄項目分組及匯總

本節以前述範例為基礎,說明如何將記錄項目分組及匯總。如果未指定分組,但指定了匯總,則會列印一項結果,因為 SQL 會將符合 WHERE 子句的所有資料列視為一個群組。

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

依時間戳記將記錄項目分組

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

SELECT
  -- Truncate the timestamp by hour.
  TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
  JSON_VALUE(json_payload.status) AS status,
  -- Count the number log entries in each group.
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries that have a status field whose value isn't NULL.
  json_payload IS NOT NULL AND JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY
  -- Group by hour and status
  hour,status
ORDER BY hour ASC

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

依資源將記錄項目分組

下列查詢說明如何依資源類型將記錄項目分組,然後計算各組的記錄項目數量:

SELECT
   -- Count the number of log entries for each resource type
   resource.type, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY resource.type
LIMIT 100

依嚴重性將記錄項目分組

下列查詢說明如何依嚴重性將記錄項目分組,然後計算各組的記錄項目數量:

SELECT
  -- Count the number of log entries for each severity.
  severity, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100

依log_id將記錄項目分組

下列查詢說明如何依記錄 ID 將記錄項目分組,然後計算每個群組中的記錄項目數量:

SELECT
  -- Count the number of log entries for each log ID.
  log_id, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100

計算每個網址的 HTTP 要求平均延遲時間

下列查詢說明如何依 HTTP 要求網址和位置將記錄項目分組,然後計算各組的記錄項目數量:

SELECT
  -- Compute the average latency for each group. Because the labels field has a
  -- data type of JSON, use JSON_VALUE to get the value of checker_location.
  JSON_VALUE(labels.checker_location) AS location,
  AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries when the request_method field is GET.
  http_request IS NOT NULL AND http_request.request_method IN ('GET')
GROUP BY
  -- Group by request URL and location
  http_request.request_url, location
ORDER BY location
LIMIT 100

計算子網路測試傳送的平均位元組數

下列查詢說明如何依資源標籤中指定的位置,將記錄項目分組,然後計算各組的記錄項目數量:

SELECT
  -- Compute the average number of bytes sent per location. Because labels has
  -- a data type of JSON, use JSON_VALUE to get the value of the location field.
  -- bytes_sent is a string. Must cast to a FLOAT64 before computing average.
  JSON_VALUE(resource.labels.location) AS location,
  AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  resource.type = "gce_subnetwork" AND json_payload IS NOT NULL
GROUP BY
  -- Group by location
  location
LIMIT 100

詳情請參閱「JSON 函式」和「轉換函式」。

計算欄位符合特定模式的記錄項目數量

如要傳回符合規則運算式的子字串,請使用 REGEXP_EXTRACT 函式:

SELECT
  -- Extract the value that begins with test.
  -- Count the number of log entries for each name.
  REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20

如需更多範例,請參閱 REGEXP_EXTRACT 說明文件。

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

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

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

下列查詢只會保留欄位與「35.193.12.15」完全相符的資料列:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- The use of backticks prevents the string from being tokenized.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20

如果查詢字串中省略反引號,系統會根據 SEARCH 說明文件中定義的規則分割查詢字串。舉例來說,執行下列陳述式時,查詢字串會分割成四個權杖:「35」、「193」、「12」和「15」:

  SEARCH(t,"35.193.12.15")

如果單一欄位與所有四個權杖相符,先前的 SEARCH 陳述式就會比對資料列。權杖的順序不影響結果。

您可以在查詢中加入多個 SEARCH 陳述式。舉例來說,在先前的查詢中,您可以將記錄 ID 的篩選器替換為類似下列的陳述式:

  SEARCH(t,"`cloudaudit.googleapis.com/data_access`")

前一個陳述式會搜尋記錄檢視表中記錄項目的每個欄位,而原始陳述式只會搜尋記錄項目的 log_id 欄位。

如要在多個欄位中執行多項搜尋,請以空格分隔個別字串。舉例來說,下列陳述式會比對欄位包含「Hello World」、「happy」和「days」的資料列:

  SEARCH(t,"`Hello World` happy days")

最後,您可以搜尋特定欄位,而非整個資料表。舉例來說,下列陳述式只會搜尋名為 text_payload 和 json_payload 的資料欄:

   SEARCH((text_payload, json_payload) ,"`35.222.132.245`")

如要瞭解 SEARCH 函式的參數處理方式,請參閱 BigQuery 參考頁面「搜尋函式」。

舉例來說,下列查詢會擷取所有資料存取稽核記錄項目,其中包含特定 IP 位址,且時間戳記在特定日期範圍內。最後,查詢會排序結果,然後顯示 20 個最舊的結果:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- CONTAINS_SUBSTR performs a contains-test.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20

查詢多個檢視表

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

如要彙整檢視表,請遵守下列限制:

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

    • 所有檢視畫面的位置都相同。
    • 所有檢視表都位於 global 或 us 位置。
  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 彙整兩個記錄檢視

如要合併兩個資料表的資訊,請使用下列其中一個 join 運算子:

SELECT
  -- Do an inner join on two tables by using the span ID and trace ID.
  -- Don't join only by span ID, as this field isn't globally unique.
  -- From the first view, show the timestamp, severity, and JSON payload.
  -- From the second view, show the JSON payload.
  a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1` a
JOIN  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2` b
ON
  a.span_id = b.span_id AND
  a.trace = b.trace
LIMIT 100

使用 union 陳述式查詢兩個記錄檢視

如要合併兩個以上 SELECT 陳述式的結果,並捨棄重複的資料列,請使用 UNION 運算子。如要保留重複的資料列,請使用 UNION ALL 運算子:

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
-- Create a union of two log views
FROM(
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1`
  UNION ALL
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2`
)
-- Sort the union by timestamp.
ORDER BY timestamp ASC
LIMIT 100

移除重複的記錄項目

Observability Analytics 不會在執行查詢前移除重複的記錄項目。這與使用 Logs Explorer 查詢記錄項目時的行為不同,後者會比較記錄名稱、時間戳記和插入 ID 欄位,藉此移除重複項目。

您可以使用資料列層級驗證,移除重複的記錄項目。

詳情請參閱「疑難排解:Observability Analytics 結果中有重複的記錄項目」。

後續步驟

如要瞭解如何轉送及儲存記錄項目,請參閱下列文件:

如需 SQL 參考文件,請參閱下列文件: