MQL 查询示例

本文档通过示例介绍了 Monitoring Query Language (MQL)。但是,它没有尝试涵盖语言的所有方面。Monitoring Query Language 参考文档对 MQL 进行了全面介绍。

如需了解基于 MQL 的提醒政策,请参阅使用 MQL 的提醒政策

您可以通过多种形式编写特定查询;所用语言灵活多样;熟悉语法之后,您还可以使用很多快捷方式。如需了解详情,请参阅严格形式查询

准备工作

如需在使用 Metrics Explorer 时访问代码编辑器,请执行以下操作:

  1. 在 Google Cloud 控制台的导航面板中,选择 Monitoring,然后选择  Metrics Explorer

    进入 Metrics Explorer

  2. 在查询构建器窗格的工具栏中,选择名为  MQL PromQL 的按钮。
  3. 验证已在语言切换开关中选择 MQL。语言切换开关位于同一工具栏中,用于设置查询的格式。

如需运行查询,请将查询粘贴到编辑器中,然后点击运行查询。 如需了解此编辑器,请参阅使用 MQL 的代码编辑器

对 Cloud Monitoring 的概念(包括指标类型、受监控的资源类型和时序)有一定的了解。如需了解这些概念,请参阅指标、时序和资源

数据模型

MDQ 查询检索并操作 Cloud Monitoring 时间序列数据库中的数据。本部分介绍与此数据库相关的一些概念和术语。如需了解详情,请参阅参考主题数据模型

每个时序都源自一种类型的受监控的资源,并且每个时序都会收集一种指标类型的数据。受监控的资源描述符定义了受监控的资源类型。同样,指标描述符定义了指标类型。例如,资源类型可能是 gce_instance、Compute Engine 虚拟机 (VM),而指标类型可能是 compute.googleapis.com/instance/cpu/utilization,即 Compute Engine 虚拟机的 CPU 利用率。

这些描述符还指定了一组标签,用于收集有关指标的其他属性信息或资源类型。例如,资源通常具有 zone 标签,用于记录资源的地理位置。

系统会为一对指标描述符和受监控的资源描述符中标签值的每个组合创建一个时序。

您可以在受监控的资源列表中找到资源类型的可用标签,例如 gce_instance。要查找指标类型的标签,请参阅指标列表;例如,请参阅 Compute Engine 中的指标

Cloud Monitoring 数据库将来自特定指标和资源类型的时序存储在一个表中。指标和资源类型作为表的标识符。此 MQL 查询会提取 Compute Engine 实例的 CPU 利用率的时间序列表:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization

指标和资源标签值的每个唯一组合在表中都有一个时序。

MQL 查询检索这些表中的时间序列数据并将其转换为输出表。这些输出表可以传递到其他操作中。例如,您可以通过将检索到的表作为输入传送到 filter 操作,隔离由特定区域或区域集的资源写入的时序:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter zone =~ 'us-central.*'

上述查询会生成表格,仅包含来自 us-central 开头的可用区中的资源的时序。

MQL 查询会将一个操作的输出作为输入传递给下一个操作。通过这种基于表的方法,您可以将操作链接在一起,通过过滤、选择以及其他熟悉的数据库操作(如内部和外部联接)来处理此数据。您还可以对时序中的数据运行各种函数,因为数据从一个操作传递到另一个操作。

Monitoring Query Language 参考中全面介绍了 MQL 中可用的操作和函数。

查询结构

查询由一个或多个operations组成。操作链接或连接在一起,以便一个操作的输出是下一个操作的输入。因此,查询的结果取决于操作的顺序。您可以执行以下操作:

  • 使用 fetch 或其他选择操作启动查询。
  • 使用多个连接在一起的操作构建查询。
  • 通过 filter 操作选择信息子集。
  • 使用 group_by 操作汇总相关信息。
  • 使用 topbottom 操作查看离群值。
  • 将多个查询与 { ; }join 操作相结合。
  • 使用 value 操作和函数计算比率和其他值。

并非所有查询都使用所有这些选项。

这些示例仅引入了一些可用的操作和函数。如需详细了解 MQL 查询的结构,请参阅参考主题查询结构

这些示例并未指定您可能会看到的两个内容:时间范围和校准。以下部分将解释原因。

时间范围

使用代码编辑器时,图表设置定义查询的时间范围。默认情况下,图表的时间范围设置为 1 小时。

