菜单
文档breadcrumb arrow Grafana Alloybreadcrumb arrow 参考breadcrumb arrow 组件breadcrumb arrow otelcolbreadcrumb arrow otelcol.processor.transform
开源

otelcol.processor.transform

otelcol.processor.transform 接受来自其他 otelcol 组件的遥测数据,并使用 OpenTelemetry 转换语言 (OTTL) 进行修改。OTTL 语句由 OTTL 函数 组成,这些函数在路径上操作。路径是对遥测数据的引用,例如

  • 资源属性。
  • 仪器范围名称。
  • 跨度属性。

除了 标准 OTTL 函数 之外,还有一个仅包含度量指标的函数集

OTTL 语句还可以包含诸如

  • 布尔值:
    • not true
    • not IsMatch(name, "http_.*")
  • 布尔表达式,其中以一个 where 开头,后面跟一个或多个布尔值
    • set(attributes["whose_fault"], "ours") where attributes["http.status"] == 500
    • set(attributes["whose_fault"], "theirs") where attributes["http.status"] == 400 or attributes["http.status"] == 404
  • 数学表达式:
    • 1 + 1
    • end_time_unix_nano - start_time_unix_nano
    • sum([1, 2, 3, 4]) + (10 / 1) - 1

注意

在 Alloy 配置文件中输入字符串有两种方式

例如,OTTL 语句 set(description, "Sum") where type == "Sum" 可以写成

  • 常规 Alloy 语法字符串: "set(description, \"Sum\") where type == \"Sum\""
  • 原始 Alloy 语法字符串: `set(description, "Sum") where type == "Sum"`

原始字符串通常更容易用于编写 OTTL 语句。

注意

otelcol.processor.transform 是 OpenTelemetry Collector 上游 transform 处理器的一个包装器。如果需要,错误报告或功能请求将重定向到上游仓库。

您可以通过指定不同的标签来指定多个 otelcol.processor.transform 组件。

警告

otelcol.processor.transform 允许您修改所有遥测方面的内容。以下列出了具体的一些风险,但并不详尽。在使用此处理器之前,理解您自己的数据非常重要。

  • 不合理的转换:度量数据类型之间的转换在 度量数据模型 中没有定义。要使用这些函数,您必须理解传入的数据,并且知道它可以被有用地转换为新的数据类型或可以用来创建新的度量。
    • 尽管 OTTL 允许您使用 set 函数与 metric.data_type 结合使用,但在转换处理器中的实现是一个 空操作。要修改数据类型,您必须使用像 convert_gauge_to_sum 这样的特定函数。
  • 身份冲突:度量的转换可能会影响度量身份,导致身份危机。在转换度量名称以及减少或更改现有属性时要特别小心。添加新的属性是安全的。
  • 孤立的遥测:处理器允许您修改跟踪的 span_idtrace_idparent_span_id 以及日志的 span_idtrace_id。修改这些字段可能会导致孤立的范围或日志。

用法

alloy
otelcol.processor.transform "LABEL" {
  output {
    metrics = [...]
    logs    = [...]
    traces  = [...]
  }
}

参数

otelcol.processor.transform 支持以下参数

名称类型描述默认必需
error_mode字符串如果处理语句过程中发生错误,如何响应错误。"propagate"

error_mode 的支持值如下

  • ignore:忽略条件返回的错误,记录它们,并继续到下一个条件。这是推荐的模式。
  • silent:忽略条件返回的错误,不记录它们,并继续到下一个条件。
  • propagate:将错误返回到管道上游。这将导致负载从 Alloy 中删除。

代码块

以下代码块支持在 otelcol.processor.transform 的定义中

层次结构代码块描述必需
trace_statementstrace_statements转换跟踪的语句。
metric_statementsmetric_statements转换度量的语句。
log_statementslog_statements转换日志的语句。
outputoutput配置接收到的遥测数据发送到的位置。
debug_metricsdebug_metrics配置此组件生成的度量,以监控其状态。

