otelcol.processor.transform
otelcol.processor.transform
接受来自其他 otelcol
组件的遥测数据,并使用 OpenTelemetry Transformation Language (OTTL) 对其进行修改。OTTL 语句由 OTTL 函数 组成,这些函数作用于路径。路径是对遥测数据的引用,例如
- 资源属性。
- Instrumentation scope 名称。
- Span 属性。
除了 标准 OTTL 函数 之外,还有一组仅用于指标的函数
- convert_sum_to_gauge
- convert_gauge_to_sum
- convert_summary_count_val_to_sum
- convert_summary_sum_val_to_sum
- copy_metric
- scale_metric
- aggregate_on_attributes
- convert_exponential_histogram_to_histogram
- aggregate_on_attribute_value
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 Collectortransform
处理器的封装。如有必要,错误报告或功能请求将被重定向到上游存储库。
您可以通过为多个 otelcol.processor.transform
组件指定不同的标签来指定它们。
警告
otelcol.processor.transform
允许您修改遥测数据的所有方面。下面给出了一些具体的风险,但这并非详尽列表。在使用此处理器之前,务必了解您的数据。
- 不健全的转换:指标数据类型之间的转换未在 指标数据模型 中定义。要使用这些函数,您必须了解传入的数据,并知道它可以有意义地转换为新的指标数据类型,或者可以用于创建新的指标。
- 尽管 OTTL 允许您将
set
函数与metric.data_type
一起使用,但它在 transform 处理器中的实现是 空操作。要修改数据类型,您必须使用特定的函数,例如convert_gauge_to_sum
。- 身份冲突:指标的转换可能会影响指标的身份,从而导致身份危机。在转换指标名称以及减少或更改现有属性时,请格外小心。添加新属性是安全的。
- 孤立的遥测数据:该处理器允许您修改追踪的
span_id
、trace_id
和parent_span_id
,以及日志的span_id
和trace_id
。修改这些字段可能会导致孤立的 span 或日志。
用法
otelcol.processor.transform "LABEL" {
output {
metrics = [...]
logs = [...]
traces = [...]
}
}
参数
otelcol.processor.transform
支持以下参数
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
error_mode | string | 如果在处理语句时发生错误,如何响应。 | "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 | string | 解释关联语句时要使用的 OTTL 上下文。 | 是 | |
statements | list(string) | OTTL 语句列表。 | 是 |
context
支持的值包括
resource
:仅在与 OTLP 资源(例如,资源属性)交互时使用。scope
:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。span
:仅在与 OTLP span 交互时使用。spanevent
:仅在与 OTLP span 事件交互时使用。
有关如何使用上下文的更多信息,请参阅 OTTL 上下文。
metric_statements 块
metric_statements
块指定转换指标遥测信号的语句。可以指定多个 metric_statements
块。
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
context | string | 解释关联语句时要使用的 OTTL 上下文。 | 是 | |
statements | list(string) | OTTL 语句列表。 | 是 |
context
支持的值包括
resource
:仅在与 OTLP 资源(例如,资源属性)交互时使用。scope
:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。metric
:仅在与单个 OTLP 指标交互时使用。datapoint
:仅在与单个 OTLP 指标数据点交互时使用。
有关如何使用上下文的更多信息,请参阅 OTTL 上下文。
log_statements 块
log_statements
块指定转换日志遥测信号的语句。可以指定多个 log_statements
块。
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
context | string | 解释关联语句时要使用的 OTTL 上下文。 | 是 | |
statements | list(string) | OTTL 语句列表。 | 是 |
context
支持的值包括
resource
:仅在与 OTLP 资源(例如,资源属性)交互时使用。scope
:仅在与 OTLP instrumentation scope(例如,instrumentation scope 的名称)交互时使用。log
:仅在与 OTLP 日志交互时使用。
有关如何使用上下文的更多信息,请参阅 OTTL 上下文。
OTTL 上下文
每个上下文都允许转换其类型的遥测数据。例如,与 resource
上下文关联的语句将能够转换资源的 attributes
和 dropped_attributes_count
。
每种类型的 context
都定义了其自己的路径和特定于该上下文的枚举。有关每个上下文的路径和枚举列表,请参阅 OpenTelemetry 文档
上下文 永远不会 提供对 protobuf 定义中“较低”级别的单个项目的访问。
- 这意味着与
resource
关联的语句 将无法 访问底层的 instrumentation scope。 - 这意味着与
scope
关联的语句 将无法 访问底层的遥测切片(span、指标或日志)。 - 同样,与
metric
关联的语句 将无法 访问单个数据点,但可以访问整个数据点切片。 - 同样,与
span
关联的语句 将无法 访问单个 SpanEvent,但可以访问整个 SpanEvents 切片。
实际上,这意味着上下文无法根据结构中“较低”级别的遥测数据来决定其遥测数据。例如,以下上下文语句是不可能的,因为它尝试在与 metric
关联的语句的条件中使用单个数据点属性
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
语句可以访问数据点的指标。
metric_statements {
context = "datapoint"
statements = [
"set(metric.description, \"test passed\") where attributes[\"test\"] == \"pass\"",
]
}
OTLP 信号的 protobuf 定义在 GitHub 上维护
尽可能将您的语句与语句意图转换的上下文关联。上下文是嵌套的,更高级别的上下文不必迭代任何较低级别的上下文。例如,尽管您可以使用 span
上下文修改与 span 关联的资源属性,但使用 resource
上下文效率更高。
output 块
output
块配置一组组件,用于将生成的遥测数据转发到这些组件。
支持以下参数
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
logs | list(otelcol.Consumer) | 要将日志发送到的消费者列表。 | [] | 否 |
metrics | list(otelcol.Consumer) | 要将指标发送到的消费者列表。 | [] | 否 |
traces | list(otelcol.Consumer) | 要将追踪发送到的消费者列表。 | [] | 否 |
您必须指定 output
块,但其所有参数都是可选的。默认情况下,遥测数据将被丢弃。相应地配置 metrics
、logs
和 traces
参数,以将遥测数据发送到其他组件。
debug_metrics 块
debug_metrics
块配置此组件生成的用于监控其状态的指标。
支持以下参数
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
disable_high_cardinality_metrics | boolean | 是否禁用某些高基数指标。 | true | 否 |
level | string | 控制包装的收集器发出的指标的详细程度。 | "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
,如果属性 test
不存在。
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]
}
}
重命名资源属性
有两种方法可以重命名属性键。一种方法是设置新属性并删除旧属性
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]
}
}
从日志正文的内容创建属性
此示例将属性 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]
}
}
合并两个属性
此示例将属性 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["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 正文
{
"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]
}
}
属性和状态代码的各种转换
该示例利用上下文效率,通过将转换与它打算转换的上下文分组。
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
具有可以被以下组件使用的导出
注意
连接某些组件可能不合理,或者组件可能需要进一步配置才能使连接正常工作。有关更多详细信息,请参阅链接的文档。