如需更改图表的时间范围,请使用时间范围选择器。例如,如果您想查看过去一周的数据,请从时间范围选择器中选择过去 1 周。您还可以指定开始时间和结束时间,或者指定查看各个时段的时间。

如需详细了解代码编辑器中的时间范围,请参阅时间范围、图表和代码编辑器

对齐

这些示例中使用的许多操作(如 joingroup_by 操作)取决于表中定期发生的所有时序点。使所有的点按常规时间戳排列的操作称为alignment。通常,对齐是隐式完成的,此处的所有示例均未显示。

如果需要,MQL 会自动为 joingroup_by 操作校准表,但 MQL 也让您可以进行明式校准。

  • 如需了解校准的一般信息,请参阅校准:序列内集合

  • 如需了解 MQL 中校准的相关信息,请参阅参考主题校准。您可以使用 alignevery 操作明确控制校准。

提取和过滤数据

MQL 查询刚开始为检索和选择或过滤数据。本部分介绍了使用 MQL 进行一些基本的检索和过滤。

检索时间序列数据

查询始终以 fetch 操作开头,该操作会从 Cloud Monitoring 中检索时间序列。

最简单的查询包含一个 fetch 操作和一个用于标识要提取的时序的参数,如下:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization

该参数包含一个受监控的资源类型 gce_instance,一对冒号字符 :: 和一个指标类型 compute.googleapis.com/instance/cpu/utilization

此查询会检索 Compute Engine 实例针对指标类型 compute.googleapis.com/instance/cpu/utilization 写入的时序,记录这些实例的 CPU 利用率。

如果您通过 Metrics Explorer 中的代码编辑器运行查询,则会获得显示所请求的每个时序的图表:

此图表显示了 Compute Engine 实例的 CPU 利用率数据。

每个请求的时序在图表上显示为一条线。每个时序包括此项目中一个虚拟机实例的 CPU 利用率指标所表示的时间值列表。

在 Cloud Monitoring 使用的后端存储空间中,时序存储在表中。fetch 操作将指定受监控资源和指标类型的时序整理到表中,然后返回该表。返回的数据显示在图表中。

fetch 参考页面上介绍了 fetch 操作及其参数。如需详细了解操作生成的数据,请参阅时序的参考页面。

过滤操作

查询通常由多个操作构成。最简单的组合是使用竖线操作符 | 将一个操作的输出传送到下一个操作的输入。以下示例演示了如何使用竖线将表输入到过滤操作:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter instance_name =~ 'gke.*'

此查询将由上一个示例中显示的 fetch 操作返回的表传送到 filter 运算,该运算将其作为计算结果为布尔值的表达式。在此示例中,表达式表示“instance_namegke 开头”。

filter 操作接受输入表、移除过滤条件为 false 的时序,并输出生成的表。以下屏幕截图显示了生成的图表:

图表显示按“GKE”过滤的结果。

如果您没有任何以 gke 开头的实例名称,请在尝试此查询之前更改过滤条件。例如,如果您的虚拟机实例名称的开头有 apache,请使用以下过滤条件:

 | filter instance_name =~ 'apache.*'

系统会针对每个输入时序对 filter 表达式进行一次计算。如果表达式的计算结果为 true,则该时序将包含在输出中。在此示例中,过滤条件表达式对每个时序的 instance_name 标签执行正则表达式匹配 =~。如果标签的值与正则表达式 'gke.*' 匹配,则时序将包含在输出中。如果不是,则从输出中移除时序。

如需详细了解过滤条件,请参阅 filter 参考页面filter 谓语可以是返回布尔值的任意表达式;有关详情,请参见表达式

分组和汇总

分组容许您按特定维度对时序进行分组。聚合将组中的所有时序组合为一个输出时序。

以下查询会过滤初始 fetch 操作的输出,以仅保留以 us-central 开头的地区资源中的时序。然后,它按地区对时序进行分组,并使用 mean 聚合对其进行组合。

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter zone =~ 'us-central.*'
| group_by [zone], mean(val())

通过 group_by 操作生成的表每个地区都有一个时序。以下屏幕截图显示了生成的图表:

图表显示按地区分组的已过滤提取。

