You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于YAML配置动态生成New Relic SLO的NRQL查询?

动态构建NRQL查询条件的Terraform实现方案

1. 标准化YAML配置结构

先把SLO配置整理成层级清晰的结构,每个SLO包含名称、可用性阈值和多组端点信息:

slos:
  - name: "checkout-api-availability"
    threshold: 99.9
    endpoints:
      - uri: "/api/checkout"
        method: "POST"
      - uri: "/api/checkout/status"
        method: "GET"
  - name: "product-api-availability"
    threshold: 99.5
    endpoints:
      - uri: "/api/products"
        method: "GET"
      - uri: "/api/products/{id}"
        method: "GET"
      - uri: "/api/products"
        method: "POST"

2. Terraform代码实现

通过Terraform内置函数动态拼接NRQL的OR条件,替代手动编写的占位符:

# 读取并解析YAML配置文件
locals {
  slo_config = yamldecode(file("${path.module}/slo_config.yaml"))
}

# 批量创建New Relic SLO对象
resource "newrelic_service_level" "slo" {
  for_each = { for slo in local.slo_config.slos : slo.name => slo }

  name        = each.value.name
  description = "Availability SLO for ${each.value.name}"
  type        = "availability"

  query {
    # 动态生成分子查询(成功请求数)
    numerator = <<-NRQL
      SELECT count(*) FROM Transaction
      WHERE ${join(" OR ", formatlist("(request.uri = '%s' AND request.method = '%s')", each.value.endpoints[*].uri, each.value.endpoints[*].method))}
        AND error IS NOT TRUE
    NRQL

    # 动态生成分母查询(总请求数)
    denominator = <<-NRQL
      SELECT count(*) FROM Transaction
      WHERE ${join(" OR ", formatlist("(request.uri = '%s' AND request.method = '%s')", each.value.endpoints[*].uri, each.value.endpoints[*].method))}
    NRQL
  }

  objective {
    target       = each.value.threshold
    time_window  = "30_day"
  }
}

3. 关键逻辑说明

  • yamldecode(file(...)):加载并解析YAML配置文件,将其转换为Terraform可遍历的列表对象。
  • formatlist:批量格式化每个端点的uri和method,生成(request.uri = 'xxx' AND request.method = 'xxx')格式的单个条件字符串。each.value.endpoints[*].uri和each.value.endpoints[*].method会自动提取所有端点的对应字段为列表,formatlist按位置一一匹配拼接。
  • join(" OR ", ...):将所有单个条件用OR连接,生成完整的WHERE子句条件,完美替代原占位符。

4. 特殊字符转义优化

如果uri或method中包含单引号(比如带参数的路径),需添加转义处理避免NRQL语法错误,修改formatlist部分:

join(" OR ", formatlist(
  "(request.uri = '%s' AND request.method = '%s')",
  [for e in each.value.endpoints : replace(e.uri, "'", "''")],
  [for e in each.value.endpoints : replace(e.method, "'", "''")]
))

这里用replace函数把单个单引号替换为两个单引号(NRQL的字符串转义规则),确保查询语法合法。

内容的提问来源于stack exchange,提问作者RamenOps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:22:19