otelcol.connector.spanmetrics
otelcol.connector.spanmetrics
接受来自其他 otelcol
组件的跨度数据,并聚合来自这些跨度的请求、错误和持续时间 (R.E.D) OpenTelemetry 指标
请求 计数是根据每个独特的维度集(包括错误)看到的跨度数量计算得出的。例如,如果用户希望仅查看
service.name
和span.name
的调用计数,则可以聚合多个指标。请求使用一个
calls
指标进行跟踪,其status.code
数据点属性设置为Ok
calls { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" }
错误 计数是根据状态码为
Error
的跨度数量计算得出的。错误使用一个
calls
指标进行跟踪,其status.code
数据点属性设置为Error
calls { service.name="shipping", span.name="get_shipping/{shippingId}, span.kind="SERVER", status.code="Error" }
持续时间 是根据跨度的开始时间和结束时间之差计算得出的,并为每个独特的维度集插入到相应的持续时间直方图时间桶中。
跨度持续时间使用一个
duration
直方图指标进行跟踪duration { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" }
注意
otelcol.connector.spanmetrics
是上游 OpenTelemetry Collectorspanmetrics
连接器的一个封装。如有必要,错误报告或功能请求将被重定向到上游仓库。
可以通过赋予不同的标签来指定多个 otelcol.connector.spanmetrics
组件。
用法
otelcol.connector.spanmetrics "LABEL" {
histogram {
...
}
output {
metrics = [...]
}
}
参数
otelcol.connector.spanmetrics
支持以下参数
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
aggregation_temporality | string | 配置是否在刷新后重置指标。 | "CUMULATIVE" | 否 |
dimensions_cache_size | 数值 | 缓存多少维度。 | 1000 | 否 |
exclude_dimensions | list(string) | 要从默认维度集中排除的维度列表。 | [] | 否 |
metrics_flush_interval | 持续时间 | 多久刷新一次生成的指标。 | "60s" | 否 |
metrics_expiration | 持续时间 | 指标被视为过期并从缓存中移除的时间段。 | "0s" | 否 |
metric_timestamp_cache_size | 数值 | 控制用于跟踪指标上次刷新时间的缓存大小。 | 1000 | 否 |
namespace | string | 指标命名空间。 | "traces.span.metrics" | 否 |
resource_metrics_cache_size | 数值 | 存放服务指标的缓存大小。 | 1000 | 否 |
resource_metrics_key_attributes | list(string) | 限制用于创建指标的资源属性。 | [] | 否 |
调整 dimensions_cache_size
可以改善 Alloy 进程的内存使用量。
支持的 aggregation_temporality
值为
"CUMULATIVE"
:指标在刷新后将不重置。"DELTA"
:指标在刷新后将重置。
如果 namespace
已设置,生成的指标名称将添加 namespace.
前缀。
将 metrics_expiration
设置为 "0s"
意味着指标将永远不会过期。
resource_metrics_cache_size
主要与累积时间性相关。它有助于避免内存增加和指标时间戳重置不正确的问题。
metric_timestamp_cache_size
仅与增量时间性跨度指标相关。它控制用于跟踪指标上次刷新时间的缓存大小。当指标从缓存中被逐出时,其下一个数据点将指示序列中的“重置”。将增量转换为累积的下游组件可以通过将累积计数器重置为 0 来处理这些重置。
resource_metrics_key_attributes
可用于避免资源属性在服务重启后发生变化的情况,这可能导致指标计数器中断(和重复)。资源无需具备所有属性。列表必须包含足够的属性以正确识别唯一的资源,否则可能会聚合来自多个服务和跨度的数据。例如,["service.name", "telemetry.sdk.language", "telemetry.sdk.name"]
。
块
在 otelcol.connector.spanmetrics
的定义中支持以下块
层级 | 块 | 描述 | 是否必需 |
---|---|---|---|
dimension | dimension | 除默认维度外要添加的维度。 | 否 |
events | events | 配置事件指标。 | 否 |
events > dimension | dimension | 要作为维度添加到事件指标的跨度事件属性,在默认属性和在顶层 dimension 块中配置的属性之上。 | 否 |
exemplars | exemplars | 配置如何将 exemplars 附加到直方图。 | 否 |
histogram | histogram | 配置从跨度持续时间派生的直方图。 | 是 |
histogram > explicit | explicit | 配置带有显式桶的直方图。 | 否 |
histogram > exponential | exponential | 配置带有指数桶的直方图。 | 否 |
output | output | 配置遥测数据的发送位置。 | 是 |
debug_metrics | debug_metrics | 配置此组件生成的用于监控其状态的指标。 | 否 |
必须指定“ exponential” 或 “ explicit” 块
- 同时指定“ exponential” 和 “ explicit” 块是不允许的。
- 既不指定“ exponential” 也不指定“ explicit” 块是不允许的。
dimension 块
该 dimension
块配置了除了默认维度外要添加的维度。
默认维度包括
service.name
span.name
span.kind
status.code
默认维度总是添加的。如果未指定额外维度,则仅添加默认维度。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
default | string | 属性缺失时使用的值。 | null | 否 |
name | string | 要查找的跨度属性或资源属性。 | 是 |
otelcol.connector.spanmetrics
将在跨度的属性集合中查找 name
属性。如果未找到,将检查资源属性。
如果属性在跨度和资源属性中都缺失
- 如果
default
未设置,则该维度将被省略。 - 如果
default
已设置,则该维度将被添加,并且其值将设置为default
的值。
events 块
该 events
块配置 events
指标,用于跟踪 span events。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
enabled | 布尔值 | 启用所有事件指标。 | false | 否 |
如果 enabled
设置为 true
,则至少需要一个 dimension
块。
histogram 块
该 histogram
块配置了从跨度持续时间派生的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
disable | 布尔值 | 禁用所有直方图指标。 | false | 否 |
unit | string | 配置直方图单位。 | "ms" | 否 |
支持的 unit
值为
"ms"
:毫秒"s"
:秒
exponential 块
该 exponential
块配置了带有指数桶的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
max_size | 数值 | 每个正数或负数范围内的最大桶数量。 | 160 | 否 |
explicit 块
该 explicit
块配置了带有显式桶的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
buckets | list(duration) | 直方图桶列表。 | ["2ms", "4ms", "6ms", "8ms", "10ms", "50ms", "100ms", "200ms", "400ms", "800ms", "1s", "1400ms", "2s", "5s", "10s", "15s"] | 否 |
exemplars 块
该 exemplars
块配置了如何将 exemplars 附加到直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
enabled | 布尔值 | 配置是否将 exemplars 添加到直方图。 | false | 否 |
max_per_data_point | 数值 | 限制可以添加到独特维度集中的 exemplars 数量。 | null | 否 |
max_per_data_point
有助于减少内存消耗。
output 块
该 output
块配置了一组用于转发结果遥测数据的组件。
支持以下参数
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
metrics | list(otelcol.Consumer) | 要将指标发送到的消费者列表。 | [] | 否 |
您必须指定 output
块,但其所有参数都是可选的。默认情况下,遥测数据会被丢弃。请相应地配置 metrics
参数以将遥测数据发送到其他组件。
debug_metrics 块
该 debug_metrics
块配置了此组件生成的用于监控其状态的指标。
支持以下参数
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
disable_high_cardinality_metrics | 布尔值 | 是否禁用某些高基数指标。 | true | 否 |
disable_high_cardinality_metrics
是 Grafana Alloy 的等效项,对应于 OpenTelemetry Collector 中的 telemetry.disableHighCardinalityMetrics
特性门控。它移除了可能导致高基数指标的属性。例如,关于 HTTP 和 gRPC 连接的指标中,带有 IP 地址和端口号的属性会被移除。
注意
如果配置了,
disable_high_cardinality_metrics
仅适用于otelcol.exporter.*
和otelcol.receiver.*
组件。
导出的字段
导出以下字段,可供其他组件引用
名称 | 类型 | 描述 |
---|---|---|
input | otelcol.Consumer | 其他组件可用于发送遥测数据的值。 |
input
接受 otelcol.Consumer
追踪遥测数据。它不接受指标和日志。
资源属性的处理
otelcol.connector.spanmetrics
是一个 OTLP 原生组件。因此,它旨在保留跨度的资源属性。
例如,假设有两个传入的资源跨度,它们具有相同的
service.name
和k8s.pod.name
资源属性。{ "resourceSpans": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "first" } } ] }, "scopeSpans": [ { "spans": [ { "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", "span_id": "086e83747d0e381e", "name": "TestSpan", "attributes": [ { "key": "attribute1", "value": { "intValue": "78" } } ] } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "first" } } ] }, "scopeSpans": [ { "spans": [ { "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", "span_id": "086e83747d0e381b", "name": "TestSpan", "attributes": [ { "key": "attribute1", "value": { "intValue": "78" } } ] } ] } ] } ] }
otelcol.connector.spanmetrics
将通过将其附加到输出指标资源来保留传入的service.name
和k8s.pod.name
资源属性。只会创建一个指标资源,因为两个跨度资源具有相同的资源属性。{ "resourceMetrics": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "first" } } ] }, "scopeMetrics": [ { "scope": { "name": "spanmetricsconnector" }, "metrics": [ { "name": "calls", "sum": { "dataPoints": [ { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "span.name", "value": { "stringValue": "TestSpan" } }, { "key": "span.kind", "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } }, { "key": "status.code", "value": { "stringValue": "STATUS_CODE_UNSET" } } ], "startTimeUnixNano": "1702582936761872000", "timeUnixNano": "1702582936761872012", "asInt": "2" } ], "aggregationTemporality": 2, "isMonotonic": true } } ] } ] } ] }
现在假设
otelcol.connector.spanmetrics
接收到两个传入的资源 spans,每个 span 的k8s.pod.name
资源属性具有不同的值。{ "resourceSpans": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "first" } } ] }, "scopeSpans": [ { "spans": [ { "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", "span_id": "086e83747d0e381e", "name": "TestSpan", "attributes": [ { "key": "attribute1", "value": { "intValue": "78" } } ] } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "second" } } ] }, "scopeSpans": [ { "spans": [ { "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", "span_id": "086e83747d0e381b", "name": "TestSpan", "attributes": [ { "key": "attribute1", "value": { "intValue": "78" } } ] } ] } ] } ] }
为了保留所有资源属性的值,
otelcol.connector.spanmetrics
将生成两个资源指标。每个资源指标的k8s.pod.name
资源属性都将具有不同的值。这样在生成指标时就不会丢失任何资源属性。{ "resourceMetrics": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "first" } } ] }, "scopeMetrics": [ { "scope": { "name": "spanmetricsconnector" }, "metrics": [ { "name": "calls", "sum": { "dataPoints": [ { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "span.name", "value": { "stringValue": "TestSpan" } }, { "key": "span.kind", "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } }, { "key": "status.code", "value": { "stringValue": "STATUS_CODE_UNSET" } } ], "startTimeUnixNano": "1702582936761872000", "timeUnixNano": "1702582936761872012", "asInt": "1" } ], "aggregationTemporality": 2, "isMonotonic": true } } ] } ] }, { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "k8s.pod.name", "value": { "stringValue": "second" } } ] }, "scopeMetrics": [ { "scope": { "name": "spanmetricsconnector" }, "metrics": [ { "name": "calls", "sum": { "dataPoints": [ { "attributes": [ { "key": "service.name", "value": { "stringValue": "TestSvcName" } }, { "key": "span.name", "value": { "stringValue": "TestSpan" } }, { "key": "span.kind", "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } }, { "key": "status.code", "value": { "stringValue": "STATUS_CODE_UNSET" } } ], "startTimeUnixNano": "1702582936761872000", "timeUnixNano": "1702582936761872012", "asInt": "1" } ], "aggregationTemporality": 2, "isMonotonic": true } } ] } ] } ] }
组件健康状态
otelcol.connector.spanmetrics
仅在给定无效配置时报告为不健康。
调试信息
otelcol.connector.spanmetrics
不暴露任何组件特定的调试信息。
示例
显式直方图和额外维度
在下面的示例中,http.status_code
和 http.method
是额外的维度,在
service.name
span.name
span.kind
status.code
otelcol.receiver.otlp "default" {
http {}
grpc {}
output {
traces = [otelcol.connector.spanmetrics.default.input]
}
}
otelcol.connector.spanmetrics "default" {
// Since a default is not provided, the http.status_code dimension will be omitted
// if the span does not contain http.status_code.
dimension {
name = "http.status_code"
}
// If the span is missing http.method, the connector will insert
// the http.method dimension with value 'GET'.
dimension {
name = "http.method"
default = "GET"
}
dimensions_cache_size = 333
aggregation_temporality = "DELTA"
histogram {
unit = "s"
explicit {
buckets = ["333ms", "777s", "999h"]
}
}
// The period on which all metrics (whose dimension keys remain in cache) will be emitted.
metrics_flush_interval = "33s"
namespace = "test.namespace"
output {
metrics = [otelcol.exporter.otlp.production.input]
}
}
otelcol.exporter.otlp "production" {
client {
endpoint = sys.env("OTLP_SERVER_ENDPOINT")
}
}
通过 Prometheus 远程写入发送指标
生成的指标可以发送到与 Prometheus 兼容的数据库,例如 Grafana Mimir。但是,为了确保接收到所有指标样本,需要额外的步骤。这是因为 otelcol.connector.spanmetrics
旨在其输出的指标中 保留资源属性。
不幸的是,Prometheus 数据模型 没有资源属性的概念。这意味着如果 otelcol.connector.spanmetrics
输出具有相同指标属性但资源属性不同的指标,otelcol.exporter.prometheus
会将这些指标转换为相同的指标序列。可以通过执行以下 任一 方式来解决此问题
推荐方法: 在
otelcol.connector.spanmetrics
之前,移除传入 spans 中所有otelcol.connector.spanmetrics
不需要使用的资源属性。otelcol.receiver.otlp "default" { http {} grpc {} output { traces = [otelcol.processor.transform.default.input] } } // Remove all resource attributes except the ones which // the otelcol.connector.spanmetrics needs. // If this is not done, otelcol.exporter.prometheus may fail to // write some samples due to an "err-mimir-sample-duplicate-timestamp" error. // This is because the spanmetricsconnector will create a new // metrics resource scope for each traces resource scope. otelcol.processor.transform "default" { error_mode = "ignore" trace_statements { context = "resource" statements = [ // We keep only the "service.name" and "special.attr" resource attributes, // because they are the only ones which otelcol.connector.spanmetrics needs. // // There is no need to list "span.name", "span.kind", and "status.code" // here because they are properties of the span (and not resource attributes): // https://github.com/open-telemetry/opentelemetry-proto/blob/v1.0.0/opentelemetry/proto/trace/v1/trace.proto `keep_keys(attributes, ["service.name", "special.attr"])`, ] } output { traces = [otelcol.connector.spanmetrics.default.input] } } otelcol.connector.spanmetrics "default" { histogram { explicit {} } dimension { name = "special.attr" } output { metrics = [otelcol.exporter.prometheus.default.input] } } otelcol.exporter.prometheus "default" { forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write "mimir" { endpoint { url = "http://mimir:9009/api/v1/push" } }
或者,在
otelcol.connector.spanmetrics
之后,将每个资源属性复制为指标数据点属性。这样做的好处是资源属性将作为指标标签可见。但是,指标的 基数 (cardinality) 可能会高得多,这可能会增加存储和查询它们的成本。下面的示例使用了 merge_maps OTTL 函数。otelcol.receiver.otlp "default" { http {} grpc {} output { traces = [otelcol.connector.spanmetrics.default.input] } } otelcol.connector.spanmetrics "default" { histogram { explicit {} } dimension { name = "special.attr" } output { metrics = [otelcol.processor.transform.default.input] } } // Insert resource attributes as metric data point attributes. otelcol.processor.transform "default" { error_mode = "ignore" metric_statements { context = "datapoint" statements = [ // "insert" means that a metric datapoint attribute will be inserted // only if an attribute with the same key does not already exist. `merge_maps(attributes, resource.attributes, "insert")`, ] } output { metrics = [otelcol.exporter.prometheus.default.input] } } otelcol.exporter.prometheus "default" { forward_to = [prometheus.remote_write.mimir.receiver] } prometheus.remote_write "mimir" { endpoint { url = "http://mimir:9009/api/v1/push" } }
如果未以上述任一方式处理资源属性,则 prometheus.remote_write
可能会记录如下错误:the sample has been rejected because another sample with the same timestamp, but a different value, has already been ingested (err-mimir-sample-duplicate-timestamp)
。
注意
为了生成 Prometheus 的
target_info
指标,传入 spans 的资源范围属性必须包含service.name
和service.instance.id
属性。
target_info
指标将为每个资源范围生成,同时 OpenTelemetry 指标名称和属性将被规范化以符合 Prometheus 命名规则。
兼容组件
otelcol.connector.spanmetrics
可以接受来自以下组件的参数
otelcol.connector.spanmetrics
具有可供以下组件使用的导出项
注意
连接某些组件可能不合理,或者组件可能需要进一步配置才能使连接正常工作。有关更多详细信息,请参阅链接的文档。