group_by 操作采用两个参数,以逗号分隔 ,。这些参数决定了精确分组行为。在示例 group_by [zone], mean(val()) 中,参数的作用如下:

  • 第一个参数 [zone] 是时序表达式,用于确定时序的分组。在此示例中,它指定用于分组的标签。分组步骤会将具有相同输出 zone 值的所有输入时序收集到一个组中。在此示例中,表达式从一个可用区的 Compute Engine 虚拟机收集时序。

    输出时序仅具有 zone 标签,其值从组中的输入时序中复制。输入时序中的其他标签将从输出时序中移除。

    映射表达式的功能远不止列表标签;如需了解详情,请参阅 map 参考页面

  • 第二个参数 mean(val()) 用于确定如何将每个组中的时序组合或aggregated为一个输出时序。组的输出时序中的每个点都是从组中的所有输入时序中聚合具有相同时间戳的点的结果。

    聚合函数(在此示例中为 mean)确定聚合值。val() 函数返回要聚合的点,聚合函数应用于这些点。在此示例中,您将获得每个输出时间点中地区虚拟机的 CPU 平均利用率。

    该表达式 mean(val())聚合表达式的示例。

group_by 操作始终会结合分组和聚合。如果您指定了分组但省略了聚合参数,则 group_by 将使用默认聚合 aggregate(val()),它会为数据类型选择适当的函数。如需查看默认聚合函数的列表,请参阅 aggregate

group_by 与基于日志的指标搭配使用

假设您创建了一个基于分布日志的指标,用于从一组长条目(包括如下字符串)中提取处理的数据点数量:

... entry ID 1 ... Processed data points 1000 ...
... entry ID 2 ... Processed data points 1500 ...
... entry ID 3 ... Processed data points 1000 ...
... entry ID 4 ... Processed data points 500 ...

如需创建显示所有已处理数据点计数的时序,请使用如下所示的 MQL:

fetch global
| metric 'logging.googleapis.com/user/METRIC_NAME'
| group_by [], sum(sum_from(value))

如需创建基于日志的分布指标,请参阅配置分布指标

从组中排除列

您可以在映射中使用 drop 修饰符从组中排除列。例如,Kubernetes core_usage_time 指标有六列:

fetch k8s_container :: kubernetes.io/container/cpu/core_usage_time
| group_by [project_id, location, cluster_name, namespace_name, container_name]

如果您不需要对 pod_name 进行分组,则可以使用 drop 将其排除:

fetch k8s_container :: kubernetes.io/container/cpu/core_usage_time
| group_by drop [pod_name]

选择时序

本部分中的示例说明了从输入表中选择特定时间序列的方法。

选择顶部或底部的时序

要查看项目中 CPU 利用率最高的三个 Compute Engine 实例的时序数据,请输入以下查询:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3

以下屏幕截图显示了一个项目的结果:

图表显示了 3 个利用率最高的时间序列。

您可以通过将 top 替换为 bottom 来检索 CPU 利用率最低的时序。

top 操作会输出一个表,其中包含从输入表中选择的指定时序数。输出中包含的时序具有时序中某些方面的最大值。

由于此查询未指定对时序进行排序的方式,因此它会返回最近点的值最大的那些时序。如需指定如何确定哪些时序具有最大值,您可以为 top 操作提供参数。例如,上述查询等效于以下查询:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3, val()

val() 表达式选择它所应用到的每个时序中最近的点的值。因此,查询会返回最近点的最大值。

您可以提供表达式,用于对时序中的某个点或所有点进行聚合,从而提供排序值。以下是过去 10 分钟内所有分值的平均值:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3, mean(val()).within(10m)

如果未使用 within 函数,则 mean 函数会应用于时序中所有显示点的值。

bottom 操作的工作原理类似。以下查询使用 max(val()) 查找每个时序中最大值点的值,然后选择该值的最小值对应的三个时序:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| bottom 3, max(val())

以下屏幕截图显示了一个图表,其中显示了具有最小峰值的流:

图表显示了 3 个利用率最高的时间序列。

排除时序中的前 n 个结果

假设您有许多 Compute Engine 虚拟机实例。其中一些实例消耗的内存比大多数实例要多得多,这些离群值使得更难查看大型实例组中的使用模式。CPU 利用率图表如下所示:

图表显示许多 CPU 利用率线,以及几个离群值。

您想要从图表中排除这三个离群值,以便更清楚地查看规模较大的组中的模式。

