嗨!我想提出一种改进 OpenTelemetry 指标和跟踪自动配置方式的建议。这与问题相关:https://github.com/spring-projects/spring-boot/issues/30156以及我在最后的评论。
作为起点,跟踪OpenTelemetryAutoConfiguration
会设置 OpenTelemetry 的一个实例并获取跟踪提供程序列表。这是指定不受支持的导出器(例如,OtlpGrpcSpanExporter
代替 brave/zipkin/wavefront)的好方法。
但是OtlpMetricsExportAutoConfiguration
根本不使用 OpenTelemetry 实例,而是OtlpMeterRegistry
根据配置注册。目前我无法指定OtlpGrpcMetricExporter
它想要使用的。
我的建议是拥有单独的基本 OpenTelemetry 自动配置、OpenTelemetry 跟踪自动配置以及最终的 OpenTelemetry 指标自动配置。
OpenTeleletry 的主要自动配置如下:
@Bean
@ConditionalOnMissingBean
// puts the sevice name based on the spring.application.name, additionally reads in additional attributes like OtlpMetricsExportAutoConfiguration does
fun otelResource(environment: Environment): Resource {
val applicationName = environment.getProperty("spring.application.name", "application")
return Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))
}
@Bean
@ConditionalOnMissingBean
fun openTelemetry(
sdkTracerProvider: ObjectProvider<SdkTracerProvider>,
sdkMeterProvider: ObjectProvider<SdkMeterProvider>, // This is the new bit - custom SdkMeterProvider that is set up like SdkTracerProvider allowing me to create a OtlpGrpcMetricExporter bean
contextPropagators: ObjectProvider<ContextPropagators>
): OpenTelemetry {
val builder = OpenTelemetrySdk.builder()
contextPropagators.ifUnique {
builder.setPropagators(it)
}
sdkMeterProvider.ifUnique {
builder.setMeterProvider(it)
}
sdkTracerProvider.ifUnique {
// set by org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration.otelSdkTracerProvider
builder.setTracerProvider(it)
}
return builder.build()
}
这otelResource
是为指标和跟踪指定服务名称和其他参数的一致方法。OpenTelemetry 接受附加信息sdkMeterProvider
并允许设置自定义信息MetricExporter
。
这OtlpMetricsExportAutoConfiguration
将创建SdkMeterProvider
出口商和注册中心:
@Bean
fun sdkMeterProvider(
metricExportersProvider: ObjectProvider<List<MetricExporter>>,
otelResource: Resource
): SdkMeterProvider {
// from https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java
val meterProviderBuilder = SdkMeterProvider.builder()
val interval = properties.metrics.interval
metricExportersProvider.getIfAvailable { emptyList() }
.map { metricExporter ->
val metricReaderBuilder = PeriodicMetricReader.builder(metricExporter)
if (interval != null) {
metricReaderBuilder.setInterval(interval)
}
metricReaderBuilder.build()
}
.forEach { reader ->
meterProviderBuilder.registerMetricReader(reader)
}
return meterProviderBuilder.setResource(otelResource).build()
}
@Bean
fun otelMeterRegistry(openTelemetry: OpenTelemetry): MeterRegistry {
return OpenTelemetryMeterRegistry.create(openTelemetry)
}
@Bean
@ConditionalOnMissingBean(MetricExporter::class)
fun metricExporter(...) : OtlpHttpMetricExporter {
// ...
}
因此,现在跟踪和指标都使用同一个 OpenTelemetry 实例,该实例通过单个 OpenTelemetry 资源实例设置。默认指标导出器是OtlpHttpMetricExporter
,可以使用 GRPC 版本覆盖。