otelcol.connector.spanmetrics
otelcol.connector.spanmetrics
接收来自其他 otelcol
组件的 span 数据,并从 span 中聚合请求、错误和持续时间 (R.E.D) OpenTelemetry 指标。
请求计数计算为每个唯一维度集(包括错误)中看到的 span 数量。如果用户希望仅查看
service.name
和span.name
上的调用计数,则可以聚合多个指标。请求使用
calls
指标进行跟踪,其中status.code
数据点属性设置为Ok
。calls { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" }
错误计数是从状态代码为
Error
的 span 数量计算得出的。错误使用
calls
指标进行跟踪,其中status.code
数据点属性设置为Error
。calls { service.name="shipping", span.name="get_shipping/{shippingId}, span.kind="SERVER", status.code="Error" }
持续时间是根据 span 开始和结束时间之间的差异计算得出的,并插入到每个唯一维度集的相关持续时间直方图时间 buckets 中。
Span 持续时间使用
duration
直方图指标进行跟踪。duration { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" }
注意
otelcol.connector.spanmetrics
是上游 OpenTelemetry Collectorspanmetrics
连接器的包装器。Bug 报告或功能请求将在必要时重定向到上游仓库。
可以通过为多个 otelcol.connector.spanmetrics
组件赋予不同的标签来指定它们。
用法
otelcol.connector.spanmetrics "LABEL" {
histogram {
...
}
output {
metrics = [...]
}
}
参数
otelcol.connector.spanmetrics
支持以下参数
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
aggregation_temporality | 字符串 | 配置是否在刷新后重置指标。 | "CUMULATIVE" | 否 |
dimensions_cache_size | 数字 | 要缓存多少维度。 | 1000 | 否 |
exclude_dimensions | list(string) | 要从默认维度集中排除的维度列表。 | [] | 否 |
metrics_flush_interval | 持续时间 | 刷新生成指标的频率。 | "60s" | 否 |
metrics_expiration | 持续时间 | 指标被视为过时并从缓存中移除的时间段。 | "0s" | 否 |
metric_timestamp_cache_size | 数字 | 控制用于跟踪指标上次刷新时间的缓存大小。 | 1000 | 否 |
namespace | 字符串 | 指标命名空间。 | "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
仅与增量时效性 span 指标相关。它控制用于跟踪指标上次刷新时间的缓存大小。当指标从缓存中逐出时,其下一个数据点将指示序列中的“重置”。从增量转换为累积的下游组件可以通过将累积计数器设置回 0 来处理这些重置。
resource_metrics_key_attributes
可用于避免资源属性可能在服务重启时发生更改,从而导致指标计数器中断(和重复)的情况。资源不需要拥有所有属性。该列表必须包含足够的属性以正确识别唯一资源,否则可能会有从多个服务和 span 聚合数据的风险。例如:["service.name", "telemetry.sdk.language", "telemetry.sdk.name"]
。
块
在 otelcol.connector.spanmetrics
的定义中支持以下块
层次结构 | 块 | 描述 | 是否必需 |
---|---|---|---|
dimension | dimension | 除了默认维度之外要添加的维度。 | 否 |
events | events | 配置事件指标。 | 否 |
events > dimension | dimension | 要作为维度添加到事件指标的 Span 事件属性,除了默认维度和在顶层 dimension 块中配置的维度之外。 | 否 |
exemplars | exemplars | 配置如何将 exemplars 附加到直方图。 | 否 |
histogram | histogram | 配置从 span 持续时间派生的直方图。 | 是 |
histogram > explicit | explicit | 具有显式 buckets 的直方图配置。 | 否 |
histogram > exponential | exponential | 具有指数 buckets 的直方图配置。 | 否 |
output | output | 配置将遥测数据发送到哪里。 | 是 |
debug_metrics | debug_metrics | 配置此组件生成的用于监控其状态的指标。 | 否 |
必须指定 “exponential” 或 “explicit” 块之一
- 不允许同时指定 “exponential” 和 “explicit” 块。
- 不允许既不指定 “exponential” 也不指定 “explicit” 块。
dimension 块
dimension
块配置除了默认维度之外要添加的维度。
默认维度是
service.name
span.name
span.kind
status.code
默认维度始终添加。如果未指定其他维度,则只会添加默认维度。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
default | 字符串 | 如果属性丢失时使用的值。 | null | 否 |
name | 字符串 | 要查找的 Span 属性或资源属性。 | 是 |
otelcol.connector.spanmetrics
将在 span 的属性集合中查找 name
属性。如果未找到,将检查资源属性。
如果 span 和资源属性中都缺少该属性
- 如果未设置
default
,则将省略维度。 - 如果设置了
default
,则将添加维度,并且其值将设置为default
的值。
events 块
events
块配置 events
指标,该指标跟踪 span 事件。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
enabled | 布尔值 | 启用所有事件指标。 | false | 否 |
如果 enabled
设置为 true
,则至少需要一个 dimension
块。
histogram 块
histogram
块配置从 span 持续时间派生的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
disable | 布尔值 | 禁用所有直方图指标。 | false | 否 |
unit | 字符串 | 配置直方图单位。 | "ms" | 否 |
unit
支持的值为
"ms"
:毫秒"s"
:秒
exponential 块
exponential
块配置具有指数 buckets 的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
max_size | 数字 | 每个正数或负数范围的最大 buckets 数量。 | 160 | 否 |
explicit 块
explicit
块配置具有显式 buckets 的直方图。
支持以下属性
名称 | 类型 | 描述 | 默认值 | 是否必需 |
---|---|---|---|---|
buckets | list(duration) | 直方图 buckets 列表。 | ["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 | 否 |
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.connector.spanmetrics
是一个 OTLP 原生组件。因此,它的目标是保留 span 的资源属性。
例如,假设有两个传入的资源 span,它们具有相同的
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
资源属性附加到输出指标资源来保留它们。只会创建一个指标资源,因为两个 span 资源都具有相同的资源属性。{ "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
接收到两个传入的资源 span,每个 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
之前,从传入的 span 中删除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
之后,将每个资源属性复制为指标数据点属性。这样做的好处是资源属性将作为指标标签可见。但是,指标的 基数 可能会高得多,这可能会增加存储和查询它们的成本。以下示例使用 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
指标,传入 span 资源 scope 属性必须包含service.name
和service.instance.id
属性。
target_info
指标将为每个资源 scope 生成,同时 OpenTelemetry 指标名称和属性将被标准化以符合 Prometheus 命名规则。
兼容组件
otelcol.connector.spanmetrics
可以接受来自以下组件的参数
otelcol.connector.spanmetrics
具有可以被以下组件使用的导出
注意
连接某些组件可能不明智,或者组件可能需要进一步配置才能使连接正常工作。有关更多详细信息,请参阅链接的文档。