如需在检索 Compute Engine CPU 利用率的时序的查询中排除前三个时序,请使用 top 表操作标识时序,使用 outer_join 表操作从结果中排除所标识的时序。您可以使用以下查询:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| {
    top 3 | value [is_default_value: false()]
  ;
    ident
  }
| outer_join true(), _
| filter is_default_value
| value drop [is_default_value]

fetch 操作会返回一个时序表,其中包含所有实例的 CPU 利用率。然后,此表被处理成两个结果表:

  • top n 表操作会输出一个表,其中包含具有最大值的 n 个时间序列。n在本示例中,n = 3。n生成的表包含要排除的三个时间序列。

    然后,包含前三个时序的表通过管道传送到 value 表操作。此操作会为前三个表中的每个时序添加另一列。对于前三个表中所有时序,为 is_default_value 列指定布尔值 false

  • ident 操作返回流入其中的同一表:CPU 利用率时序的原始表。此表中的任何时间序列都没有 is_default_value 列。

然后,前三个表和原始表通过管道传送到 outer_join 表操作。前三个表是联接中的左表,提取的表是联接中的右表。外联接设置为提供值 true 作为要联接的行中不存在的任何字段的值。外部联接的结果是一个合并表,其中前三表中的行使 is_default_value 列的值为 false,原始表中不在前三表中的所有行都获得值为 trueis_default_value 列。

然后,通过联接生成的表会传递给 filter 表操作,该操作会过滤掉 is_default_value 列中值为 false 的行。生成的表包含最初提取的表中的行,不含前三表中的行。该表包含预期的时序集,并添加了 is_default_column

最后一步是删除联接添加的列 is_default_column,使输出表中的列与最初提取的表相同。

以下屏幕截图显示了上述查询的图表:

图表显示许多 CPU 利用率线,并排除了离群值。

您可以通过将 top n 替换为 bottom n,创建查询以排除 CPU 利用率最低的时序。

如果您想要设置提醒,但不希望离群值不断触发提醒,那么排除离群值会非常有用。以下提醒查询使用与前一查询相同的排除逻辑,在排除前两个 Pod 后监控一组 Kubernetes Pod 的 CPU 限额利用率:

fetch k8s_container
| metric 'kubernetes.io/container/cpu/limit_utilization'
| filter (resource.cluster_name == 'CLUSTER_NAME' &&
          resource.namespace_name == 'NAMESPACE_NAME' &&
          resource.pod_name =~ 'POD_NAME')
| group_by 1m, [value_limit_utilization_max: max(value.limit_utilization)]
| {
    top 2 | value [is_default_value: false()]
  ;
    ident
  }
| outer_join true(), _
| filter is_default_value
| value drop [is_default_value]
| every 1m
| condition val(0) > 0.73 '1'

从分组中选择顶部或底部

topbottom 表操作会从整个输入表中选择时序。top_bybottom_by 操作将表中的时序分组,然后从每个组中选择一定数量的时序。

以下查询选择每个区域中峰值最高的时序:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top_by [zone], 1, max(val())

图表按区域显示最大峰值。

[zone] 表达式表示某个组由 zone 列具有相同值的时序组成。top_by 中的 1 表示从每个地区的组中选择的时序数量。max(val()) 表达式会在每个时序中查找图表时间范围内的最大值。

您可以使用任何聚合函数来代替 max。例如,以下使用 mean 聚合器,并使用 within 指定 20 分钟的排序范围。它会选择每个地区中的前两个时序:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top_by [zone], 2, mean(val()).within(20m)

图表会在 20 分钟内按地区显示两个最大平均值。

在前面的示例中,可用区 us-central-c 中只有一个实例,因此只返回一个时序;群组中没有“前 2 名”

将所选项目与 union 结合使用

您可以结合使用 topbottom 等选择操作来创建同时显示这两者的图表。例如,以下查询返回具有最大值的单个时序和具有最小值的单个时序:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| {
    top 1, max(val())
  ;
    bottom 1, min(val())
  }
| union

生成的图表显示了两行,一行包含最高值,一行包含最小值:

图表会显示包含最高值和最低值的时序。

您可以使用大括号 { } 来指定操作序列,每个操作生成一个时间序列表作为输出。各个操作以英文分号 ; 分隔。

在此示例中,fetch 操作返回一个表,传送到序列中的两个操作:top 操作和 bottom 操作。每项操作都会生成基于同一输入表的输出表。然后,union 操作会将两个表合并为一个表,该表将显示在图表上。

