【问题标题】:Combining two metrics with different resource types into one using MQL使用 MQL 将两个具有不同资源类型的指标合并为一个
【发布时间】:2022-12-09 11:54:44
【问题描述】:

当两个指标来自两个不同的资源时,如何将它们合并为一个指标?


我有一个简单的基于日志的指标,my-metric,定义如下:

resource "google_logging_metric" "my_metric" {
  name = "my-metric"

  filter = <<-EOT
             logName="projects/my-project/logs/my-app"
             labels.name="my.event"
           EOT

  label_extractors = {
    "event_type" = "EXTRACT(labels.event_type)"
  }

  metric_descriptor {
    value_type  = "INT64"
    metric_kind = "DELTA"

    labels {
      key        = "event_type"
      value_type = "STRING"
    }
  }
}

我最近将我的应用程序移至具有自己日志的 Google Cloud Run (GCR),因此我更新了指标的过滤器,如下所示:

(
  logName="projects/my-project/logs/my_app"
  OR
  logName="projects/my-project/logs/run.googleapis.com%2Fstdout"
)
labels.name="my.event"

让我没想到的是公制附加到不同的资源,所以逻辑上我有两个指标。在 MQL 中:

  1. gce_instance::logging.googleapis.com/user/my-metric
  2. global::logging.googleapis.com/user/my-metric

    我想保留基于此指标的现有警报策略,所以我想知道是否有一种方法可以将来自全局和 GCE 实例资源的指标合并为一个指标(我将按 event_type 分组并添加它们向上,例如)。


    反复试验

    我试图将它们合并到指标资源管理器中的一个图表中。

    1. 否认

    我以前几乎只使用过一个日志和全局资源,所以我的直觉是简单地这样做:

    fetch global::logging.googleapis.com/user/my-metric
    

    不过,这只会让我获得一半的价值。我意识到我会得到这样的另一半:

    fetch gce_instance::logging.googleapis.com/user/my-metric
    

    2.愤怒

    好的,让我们把它们结合起来。我对 MQL 的了解足以对我自己和他人构成危险(或者我是这么认为的)。

    {
        fetch global::logging.googleapis.com/user/my-metric
        ;
        fetch gce_instance::logging.googleapis.com/user/my-metric
    }
    | outer_join 0
    | add
    

    那只显示 global 资源。它恰好是第一个,所以我的直觉是交换它们,有时会提供更多信息(我发现 MQL 参考非常抽象,而且我主要通过复制粘贴示例和反复试验来学习)。将 gce_instance 首先抛出两个错误:

    第 8 行:输入表 1 没有表 0 中存在的时间序列标识符列“resource.instance_id”。表 0 必须是表 1 的时间序列标识符列的子集。 第 8 行:输入表 1 没有表 0 中存在的时间序列标识符列“resource.zone”。表 0 必须是表 1 的时间序列标识符列的子集。

    我真的不需要 instance_idzone,所以也许我可以删除它们?

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | outer_join 0
    | add
    

    现在只有gce_instance 资源。作为参考,它看起来像这样:

    只有 global 资源:

    只有 gce_instance 资源:

    我想要什么(种类):

    3.讨价还价

    join

    一旦您完全掌握 MQL,我相信它会很漂亮,但对我来说它仍然是一个黑盒子。这是其他一些尝试。我基本上浏览了 MQL 参考,尝试了我能找到的每个关键字:

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | join
    

    所选时间范围内没有可用数据

    不知道那是什么意思。下一个!

    joingroup_by

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | group_by [metric.event_type], max(val())
    | join
    

    所选时间范围内没有可用数据

    没用...下一个!

    union_group_by

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | union_group_by [metric.event_type]
    

    图表定义无效。 INVALID_ARGUMENT:请求包含无效参数。

    这很有帮助,谢谢。下一个!

    outer_join or_else

    outer_join 在我的第一次尝试中至少似乎给出了两个带有值的表。也许我只需要将它们结合起来?

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | outer_join 0
    | or_else
    

    很有意思。我现在得到一堆不同的时间序列,按event_type分组。不过,它们都在 0 处趋于平缓。换成outer_join 123?是的,他们现在都是 123 而不是。

    outer_join docs 有话要说:

    必须给出 left_default_value 和 right_default_value 参数之一或两者。每个对应一个输入表(第一个“左”表或第二个“右”表),当为表指定时,如果该表没有与其他表。每个参数指定所创建行的值列。如果为表提供了默认参数,则该表中的时间序列标识符列必须是另一个表的时间序列的子集,并且如果另一个表具有 Delta 时间,则它只能具有 Delta 时间序列类型-系列类。

    我发现这部分隐约有趣:

    该表中的时间序列标识符列必须是其他表的时间序列的子集

    不确定我的时间序列标识符列是什么。也许他们只是不好,但我不会放弃。如果他们是不是一个子集?也许我需要对齐, 不是总计的?我有没有提到我不知道自己在做什么?

    对齐

    对齐表操作使用对齐函数 [不是我的错字] 来生成对齐表,该表的时间序列具有定期时间戳的点。

    我想我需要调用对齐表操作与其中之一对齐功能?定期间隔听起来很酷。

    The aggregation docs has a section about aligners as well

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        | map drop [resource.zone, resource.instance_id]
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | align interpolate(10m)
    # | group_by [metric.event_type], sum(val())
    | outer_join 0
    | add
    
    

    插值不会给我丢失的数据。这个给了我 global 资源,但在没有任何数据的地方进行了一些插值。这感觉也像是死胡同。

    我也输入了group_by,以防万一,没有变化。

    4.抑郁症

    我现在开始有点沮丧,我有两个表中的数据,但无论我做什么,我只能看到其中一个表中的数据。我之前以各种方式将时间序列与 MQL 相结合,一旦它起作用,我通常可以解释原因。当它不起作用时它会变得更狡猾。

    也许我们可以以某种方式回到第一原则?我知道 group_by [] 清除了标签,也许这会简化事情?

    {
        fetch gce_instance::logging.googleapis.com/user/my-metric
        ;
        fetch global::logging.googleapis.com/user/my-metric
    }
    | group_by []
    

    第 1 行:预期查询有 1 个结果但有 2 个。

    哎哟。最后加个| union

    第 7 行:输入表 0 具有遗留目标架构“cloud.CloudTask”,它不同于输入表 1 的遗留目标架构“cloud.Global”。 “联合”表操作的输入需要具有相同的列名、列类型和目标架构。

    那是一个新的! “目标模式”是吧?也许这一直是问题所在?

    快来咨询the trusty reference吧!图式……图式?没有提到模式。

    也许是examples?不,但它说“在你开始之前”。我以前读过,但也许我错过了什么?

    熟悉 Cloud Monitoring 概念(包括指标类型、受监控资源类型和时间序列)会很有帮助。有关这些概念的介绍,请参阅Metrics, time series, and resources

    但是不,“指标、时间序列和资源”页面也没有提到遗留目标模式,甚至没有提到一般模式。 Components of the metric modelNotes on terminology 页面也没有。

    我是在另一个死胡同吗? A quick Google search 似乎表明它是。

    其他尝试

    • 使用value[foo: val()] 等将表格分成不同的值。
    • 映射列名称并以各种方式重新组合它们。
    • 使用addor_else 等添加值。

    五、验收

    我已经尝试了所有我能想到的方法,并多次通读了大部分文档。

    写下这个问题,我找到了 [一个令人兴奋的答案](https://stackoverflow.com/a/67098846/98057] 并尝试使用我的指标:

    {
        fetch gce_instance
        | metric 'logging.googleapis.com/user/my-metric'
        | group_by [], sum(val())
        | align rate(1m)
        | every 1m
        ;
        fetch global
        | metric 'logging.googleapis.com/user/my-metric'
        | group_by [], sum(val())
        | align rate(1m)
        | every 1m
    }
    | join
    | add
    

    所选时间范围内没有可用数据

    我当然已经验证了至少一个“子查询”返回了一些数据,在这种情况下是这样的:

    fetch gce_instance
    | metric 'logging.googleapis.com/user/my-metric'
    | group_by [], sum(val())
    | align rate(1m)
    | every 1m
    

    如何使用 MQL 将来自两种不同资源类型的这两种指标合并为一种?

【问题讨论】:

    标签: google-cloud-platform time-series metrics google-cloud-monitoring monitoring-query-language


    【解决方案1】:

    这是 GCP 支持的解决方案:

    {
        fetch gce_instance
        | metric 'logging.googleapis.com/user/my-metric'
        | group_by [], sum(val())
        | align rate(1m)
        | every 1m
        ;
        fetch global
        | metric 'logging.googleapis.com/user/my-metric'
        | group_by [], sum(val())
        | align rate(1m)
        | every 1m
    }
    | outer_join 0,0
    | add
    

    我尝试了outer_join(0,0)(语法错误)和outer_join 0,但是outer_join 0,0做了它应该做的——为两个表添加了默认值。很明显,一旦你看到它。

    【讨论】:

    • 看来这个MQL可以简化为{ fetch gce_instance::logging.googleapis.com/user/my-metric | group_by [], sum(val()) | align rate(1m) | every 1m ; fetch global::logging.googleapis.com/user/my-metric | group_by [], sum(val()) | align rate(1m) | every 1m } | union
    • @commander.trout 是的,如果你能摆脱它,那就更简单了!在我的设置中,使用 union 时出现此错误:“输入表 N 具有遗留目标架构‘cloud.X’,它不同于输入表 M 的遗留目标架构‘cloud.Global’。‘联合’的输入表操作需要具有相同的列名、列类型和目标架构。”
    【解决方案2】:

    经过数小时的挖掘和试验,我发现以下内容给了我想要的东西,

    {
      fetch gce_instance::logging.googleapis.com/user/ping
      | group_by [metric.client]
      ;
      fetch global::logging.googleapis.com/user/ping
      | group_by [metric.client]
    }
    | union
    

    如果没有 group_by [metric.client]union 将失败,并出现类似于 The inputs to the 'union' table operation are required to have the same column names, column types, and target schemas 的错误。

    就我而言,我继续通过管道连接到absent_for 以创建一个警报,如果任何“客户端”的指标数据丢失,该警报就会触发。

    【讨论】:

      猜你喜欢
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 2021-09-22
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      相关资源
      最近更新 更多