MQL 查询示例

本文档通过示例介绍 Monitoring Query Language (MQL)。不过, 未涵盖语言的各个方面。MQL 为 Monitoring Query Language 参考文档中进行了全面记录。

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

您可以采用多种形式编写特定查询:语言是 非常灵活,学完本课程后,您还可以使用许多快捷键 熟悉语法如需了解详情,请参阅严格形式查询

准备工作

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

  1. 在 Google Cloud 控制台中,转到 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 中可用的操作和函数。

查询结构

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

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

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

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

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

时间范围

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

要更改图表的时间范围,请使用时间范围选择器。对于 例如,如果您想查看过去一周的数据 时间范围选择器中的过去 1 周。你还可以指定 开始和结束时间,或指定查看前后的时间。

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

对齐

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

如果需要,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()) 用于确定如何将每个组中的时间序列组合或聚合为一个输出时间序列。组的输出时间序列中的每个点都是从组中的所有输入时间序列中聚合具有相同时间戳的点的结果。

    聚合函数(在此示例中为 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 = 3。生成的 表包含要排除的三个时序。

    然后,包含前三个时序的表格会导入 value 表操作。此操作会添加另一列 前三个表格中的每个时序此列 is_default_value - 为其指定布尔值 false 前三条表格中的时序。

  • ident 操作返回传入其中的同一表: CPU 利用率时序的原始表。从来没有 此表中的系列包含 is_default_value 列。

然后通过管道将前三个表格和原始表格 outer_join 表操作。前三张表格是左边表格 提取的表就是联接中的正确表。 设置外联接以提供值 true 作为 要联接的行中不存在的任何字段。使用 外联接是合并的表,前三个表中的行保留 值为 false 的列 is_default_value,以及 原本排名前三的表格获得的 值为 trueis_default_value 列。

然后,联接生成的表会传递给 filter 表操作,该操作可过滤掉含有 is_default_value 列中 false 的值。生成的表 包含最初提取的表中的行,但不包含这些行 从前三条表格中此表包含预期的时序集 添加了 is_default_column

最后一步是删除由 is_default_column 因此输出表的列与最初提取的列相同 表格。

以下屏幕截图显示了先前查询的图表:

此图表显示了许多 CPU 利用率行,不包括离群值。

您可以创建一个查询来排除 将 top n 替换为 bottom n 可提高 CPU 利用率。

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

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 的列 表格。
  • 使用 group_by 表运算符和 max_val_of_read_ops_count_max 列上的 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 操作。例如,以下 查询计算数据流的第 99 个百分位值以 1 小时的滑动时间表示 窗口:

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(错误)响应代码的请求进行计数。

    此表格是比率的分子。

  • ident(即身份)操作会输出其输入, 此操作会返回最初提取的表。即包含对每个响应代码计数的时间序列的表。

    下表是比率的分母。

分别由 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.instance_name 标签出现在第一个表中,但未出现在第二个表中:

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

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

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

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

    在第一个表中找到的时序可能具有匹配的标签值 也就是在第二个表格中显示了多个时序 对每一对值执行减法运算。

时移

有时,您需要比较当前发生的情况以及过去发生的情况。为了允许您比较过去的数据和当前数据,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 参考

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