如需详细了解使用 { } 的顺序排序,请参阅参考主题查询结构

将时序与一个标签的不同值合并在一起

假设您有多个适用于同一指标类型的时序,并希望将其中几个时序组合在一起。如果您想根据单个标签的值进行选择,则无法使用 Metrics Explorer 中的查询构建器界面创建查询。您需要根据同一标签的两个或多个不同值进行过滤,但查询构建器界面要求时序与要选择的所有过滤条件匹配:标签匹配是一项 AND 测试。任何时序的同一标签都不能具有两个不同的值,但您无法在查询构建器中为过滤条件创建 OR 测试。

以下查询会检索两个特定 Compute Engine 实例的 Compute Engine instance/disk/max_read_ops_count 指标的时序,并以 1 分钟为间隔调整输出:

fetch gce_instance
| metric 'compute.googleapis.com/instance/disk/max_read_ops_count'
| filter (resource.instance_id == '1854776029354445619' ||
          resource.instance_id == '3124475757702255230')
| every 1m

以下图表显示了此查询的结果:

图表显示了按相同标签值选择的两个时序。

如果要查找这两个虚拟机的最大 max_read_ops_count 值的总和,并将它们相加,您可以执行以下操作:

  • 使用 group_by 表运算符、指定相同的 1 分钟校准时间段并使用 max 聚合器对该时间段进行聚合,以在输出表中创建一个名为 max_val_of_read_ops_count_max 的列,从而查找每个时序的最大值。
  • max_val_of_read_ops_count_max 列使用 group_by 表运算符和 sum 聚合器,计算时序的总和。

下面显示了该查询:

fetch gce_instance
| metric 'compute.googleapis.com/instance/disk/max_read_ops_count'
| filter (resource.instance_id == '1854776029354445619' ||
          resource.instance_id == '3124475757702255230')
| group_by 1m, [max_val_of_read_ops_count_max: max(value.max_read_ops_count)]
| every 1m
| group_by [], [summed_value: sum(max_val_of_read_ops_count_max)]

以下图表显示了此查询的结果:

图表显示按同一标签的值选择的两个时序的总和。

计算跨时间和数据流的百分位统计信息

如需为每个数据流单独计算滑动窗口上的百分位数据流值,请使用临时 group_by 操作。例如,以下查询计算流在 1 小时的滑动窗口中的第 99 百分位值:

fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization
| group_by 1h, percentile(val(), 99)
| every 1m

如需计算多个数据流在某个时间点(而不是一个数据流中跨时间的同一百分位数)统计值,请使用空间 group_by 操作:

fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization
| group_by [], percentile(val(), 99)

计算比率

假设您已构建在 Compute Engine 虚拟机实例上运行的分布式 Web 服务并使用 Cloud Load Balancing

您希望看到一个图表,其中显示返回 HTTP 500 响应(内部错误)的请求数占请求总数的比例;也就是请求失败的比率。本部分介绍了计算请求失败比率的几种方法。

Cloud Load Balancing 使用受监控的资源类型 http_lb_rulehttp_lb_rule 受监控的资源类型具有 matched_url_path_rule 标签,记录规则定义的网址前缀;默认值为 UNMATCHED

loadbalancing.googleapis.com/https/request_count 指标类型具有 response_code_class 标签。此标签用于采集响应代码类。

使用 outer_joindiv

以下查询确定项目中每个 http_lb_rule 受监控的资源中的 matched_url_path_rule 标签的每个值的 500 响应。然后,它会将此故障计数表与原始表连接,原始表包含所有响应计数,并除以值以显示故障响应与总响应的比率:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| {
    filter response_code_class = 500
  ;
    ident
  }
| group_by [matched_url_path_rule]
| outer_join 0
| div

以下图表显示了一个项目的结果:

图表显示了连接后的请求失败总比率。

图表上折线周围的阴影区域是最小/最大条带;如需了解详情,请参阅最小/最大条带

fetch 操作会输出一个时间序列表,其中包含所有负载平衡查询的请求计数。此表通过大括号中的两个操作序列,以两种方式进行处理:

  • filter response_code_class = 500 仅输出具有值为 500response_code_class 标签的时序。生成的时序会对使用 HTTP 5xx(错误)响应代码的请求进行计数。

    此表格是比率的分子。

  • identidentity 操作会输出其输入,因此该操作会返回最初提取的表。即包含对每个响应代码计数的时序的表。

    下表是比率的分母。

