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

otelcol.processor.transform

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

  • 资源属性。
  • Instrumentation scope 名称。
  • Span 属性。

除了 标准 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 一起使用,但它在 transform 处理器中的实现是 空操作。要修改数据类型,您必须使用特定的函数,例如 convert_gauge_to_sum
  • 身份冲突:指标的转换可能会影响指标的身份,从而导致身份危机。在转换指标名称以及减少或更改现有属性时,请格外小心。添加新属性是安全的。
  • 孤立的遥测数据:该处理器允许您修改追踪的 span_idtrace_idparent_span_id,以及日志的 span_idtrace_id。修改这些字段可能会导致孤立的 span 或日志。

用法

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

参数

otelcol.processor.transform 支持以下参数

名称类型描述默认值必需
error_modestring如果在处理语句时发生错误,如何响应。"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 块。

名称类型描述默认值必需
contextstring解释关联语句时要使用的 OTTL 上下文。
statementslist(string)OTTL 语句列表。

context 支持的值包括

  • resource:仅在与 OTLP 资源(例如,资源属性)交互时使用。
  • scope:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。
  • span:仅在与 OTLP span 交互时使用。
  • spanevent:仅在与 OTLP span 事件交互时使用。

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

metric_statements 块

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

名称类型描述默认值必需
contextstring解释关联语句时要使用的 OTTL 上下文。
statementslist(string)OTTL 语句列表。

context 支持的值包括

  • resource:仅在与 OTLP 资源(例如,资源属性)交互时使用。
  • scope:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。
  • metric:仅在与单个 OTLP 指标交互时使用。
  • datapoint:仅在与单个 OTLP 指标数据点交互时使用。

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

log_statements 块

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

名称类型描述默认值必需
contextstring解释关联语句时要使用的 OTTL 上下文。
statementslist(string)OTTL 语句列表。

context 支持的值包括

  • resource:仅在与 OTLP 资源(例如,资源属性)交互时使用。
  • scope:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。
  • log:仅在与 OTLP 日志交互时使用。

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

OTTL 上下文

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

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

上下文 永远不会 提供对 protobuf 定义中“较低”级别的单个项目的访问。

  • 这意味着与 resource 关联的语句 将无法 访问底层的 instrumentation scope。
  • 这意味着与 scope 关联的语句 将无法 访问底层的遥测切片(span、指标或日志)。
  • 同样,与 metric 关联的语句 将无法 访问单个数据点,但可以访问整个数据点切片。
  • 同样,与 span 关联的语句 将无法 访问单个 SpanEvent,但可以访问整个 SpanEvents 切片。

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

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

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

  • 这意味着与 datapoint 关联的语句可以访问数据点的指标、instrumentation scope 和资源。
  • 这意味着与 spanevent 关联的语句可以访问 span 事件的 span、instrumentation scope 和资源。
  • 这意味着与 span/metric/log 关联的语句可以访问遥测数据的 instrumentation scope 和资源。
  • 这意味着与 scope 关联的语句可以访问 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 块配置一组组件,用于将生成的遥测数据转发到这些组件。

支持以下参数

名称类型描述默认值必需
logslist(otelcol.Consumer)要将日志发送到的消费者列表。[]
metricslist(otelcol.Consumer)要将指标发送到的消费者列表。[]
traceslist(otelcol.Consumer)要将追踪发送到的消费者列表。[]

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

debug_metrics 块

debug_metrics 块配置此组件生成的用于监控其状态的指标。

支持以下参数

名称类型描述默认值必需
disable_high_cardinality_metricsboolean是否禁用某些高基数指标。true
levelstring控制包装的收集器发出的指标的详细程度。"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,如果属性 test 不存在。

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
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]
  }
}

从日志正文的内容创建属性

此示例将属性 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]
  }
}

合并两个属性

此示例将属性 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["service.name"], attributes["service.version"]], " "))`,
    ]
  }

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

解析 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
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"`,
      `convert_sum_to_gauge() where name == "system.processes.count"`,
      `convert_gauge_to_sum("cumulative", false) where name == "prometheus_metric"`,
      `aggregate_on_attributes("sum") where name == "system.memory.usage"`,
    ]
  }

  metric_statements {
    context = "datapoint"
    statements = [
      `limit(attributes, 100, ["host.name"])`,
      `truncate_all(attributes, 4096)`,
    ]
  }

  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 = sys.env("OTLP_ENDPOINT")
  }
}

兼容组件

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

otelcol.processor.transform 具有可以被以下组件使用的导出

注意

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