trace_statements 代码块

trace_statements 代码块指定转换跟踪遥测信号的语句。可以指定多个 trace_statements 代码块。

名称类型描述默认必需
context字符串在解释相关语句时使用的 OTTL 上下文。
statements列表(字符串)OTTL 语句的列表。

context 的支持值如下

  • resource:当仅与环境变量交互时使用(例如,环境变量属性)。
  • scope:当仅与 OTLP 仪表化作用域交互时使用(例如,仪表化作用域的名称)。
  • span:当仅与 OTLP span 交互时使用。
  • spanevent:当仅与 OTLP span 事件交互时使用。

有关如何使用上下文的更多信息,请参阅 OTTL 上下文

metric_statements 块

metric_statements 块指定用于转换指标遥测信号的语句。可以指定多个 metric_statements 块。

名称类型描述默认必需
context字符串在解释相关语句时使用的 OTTL 上下文。
statements列表(字符串)OTTL 语句的列表。

context 的支持值如下

  • resource:当仅与环境变量交互时使用(例如,环境变量属性)。
  • scope:当仅与 OTLP 仪表化作用域交互时使用(例如,仪表化作用域的名称)。
  • metric:当仅与单个 OTLP 指标交互时使用。
  • datapoint:当仅与单个 OTLP 指标数据点交互时使用。

有关如何使用上下文的更多信息,请参阅 OTTL 上下文

log_statements 块

log_statements 块指定用于转换日志遥测信号的语句。可以指定多个 log_statements 块。

名称类型描述默认必需
context字符串在解释相关语句时使用的 OTTL 上下文。
statements列表(字符串)OTTL 语句的列表。

context 的支持值如下

  • resource:当仅与环境变量交互时使用(例如,环境变量属性)。
  • scope:当仅与 OTLP 仪表化作用域交互时使用(例如,仪表化作用域的名称)。
  • log:当仅与 OTLP 日志交互时使用。

有关如何使用上下文的更多信息,请参阅 OTTL 上下文

OTTL 上下文

每个上下文允许转换其类型的遥测。例如,与 resource 上下文关联的语句将能够转换资源的 attributesdropped_attributes_count

每种 context 类型定义其自己的路径和特定于该上下文的枚举。有关每个上下文中路径和枚举的列表,请参阅 OpenTelemetry 文档。

上下文 决不 提供对 protobuf 定义中“更低级别”的单独项的访问。

  • 这意味着与 resource 关联的语句 将无法 访问底层的仪表化作用域。
  • 这意味着与 scope 关联的语句 将无法 访问底层的遥测切片(span、指标或日志)。
  • 类似地,与 metric 关联的语句 将无法 访问单个数据点,但可以访问整个数据点切片。
  • 类似地,与 span 关联的语句 将无法 访问单个 SpanEvent,但可以访问整个 SpanEvents 切片。

实际上,这意味着上下文不能根据结构中“更低级别”的遥测来做出其遥测相关的决定。例如,以下上下文语句 不可能,因为它试图在关联到 metric 的语句的条件中使用单个数据点属性。

alloy
metric_statements {
  context = "metric"
  statements = [
    "set(description, \"test passed\") where datapoints.attributes[\"test\"] == \"pass\"",
  ]
}

上下文 始终 提供对与正在转换的遥测关联的 protobuf 定义中“更高级别”的项的访问。

  • 这意味着与 datapoint 关联的语句可以访问数据点的指标、仪表化作用域和资源。
  • 这意味着与 spanevent 关联的语句可以访问 spanevent 的 span、仪表化作用域和资源。
  • 这意味着与 span/metric/log 关联的语句可以访问遥测的仪表化作用域和资源。
  • 这意味着与 scope 关联的语句可以访问作用域的资源。

例如,以下上下文语句是可能的,因为 datapoint 语句可以访问数据点的指标。