分别由 filterident 操作生成的分子表和分母表由 group_by 操作分开处理。group_by 操作按 matched_url_path_rule 标签的值对每个表中的时序进行分组,并对标签的每个值的计数求和。此 group_by 操作未明确声明聚合函数,因此将使用默认值 sum

  • 对于已过滤的表,group_by 结果是针对每个 matched_url_path_rule 值返回 500 响应的请求数量。

  • 对于身份表,group_by 结果是每个 matched_url_path_rule 值的总请求数。

这些表被传递到 outer_join 操作,该操作会将匹配的标签值与具有匹配标签值的时序配对,每个表对应一个表中的一个输入表。通过将一个时序中每个点的时间戳与另一个时序中某个点的时间戳进行匹配,可以压缩成对时序。对于每个匹配的点对,outer_join 会生成一个输出,其中包含两个值,每个输入表中对应一个值。联接的时序由与两个输入时序相同的标签联接。

使用外部联接时,如果第二个表中的点在第一个表中没有匹配点,则必须提供一个替换值。在此示例中,使用值为 0 的点(outer_join 操作的参数)。

最后,div 操作会获取每个点包含两个值,并除以这些值生成一个输出点:每个网址映射的 500 个响应与所有响应的比率。

此处的字符串 div 实际上是 div 函数的名称,用于分隔两个数值。但它在此处用作操作。用作操作时,类似于 div 的函数会在每个输入点(启用此 join)中获得两个值,并为相应的输出点生成单个值。

查询的 | div 部分是 | value val(0) / val(1) 的快捷方式。value 操作允许输入表的值列上的任意表达式生成输出表的值列。如需了解详情,请参阅 value 操作和表达式的参考页面。

使用 ratio

div 函数可以替换为两个值的任何函数,但由于经常使用比率,MQL 提供了一个 ratio 表操作来直接计算比率。

以下查询等于上述版本(使用 outer_joindiv):

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| {
    filter response_code_class = 500
  ;
    ident
  }
| group_by [matched_url_path_rule]
| ratio

在此版本中,ratio 操作会替换早期版本中的 outer_join 0 | div 操作并产生相同的结果。

请注意,如果分子和分母输入具有标识每个时序的相同标签,则 ratio 仅使用 outer_join 为分子提供一个 0,这是 MQL outer_join 的要求。如果分子输入具有额外的标签,则分母中缺失的任何点都不会输出。

使用 group_by/

还有一种方法可以计算错误响应与所有响应的比率。在这种情况下,由于比率的分子和分母来自同一时序,因此您也可以单独进行分组计算。以下查询演示了此方法:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| group_by [matched_url_path_rule],
    sum(if(response_code_class = 500, val(), 0)) / sum(val())

此查询使用基于两个总和的比率构建的聚合表达式

  • 第一个 sum 使用 if 函数来计算 500 个值的标签,其他则为 0。sum 函数计算返回 500 的请求的计数。

  • 第二个 sum 会将所有请求 val() 的计数加起来。

然后将两个总和相除,得到 500 个响应与所有响应的比率。此查询产生的结果与使用 outer_joindiv 以及使用 ratio 中的查询相同。

使用 filter_ratio_by

由于比率经常通过将来自同一表的两个总和相除来计算,MQL 会为此目的提供 filter_ratio_by 操作。以下查询执行与上一版本相同的操作,前一版本明确除以总和:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| filter_ratio_by [matched_url_path_rule], response_code_class = 500

filter_ratio_by 操作的第一个操作数(此处为 [matched_url_path_rule])指示如何对响应进行分组。第二个操作(此处为 response_code_class = 500)用作分子的过滤表达式。

  • 分母表是按 matched_url_path_rule 对提取的表进行分组并使用 sum 进行聚合的结果。
  • 分子表是提取的表,按 HTTP 响应代码 5xx 对时序进行过滤,然后按 matched_url_path_rule 进行分组并使用 sum 进行聚合。

比率和配额指标

如需对 serviceruntime 配额指标设置查询和提醒以及特定于资源的配额指标,以监控配额消耗情况,您可以使用 MQL。如需了解详情(包括示例),请参阅使用配额指标

算术计算

有时,您可能需要先对数据执行算术运算,然后再为其绘制图表。例如,您可能希望扩缩时序,将数据转换为对数刻度,或绘制两个时序的总和图表。如需查看 MQL 中可用的算术函数列表,请参阅算术

