本文档包含一些示例查询,这些查询专门用于查询存储在 Google Cloud 项目中的轨迹数据。
SQL 语言支持
Log Analytics 页面中使用的查询支持 GoogleSQL 函数,但有一些例外情况。
通过 Log Analytics 页面发出的 SQL 查询不支持以下 SQL 命令:
- DDL 和 DML 命令
- JavaScript 用户定义的函数
- BigQuery ML 函数
- SQL 变量
仅当您使用 BigQuery Studio 和 Looker Studio 页面或 bq 命令行工具查询关联的数据集时,系统才支持以下各项:
- JavaScript 用户定义的函数
- BigQuery ML 函数
- SQL 变量
最佳做法
如需设置查询的时间范围,我们建议您使用时间范围选择器。例如,如需查看过去一周的数据,请从时间范围选择器中选择过去 7 天。您还可以使用时间范围选择器指定开始时间和结束时间、指定要查看的时间范围,以及更改时区。
如果您在 WHERE 子句中添加 start_time 字段,则不会使用时间范围选择器设置。以下示例使用 TIMESTAMP_SUB 函数过滤数据,该函数可让您指定从当前时间开始的回溯时间间隔:
WHERE
start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.-
如需获得加载 Log Analytics 页面、在跟踪记录数据上撰写、运行和保存私密查询所需的权限,请让管理员为您授予以下 IAM 角色:
-
Observability View Accessor (
roles/observability.viewAccessor) 在您要查询的可观测性视图上。此角色支持 IAM 条件,可让您将授予的权限限制为仅针对特定视图。如果您未为角色授予附加条件,则正文可以访问所有可观测性视图。 -
针对项目的 Observability Analytics User (
roles/observability.analyticsUser)。此角色包含保存和运行专用查询以及运行共享查询所需的权限。 -
项目的 Logs Viewer (
roles/logging.viewer) 角色。
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
-
Observability View Accessor (
如何使用本页面上的查询
-
在 Google Cloud 控制台中,前往 manage_search Log Analytics 页面:
如果您使用搜索栏查找此页面,请选择子标题为 Logging 的结果。
在查询窗格中,点击 code SQL,然后将查询复制并粘贴到 SQL 查询窗格中。
以下内容展示了查询
_AllSpans视图的FROM原因的格式:FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`FROM子句包含以下字段:- PROJECT_ID:项目的标识符。
- LOCATION:可观测性存储桶的位置。
_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
如需了解详情,请参阅条件表达式。
显示 span 延迟时间的第 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的 span,请使用以下子句:-- Matches spans that have a name field. WHERE name IS NOT NULL如需仅分析
name值为"POST"的 span,请使用以下子句:-- Matches spans whose name is POST. WHERE STRPOS(name, "POST") > 0如需仅分析
name包含值"POST"的 span,请将LIKE运算符与通配符搭配使用:-- Matches spans whose name contains POST. WHERE name LIKE "%POST%"
按整数数据类型过滤
字段 kind 是一个整数,其值介于 0 到 5 之间:
如需仅分析指定了
kind的 span,请使用以下子句:-- Matches spans that have field named kind. WHERE kind IS NOT NULL如需分析
kind值为 1 或 2 的 span,请使用以下子句:-- Matches spans whose kind value is 1 or 2. WHERE kind IN (1, 2)
按 RECORD 数据类型过滤
轨迹架构中的某些字段的数据类型为 RECORD。这些字段可以存储一个或多个数据结构,也可以存储相同数据结构的重复条目。
按状态或状态代码过滤
status 字段是数据类型为 RECORD 的字段的一个示例。此字段存储一个数据结构,其成员标记为 code 和 message。
如需仅在
status.code字段的值为1时分析 span,请添加以下子句:-- Matches spans that have a status.code field that has a value of 1. WHERE status.code = 1status.code字段以整数形式存储。如需分析
status字段不是EMPTY的 span,请添加以下子句:-- 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
按事件或链接过滤
events 和 links 字段以 RECORD 的数据类型存储,但这些字段是重复字段。
如需匹配至少包含一个事件的 span,请使用以下子句:
-- 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的事件的 span,请使用以下子句: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的 span,请使用以下子句:-- Matches spans where at least one attribute is specified. WHERE attributes IS NOT NULL如需仅分析属性键名为
component且值为"proxy"的 span,请使用以下子句:-- 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%'
对轨迹数据进行分组和汇总
本部分说明了如何对 span 进行分组和汇总。如果您未指定分组,但指定了聚合,则会输出一个结果,因为 SQL 会将满足 WHERE 子句的所有条目视为一个组。
每个 SELECT 表达式都必须包含在组字段中或进行汇总。
按开始时间对 span 进行分组
如需按开始时间对数据进行分组,请使用 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 文档和日期时间函数。
按状态代码统计 span 数
如需显示具有特定状态代码的 span 的数量,请运行以下查询:
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 的平均时长
如需显示按 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
按服务名称计算平均时长和百分位数
以下查询会计算每个服务的 span 数量和各种统计信息:
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 语句的结果,然后从合并后的数据中选择列。
如需联接视图,请注意以下限制:
-
视图的位置满足以下条件之一:
- 所有视图都位于同一位置。
- 所有视图都位于
global或us位置。
-
当存储资源使用客户管理的加密密钥 (CMEK) 时,必须满足以下条件之一:
- 使用 CMEK 的存储资源使用相同的 Cloud KMS 密钥。
- 使用 CMEK 的存储资源具有共同的祖先,该祖先指定了与存储资源位于同一位置的默认 Cloud KMS 密钥。
当一个或多个存储资源使用 CMEK 时,系统会使用通用 Cloud KMS 密钥或祖先的默认 Cloud KMS 密钥来加密联接生成的临时数据。
例如,假设您有两个位于同一位置的视图。然后,在满足以下任一条件时,您可以联接这些视图:
- 存储资源不使用 CMEK。
- 一个存储资源使用 CMEK,另一个不使用。
- 这两个存储资源都使用 CMEK,并且都使用相同的 Cloud KMS 密钥。
两个存储资源都使用 CMEK,但使用的密钥不同。不过,这些资源共用一个祖先,该祖先指定了一个与存储资源位于同一位置的默认 Cloud KMS 密钥。
例如,假设日志存储桶和可观测性存储桶的资源层次结构包含同一组织。如果为相应组织配置了 Cloud Logging 的默认资源设置和可观测性存储分区,且存储位置的默认 Cloud KMS 密钥相同,则可以联接这些存储分区中的视图。
使用轨迹 ID 联接轨迹数据和日志数据
以下查询使用 span ID 和 trace 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 和 span ID,您可以单独查询这些 ID 以收集更多信息。此外,结果还会列出日志条目和 JSON 载荷的严重程度。
后续步骤
如需查看 SQL 参考文档或其他示例,请参阅以下文档: