otelcol.connector.spanmetrics
otelcol.connector.spanmetrics
接受来自其他 otelcol
组件的 span 数据,并从 spans 中聚合请求、错误和持续时间(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 开始时间和结束时间之间的差值计算的,并插入到每个唯一维度的相关持续时间直方图时间桶中。
使用
duration
直方图度量的 span 持续时间进行跟踪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 | 字符串 | 配置是否在刷新后重置度量。 | "CUMULATIVE" | 否 |
dimensions_cache_size | 数字 | 缓存多少维度。 | 1000 | 否 |
exclude_dimensions | 字符串列表 | 要从默认维度集中排除的维度列表。 | [] | 否 |
metrics_flush_interval | 持续时间 | 多久刷新一次生成的度量。 | "60s" | 否 |
metrics_expiration | 持续时间 | 度量被视为过时并从缓存中删除的时间段。 | "0s" | 否 |
metric_timestamp_cache_size | 数字 | 控制用于跟踪上次度量刷新时间的缓存大小的缓存大小。 | 1000 | 否 |
namespace | 字符串 | 度量命名空间。 | "" | 否 |
resource_metrics_cache_size | 数字 | 存储每个服务的度量的缓存大小。 | 1000 | 否 |
resource_metrics_key_attributes | 字符串列表 | 限制用于创建度量时的资源属性。 | [] | 否 |
调整 dimensions_cache_size
可以提高 Alloy 处理内存使用率。
支持的 aggregation_temporality
值包括
"CUMULATIVE"
:指标在刷新后不会被重置。"DELTA"
:指标在刷新后将重置。
如果设置了namespace
,生成的指标名称将添加一个namespace.
前缀。
将metrics_expiration
设置为"0s"
表示指标永远不会过期。
resource_metrics_cache_size
主要适用于累计时间模式。它有助于避免因内存增长和指标时间戳错误重置而产生的问题。
metric_timestamp_cache_size
仅适用于delta时间跨度指标。它控制用于跟踪最后一次刷新指标所使用的缓存的大小。当一个指标从缓存中移除时,其下一个数据点将表示该序列中的“重置”。从delta转换为累计的时间序列组件可能会通过将累计计数器重置为0来处理这些重置。
resource_metrics_key_attributes
可以用来自避免以下情况:在服务重启期间资源属性可能会发生变化,导致指标计数器中断(以及重复)。资源不需要具有所有属性。列表必须包括足够的属性才能正确地标识唯一的资源,否则风险从多个服务中聚合数据以及在跨度中。
块
以下块在otelcol.connector.spanmetrics
定义内受到支持:
层次结构 | 块 | 描述 | 必需 |
---|---|---|---|
维度 | 维度 | 要添加的额外维度。 | 否 |
事件 | 事件 | 配置事件指标。 | 否 |
事件 > 维度 | 维度 | 要添加到事件指标中的事件属性,作为默认属性和顶层dimension 块中配置的额外属性之上。 | 否 |
示例 | 示例 | 配置如何将示例附加到直方图。 | 否 |
直方图 | 直方图 | 配置从跨度持续时间派生的直方图。 | 是 |
直方图 > 明确 | 明确 | 具有明确桶的直方图的配置。 | 否 |
直方图 > 指数 | 指数 | 具有指数桶的直方图的配置。 | 否 |
输出 | 输出 | 配置发送遥测数据的位置。 | 是 |
调试指标 | 调试指标 | 配置本组件生成以监控其状态的指标。 | 否 |
维度块
dimension
块配置要添加的额外维度。
默认维度是
service.name
span.name
span.kind
status.code
默认维度始终添加。如果不指定额外的维度,则仅添加默认维度。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
默认 | 字符串 | 如果缺少属性时使用的值。 | null | 否 |
名称 | 字符串 | 要查找的跨度属性或资源属性。 | 是 |
otelcol.connector.spanmetrics
将在跨度属性的集合中查找名称
属性。如果没有找到,将检查资源属性。
如果跨度和资源属性中均缺少属性
- 如果未设置
默认
,则省略维度。 - 如果设置了
默认
,则添加维度,并将其值设置为默认
的值。
事件块
events
块配置跟踪跨度事件的events
指标。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
启用 | 布尔值 | 启用所有事件指标。 | false | 否 |
如果启用设置为true,则至少需要一个维度
块。
直方图块
“直方图”块配置了从跨度持续时间导出的直方图。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
禁用 | 布尔值 | 禁用所有直方图指标。 | false | 否 |
单位 | 字符串 | 配置直方图单位。 | "ms" | 否 |
支持unit
的值有
"ms"
:毫秒"s"
:秒
指数块
“指数”块配置具有指数桶的直方图。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
max_size | 数字 | 正数或负数范围的每个桶的最大数量。 | 160 | 否 |
显式块
“显式”块配置具有显式桶的直方图。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
buckets | list(duration) | 直方图桶列表。 | ["2ms", "4ms", "6ms", "8ms", "10ms", "50ms", "100ms", "200ms", "400ms", "800ms", "1s", "1400ms", "2s", "5s", "10s", "15s"] | 否 |
示例块
“示例”块配置如何将示例附加到直方图。
以下属性受支持:
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
启用 | 布尔值 | 配置是否将示例添加到直方图。 | false | 否 |
max_per_data_point | 数字 | 限制可以添加到唯一维度集的示例数量。 | null | 否 |
max_per_data_point
可以帮助减少内存消耗。
输出块
“输出”块配置了一组组件,用于将最终遥测数据发送到。
支持的以下参数
名称 | 类型 | 描述 | 默认值 | 必需 |
---|---|---|---|---|
metrics | list(otelcol.Consumer) | 发送指标的目标消费者列表。 | [] | 否 |
必须指定“输出”块,但其所有参数都是可选的。默认情况下,遥测数据将被丢弃。根据需要配置“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 地址和端口号的属性。
注意
如果已配置,则仅在otelcol.exporter.*
和otelcol.receiver.*
组件中应用disable_high_cardinality_metrics
。
level
是 Alloy 中用于 OpenTelemetry Collector 的telemetry.metrics.level
功能标志的等价物。可能的值是 "none"
、"basic"
、"normal"
和 "detailed"
。
导出字段
以下字段被导出,并可由其他组件引用
名称 | 类型 | 描述 |
---|---|---|
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
接收到两个不同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 = env("OTLP_SERVER_ENDPOINT")
}
}
通过Prometheus远程写入发送指标
生成的指标可以发送到Grafana Mimir等Prometheus兼容的数据库。然而,需要执行额外的步骤来确保接收所有指标样本。这是因为 otelcol.connector.spanmetrics
旨在在它输出的指标中,保留资源属性。
不幸的是,Prometheus数据模型 没有资源属性的概念。这意味着如果 otelcol.connector.spanmetrics
输出具有相同指标属性,但不同资源属性的指标,otelcol.exporter.prometheus
将将指标转换为相同的指标系列。可以通过执行以下之一来解决这个问题
推荐做法:在
otelcol.connector.spanmetrics
之前,删除所有不影响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
可能会记录如下错误:因为已经处理了另一个具有相同时间戳但不同值的数据样本,拒绝样本(err-mimir-sample-duplicate-timestamp)
。
注意
要生成 Prometheus
target_info
指标,传入的跨度资源范围属性必须包含service.name
和service.instance.id
属性。对于每个资源范围将生成
target_info
指标,同时 OpenTelemetry 指标名称和属性将规范化,以符合 Prometheus 命名规则。
兼容组件
otelcol.connector.spanmetrics
可以接受以下组件的参数:
otelcol.connector.spanmetrics
有以下可以由以下组件消费的导出:
注意
连接某些组件可能不合适或有必要进行进一步配置以正确连接。请参阅相关文档以获取更多详细信息。