如需扩缩时序,请使用 mul 函数。例如,以下查询会检索时序,然后将每个值乘以 10:

  fetch gce_instance
  | metric 'compute.googleapis.com/instance/disk/read_bytes_count'
  | mul(10)

如需对两个时序求和,请将查询配置为提取两个时间序列表,联接这些结果,然后调用 add 函数。以下示例展示了计算对 Compute Engine 实例执行读写操作的总字节数的查询:

  fetch gce_instance
  | { metric 'compute.googleapis.com/instance/disk/read_bytes_count'
    ; metric 'compute.googleapis.com/instance/disk/write_bytes_count' }
  | outer_join 0
  | add

如需从读取字节数中减去写入的字节数,请将 add 替换为前一个表达式中的 sub

MQL 使用从第一次提取和第二次提取返回的表集中的标签来确定如何联接表:

  • 如果第一个表包含第二个表中未找到的标签,则 MQL 无法执行 outer_join 操作,因此它会报告错误。例如,以下查询导致错误,因为 metric.throttle_reason 标签出现在第一个表中,但未出现在第二个表中:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count'
        ; metric 'compute.googleapis.com/instance/disk/write_bytes_count' }
      | outer_join 0
      | add
    

    解决这种类型的错误的一种方法是应用分组子句,以确保两个表具有相同的标签。例如,您可以将所有时序标签分组:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count'
          | group_by []
        ; metric 'compute.googleapis.com/instance/disk/write_bytes_count'
          | group_by [] }
      | outer_join 0
      | add
    
  • 如果两个表的标签匹配,或者第二个表包含第一个表中找不到的标签,则允许外部联接。例如,虽然 metric.throttle_reason 标签出现在第二个表中,但未出现在第一个表中,但是下面的查询不会导致错误:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/write_bytes_count'
        ; metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count' }
      | outer_join 0
      | sub
    

    在第一个表中找到的时序可能具有与第二个表中的多个时序匹配的标签值,因此 MQL 会对每个配对执行减法运算。

时移

有时,您需要比较当前发生的情况以及过去发生的情况。为了允许您比较过去的数据和当前数据,MQL 提供 time_shift 表操作,可以将过去的数据移至当前时间段。

时间内比率

以下查询使用 time_shiftjoindiv 来计算每个地区从现在开始到一周前的平均利用率。

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| group_by [zone], mean(val())
| {
    ident
  ;
    time_shift 1w
  }
| join | div

下图表显示了此查询的可能结果:

图表显示当前和时移数据的比率。

前两个操作提取时序,然后按区域对时序进行分组,并计算每个时序的平均值。然后将生成的表传递给两个操作。第一个操作 ident 将表保持不变。

第二个操作 time_shift 将时间段(1 周)与表中值的时间戳相加,从而将数据从一周前移过去。此更改会将第二个表中较早数据的时间戳与第一个表中的当前数据时间戳保持一致。

然后,使用内部 join 合并未更改的表和时移表。join 生成一个时间序列表,其中每个点都有两个值:当前利用率和一周前的利用率。然后,查询会使用 div 操作来计算当前值与一周前的值的比率。

过去和现在的数据

通过将 time_shiftunion 结合使用,您可以创建同时显示过去和当前数据的图表。例如,以下查询会返回当前和一周前的总体平均利用率。使用 union 可以在同一图表上显示这两个结果。

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| group_by []
| {
     add [when: "now"]
  ;
     add [when: "then"] | time_shift 1w
  }
| union

下图表显示了此查询的可能结果:

图表显示当前和过去的平均利用率。

此查询会提取时序,然后使用 group_by [] 将它们组合成一个不带标签的时序,从而保留 CPU 利用率数据点。此结果会传递给两个操作。第一个为名为 when、值为 now 的新标签添加一列。第二个添加一个名为 when、值为 then 的标签,并将结果传递给 time_shift 操作以将值移动一周。此查询使用 add 映射修饰符;有关详情,请参见映射

这两个表(每个表都包含单个时序的数据)将传递到 union,然后会生成一个包含两个输入表中的时序的表。

后续步骤

如需简要了解 QQL 语言结构,请参阅 MDQ 语言简介

如需了解 MQL 完整内容,请参阅 Monitoring Query Language 参考

如需了解如何与图表交互,请参阅使用图表