alloy
metric_statements {
  context = "datapoint"
  statements = [
    "set(metric.description, \"test passed\") where attributes[\"test\"] == \"pass\"",
  ]
}

OTLP 信号的 protobuf 定义在 GitHub 上维护。

尽可能将您的语句关联到要转换的语句的上下文。上下文是嵌套的,较高层级的上下文不需要迭代任何较低层级的上下文。例如,虽然您可以使用 span 上下文修改关联到 span 的资源属性,但使用 resource 上下文更有效。

output 块

output 块配置一个组件集,以将结果遥测数据转发到。

以下参数受支持

名称类型描述默认必需
日志list(otelcol.Consumer)要发送日志的消费方列表。[]
度量list(otelcol.Consumer)要发送指标的消费方列表。[]
跟踪list(otelcol.Consumer)要发送跟踪的消费方列表。[]

您必须指定output块,但其所有参数都是可选的。默认情况下,遥测数据将被丢弃。根据需要配置metricslogstraces参数,以向其他组件发送遥测数据。

debug_metrics块

debug_metrics块配置了该组件生成的监控其状态的指标。

以下参数受支持

名称类型描述默认必需
disable_high_cardinality_metrics布尔值是否禁用某些高基数指标。true
level字符串控制封装的收集器发出的指标的详细程度。"detailed"

disable_high_cardinality_metrics是Grafana Alloy中对应的在OpenTelemetry Collector中的telemetry.disableHighCardinalityMetrics功能开关。它删除可能导致高基数指标的属性。例如,从HTTP和gRPC连接中移除具有IP地址和端口号的属性。

注意

如果已配置,则disable_high_cardinality_metrics仅应用于otelcol.exporter.*otelcol.receiver.*组件。

level是Alloy中对应的在OpenTelemetry Collector中的telemetry.metrics.level功能开关。可能的值有"none""basic""normal""detailed"

导出字段

以下字段被导出,可以被其他组件引用

名称类型描述
inputotelcol.Consumer其他组件可以使用它来发送遥测数据的一个值。

input接受任何遥测信号(指标、日志或跟踪)的otelcol.Consumer数据。

组件健康状态

otelcol.processor.transform仅在给出无效配置的情况下报告不健康。

调试信息

otelcol.processor.transform不公开任何特定于组件的调试信息。

调试指标

otelcol.processor.transform不公开任何特定于组件的调试指标。

示例

如果某个属性不存在,则执行转换

