otelcol.processor.transform
otelcol.processor.transform
接受来自其他 otelcol
组件的遥测数据,并使用 OpenTelemetry 转换语言 (OTTL) 进行修改。OTTL 语句由 OTTL 函数 组成,这些函数在路径上操作。路径是对遥测数据的引用,例如
- 资源属性。
- 仪器范围名称。
- 跨度属性。
除了 标准 OTTL 函数 之外,还有一个仅包含度量指标的函数集
- convert_sum_to_gauge
- convert_gauge_to_sum
- convert_summary_count_val_to_sum
- convert_summary_sum_val_to_sum
- copy_metric
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 配置文件中输入字符串有两种方式
- 使用引号 (常规 Alloy 语法字符串)。需要转义的字符,如
\
和"
,必须使用\
字符前缀进行转义。- 使用反引号 (原始 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_id
、trace_id
和parent_span_id
以及日志的span_id
和trace_id
。修改这些字段可能会导致孤立的范围或日志。
用法
otelcol.processor.transform "LABEL" {
output {
metrics = [...]
logs = [...]
traces = [...]
}
}
参数
otelcol.processor.transform
支持以下参数
名称 | 类型 | 描述 | 默认 | 必需 |
---|---|---|---|---|
error_mode | 字符串 | 如果处理语句过程中发生错误,如何响应错误。 | "propagate" | 否 |
error_mode
的支持值如下
ignore
:忽略条件返回的错误,记录它们,并继续到下一个条件。这是推荐的模式。silent
:忽略条件返回的错误,不记录它们,并继续到下一个条件。propagate
:将错误返回到管道上游。这将导致负载从 Alloy 中删除。
代码块
以下代码块支持在 otelcol.processor.transform
的定义中
层次结构 | 代码块 | 描述 | 必需 |
---|---|---|---|
trace_statements | trace_statements | 转换跟踪的语句。 | 否 |
metric_statements | metric_statements | 转换度量的语句。 | 否 |
log_statements | log_statements | 转换日志的语句。 | 否 |
output | output | 配置接收到的遥测数据发送到的位置。 | 是 |
debug_metrics | debug_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
上下文关联的语句将能够转换资源的 attributes
和 dropped_attributes_count
。
每种 context
类型定义其自己的路径和特定于该上下文的枚举。有关每个上下文中路径和枚举的列表,请参阅 OpenTelemetry 文档。
上下文 决不 提供对 protobuf 定义中“更低级别”的单独项的访问。
- 这意味着与
resource
关联的语句 将无法 访问底层的仪表化作用域。 - 这意味着与
scope
关联的语句 将无法 访问底层的遥测切片(span、指标或日志)。 - 类似地,与
metric
关联的语句 将无法 访问单个数据点,但可以访问整个数据点切片。 - 类似地,与
span
关联的语句 将无法 访问单个 SpanEvent,但可以访问整个 SpanEvents 切片。
实际上,这意味着上下文不能根据结构中“更低级别”的遥测来做出其遥测相关的决定。例如,以下上下文语句 不可能,因为它试图在关联到 metric
的语句的条件中使用单个数据点属性。
metric_statements {
context = "metric"
statements = [
"set(description, \"test passed\") where datapoints.attributes[\"test\"] == \"pass\"",
]
}
上下文 始终 提供对与正在转换的遥测关联的 protobuf 定义中“更高级别”的项的访问。
- 这意味着与
datapoint
关联的语句可以访问数据点的指标、仪表化作用域和资源。 - 这意味着与
spanevent
关联的语句可以访问 spanevent 的 span、仪表化作用域和资源。 - 这意味着与
span
/metric
/log
关联的语句可以访问遥测的仪表化作用域和资源。 - 这意味着与
scope
关联的语句可以访问作用域的资源。
例如,以下上下文语句是可能的,因为 datapoint
语句可以访问数据点的指标。
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
块,但其所有参数都是可选的。默认情况下,遥测数据将被丢弃。根据需要配置metrics
、logs
和traces
参数,以向其他组件发送遥测数据。
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"
。
导出字段
以下字段被导出,可以被其他组件引用
名称 | 类型 | 描述 |
---|---|---|
input | otelcol.Consumer | 其他组件可以使用它来发送遥测数据的一个值。 |
input
接受任何遥测信号(指标、日志或跟踪)的otelcol.Consumer
数据。
组件健康状态
otelcol.processor.transform
仅在给出无效配置的情况下报告不健康。
调试信息
otelcol.processor.transform
不公开任何特定于组件的调试信息。
调试指标
otelcol.processor.transform
不公开任何特定于组件的调试指标。
示例
如果某个属性不存在,则执行转换
此示例设置在属性test
不存在时将其设置为pass
。
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]
}
}
另一种方法是使用正则表达式更新键
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
设置为日志体的值
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.name
和service.version
的值组合。
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体
{
"name": "log",
"attr1": "example value 1",
"attr2": "example value 2",
"nested": {
"attr3": "example value 3"
}
}
您可以将特定字段作为属性添加到日志中
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"`,
]
}
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
有导出可以被以下组件消费
注意
连接某些组件可能不合理,或者组件可能需要进一步配置才能正确连接。有关详细信息,请参阅链接文档。