此示例设置在属性test不存在时将其设置为pass

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  trace_statements {
    context = "span"
    statements = [
      // Accessing a map with a key that does not exist will return nil.
      `set(attributes["test"], "pass") where attributes["test"] == nil`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义。

重命名资源属性

更改属性键有两种方法。一种方法是通过设置新属性并删除旧属性来完成

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  trace_statements {
    context = "resource"
    statements = [
      `set(attributes["namespace"], attributes["k8s.namespace.name"])`,
      `delete_key(attributes, "k8s.namespace.name")`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

另一种方法是使用正则表达式更新键

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  trace_statements {
    context = "resource"
    statements = [
     `replace_all_patterns(attributes, "key", "k8s\\.namespace\\.name", "namespace")`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义,以及在每\中使用\\进行转义。

从日志体内容创建属性

此示例将属性body设置为日志体的值

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  log_statements {
    context = "log"
    statements = [
      `set(attributes["body"], body)`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义。

合并两个属性

此示例将属性test设置为属性service.nameservice.version的值组合。

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  trace_statements {
    context = "resource"
    statements = [
      // The Concat function combines any number of strings, separated by a delimiter.
      `set(attributes["test"], Concat([attributes["foo"], attributes["bar"]], " "))`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义。

解析JSON日志

给定以下JSON体

json
{
  "name": "log",
  "attr1": "example value 1",
  "attr2": "example value 2",
  "nested": {
    "attr3": "example value 3"
  }
}

您可以将特定字段作为属性添加到日志中

alloy
otelcol.processor.transform "default" {
  error_mode = "ignore"

  log_statements {
    context = "log"

    statements = [
      // Parse body as JSON and merge the resulting map with the cache map, ignoring non-json bodies.
      // cache is a field exposed by OTTL that is a temporary storage place for complex operations.
      `merge_maps(cache, ParseJSON(body), "upsert") where IsMatch(body, "^\\{")`,

      // Set attributes using the values merged into cache.
      // If the attribute doesn't exist in cache then nothing happens.
      `set(attributes["attr1"], cache["attr1"])`,
      `set(attributes["attr2"], cache["attr2"])`,

      // To access nested maps you can chain index ([]) operations.
      // If nested or attr3 do no exist in cache then nothing happens.
      `set(attributes["nested.attr3"], cache["nested"]["attr3"])`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义,以及在每\中使用\\进行转义。

属性和状态码的多种变换

示例通过将变换与要转换的上下文分组,利用了上下文效率。

alloy
otelcol.receiver.otlp "default" {
  http {}
  grpc {}

  output {
    metrics = [otelcol.processor.transform.default.input]
    logs    = [otelcol.processor.transform.default.input]
    traces  = [otelcol.processor.transform.default.input]
  }
}

otelcol.processor.transform "default" {
  error_mode = "ignore"

  trace_statements {
    context = "resource"
    statements = [
      `keep_keys(attributes, ["service.name", "service.namespace", "cloud.region", "process.command_line"])`,
      `replace_pattern(attributes["process.command_line"], "password\\=[^\\s]*(\\s?)", "password=***")`,
      `limit(attributes, 100, [])`,
      `truncate_all(attributes, 4096)`,
    ]
  }

  trace_statements {
    context = "span"
    statements = [
      `set(status.code, 1) where attributes["http.path"] == "/health"`,
      `set(name, attributes["http.route"])`,
      `replace_match(attributes["http.target"], "/user/*/list/*", "/user/{userId}/list/{listId}")`,
      `limit(attributes, 100, [])`,
      `truncate_all(attributes, 4096)`,
    ]
  }

  metric_statements {
    context = "resource"
    statements = [
      `keep_keys(attributes, ["host.name"])`,
      `truncate_all(attributes, 4096)`,
    ]
  }

  metric_statements {
    context = "metric"
    statements = [
      `set(description, "Sum") where type == "Sum"`,
    ]
  }

  metric_statements {
    context = "datapoint"
    statements = [
      `limit(attributes, 100, ["host.name"])`,
      `truncate_all(attributes, 4096)`,
      `convert_sum_to_gauge() where metric.name == "system.processes.count"`,
      `convert_gauge_to_sum("cumulative", false) where metric.name == "prometheus_metric"`,
    ]
  }

  log_statements {
    context = "resource"
    statements = [
      `keep_keys(attributes, ["service.name", "service.namespace", "cloud.region"])`,
    ]
  }

  log_statements {
    context = "log"
    statements = [
      `set(severity_text, "FAIL") where body == "request failed"`,
      `replace_all_matches(attributes, "/user/*/list/*", "/user/{userId}/list/{listId}")`,
      `replace_all_patterns(attributes, "value", "/account/\\d{4}", "/account/{accountId}")`,
      `set(body, attributes["http.route"])`,
    ]
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

otelcol.exporter.otlp "default" {
  client {
    endpoint = env("OTLP_ENDPOINT")
  }
}

每个语句都用反引号括起来而不是引号。这构成了一个原始字符串,使我们能够在正常 Alloy语法字符串内部避免在每个"中使用\"进行转义,以及在每\中使用\\进行转义。

兼容组件

otelcol.processor.transform可以接受以下组件的参数

otelcol.processor.transform有导出可以被以下组件消费

注意

连接某些组件可能不合理,或者组件可能需要进一步配置才能正确连接。有关详细信息,请参阅链接文档。