This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new 34981c9606 add dubbo-spring-boot-observability-starter (#11579)
34981c9606 is described below

commit 34981c9606facf63000264a71d2a69b93afe2fd1
Author: ShenFeng312 <[email protected]>
AuthorDate: Thu Mar 2 06:37:06 2023 +0800

    add dubbo-spring-boot-observability-starter (#11579)
    
    * add dubbo-spring-boot-observability-starter
    
    * add License and fix codestyle
    
    * Add License
    
    * Add dubbo-spring-boot-observability-starter to dubbo-dependencies-all
    
    * Changes following review
    
    * Changes following review
    
    * Polish pom
    
    * Changes following review
    
    * Add dubbo-metrics-default in dubbo-spring-boot-observability-starter
    
    * Remove author tag
    
    * Polish pom
---
 .../dubbo-demo-spring-boot-consumer/pom.xml        |   9 +-
 .../demo/consumer/ObservationConfiguration.java    | 215 -----------------
 .../dubbo-demo-spring-boot-provider/pom.xml        |   8 +-
 .../demo/provider/ObservationConfiguration.java    | 214 -----------------
 dubbo-demo/dubbo-demo-spring-boot/pom.xml          |  20 ++
 dubbo-dependencies-bom/pom.xml                     |   1 +
 dubbo-distribution/dubbo-bom/pom.xml               |   5 +
 .../pom.xml                                        |  77 ++++++
 .../ConditionalOnDubboTracingEnable.java           |  34 +++
 .../DubboMicrometerTracingAutoConfiguration.java   |  78 ++++++
 .../DubboObservationAutoConfiguration.java         | 153 ++++++++++++
 .../autoconfigure/ObservationHandlerGrouping.java  |  74 ++++++
 .../ObservationRegistryPostProcessor.java          |  54 +++++
 .../brave/BraveAutoConfiguration.java              | 261 +++++++++++++++++++++
 .../otel/OpenTelemetryAutoConfiguration.java       | 257 ++++++++++++++++++++
 .../config/DubboTracingProperties.java             | 191 +++++++++++++++
 .../META-INF/spring-configuration-metadata.json    |  82 +++++++
 .../src/main/resources/META-INF/spring.factories   |   6 +
 ...rk.boot.autoconfigure.AutoConfiguration.imports |   4 +
 dubbo-spring-boot/pom.xml                          |   7 +
 dubbo-test/dubbo-dependencies-all/pom.xml          |   5 +
 21 files changed, 1318 insertions(+), 437 deletions(-)

diff --git 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml 
b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml
index 6eec35ee18..626b9d9825 100644
--- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml
+++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/pom.xml
@@ -134,15 +134,16 @@
         </dependency>
 
         <!-- Observabililty -->
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metrics-default</artifactId>
-        </dependency>
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-tracing-bridge-otel</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-spring-boot-observability-starter</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java
 
b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java
deleted file mode 100644
index 717e36a8f9..0000000000
--- 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-consumer/src/main/java/org/apache/dubbo/springboot/demo/consumer/ObservationConfiguration.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.springboot.demo.consumer;
-
-
-import io.micrometer.core.instrument.MeterRegistry;
-import 
io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
-import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
-import io.micrometer.observation.ObservationHandler;
-import io.micrometer.observation.ObservationRegistry;
-import io.micrometer.tracing.Tracer;
-import io.micrometer.tracing.handler.DefaultTracingObservationHandler;
-import 
io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler;
-import 
io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler;
-import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
-import io.micrometer.tracing.otel.bridge.ArrayListSpanProcessor;
-import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
-import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
-import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
-import io.micrometer.tracing.otel.bridge.OtelPropagator;
-import io.micrometer.tracing.otel.bridge.OtelTracer;
-import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
-import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
-import io.micrometer.tracing.propagation.Propagator;
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.context.ContextStorage;
-import io.opentelemetry.context.propagation.ContextPropagators;
-import io.opentelemetry.extension.trace.propagation.B3Propagator;
-import io.opentelemetry.sdk.OpenTelemetrySdk;
-import io.opentelemetry.sdk.resources.Resource;
-import io.opentelemetry.sdk.trace.SdkTracerProvider;
-import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
-import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import java.util.Collections;
-
-import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn;
-
-@Configuration
-public class ObservationConfiguration {
-    /**
-     * Default value for application name if {@code spring.application.name} 
is not set.
-     */
-    private static final String DEFAULT_APPLICATION_NAME = "application";
-
-    @javax.annotation.Resource
-    private ApplicationModel applicationModel;
-
-    @Bean
-    ObservationRegistry observationRegistry() {
-        ObservationRegistry observationRegistry = ObservationRegistry.create();
-        applicationModel.getBeanFactory().registerBean(observationRegistry);
-        return observationRegistry;
-
-    }
-
-    @Bean
-    MeterRegistry meterRegistry() {
-        return new SimpleMeterRegistry();
-    }
-
-    @Bean
-    ArrayListSpanProcessor spanExporter() {
-        return new ArrayListSpanProcessor();
-    }
-
-    @Bean
-    SdkTracerProvider sdkTracerProvider(Environment environment) {
-        String applicationName = 
environment.getProperty("dubbo.application.name", DEFAULT_APPLICATION_NAME);
-        return SdkTracerProvider.builder().setSampler(alwaysOn())
-            
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter()).build())
-            
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, 
applicationName)))
-            .build();
-    }
-
-    @Bean
-    ContextPropagators contextPropagators() {
-        return ContextPropagators.create(B3Propagator.injectingSingleHeader());
-    }
-
-    @Bean
-    OpenTelemetrySdk openTelemetrySdk(SdkTracerProvider sdkTracerProvider) {
-        return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider)
-            .setPropagators(contextPropagators()).build();
-    }
-
-    @Bean
-    io.opentelemetry.api.trace.Tracer otelTracer(OpenTelemetrySdk 
openTelemetrySdk) {
-        return openTelemetrySdk.getTracerProvider()
-            .get("io.micrometer.micrometer-tracing");
-    }
-
-    @Bean
-    OtelCurrentTraceContext otelCurrentTraceContext() {
-        return new OtelCurrentTraceContext();
-    }
-
-    Slf4JEventListener slf4JEventListener() {
-        return new Slf4JEventListener();
-    }
-
-    Slf4JBaggageEventListener slf4JBaggageEventListener() {
-        return new Slf4JBaggageEventListener(Collections.emptyList());
-    }
-
-    @Bean
-    OtelTracer tracer(io.opentelemetry.api.trace.Tracer otelTracer, 
OtelCurrentTraceContext otelCurrentTraceContext) {
-        Slf4JEventListener slf4JEventListener = slf4JEventListener();
-        Slf4JBaggageEventListener slf4JBaggageEventListener = 
slf4JBaggageEventListener();
-        OtelTracer.EventPublisher eventPublisher = event -> {
-            slf4JEventListener.onEvent(event);
-            slf4JBaggageEventListener.onEvent(event);
-        };
-        ContextStorage.addWrapper(new 
EventPublishingContextWrapper(eventPublisher));
-        return new OtelTracer(otelTracer, otelCurrentTraceContext, 
eventPublisher, new OtelBaggageManager(otelCurrentTraceContext, 
Collections.emptyList(), Collections.emptyList()));
-    }
-
-    @Bean
-    Propagator propagator(io.opentelemetry.api.trace.Tracer otelTracer) {
-        return new OtelPropagator(contextPropagators(), otelTracer);
-    }
-
-    @Bean
-    ObservationHandlerRegistrar 
observationHandlerRegistrar(ObservationRegistry observationRegistry, OtelTracer 
tracer, Propagator propagator, MeterRegistry meterRegistry) {
-        return new ObservationHandlerRegistrar(observationRegistry, tracer, 
propagator, meterRegistry);
-    }
-
-    @Bean
-    MetricsDumper metricsDumper(MeterRegistry meterRegistry) {
-        return new MetricsDumper(meterRegistry);
-    }
-
-    @Bean
-    TracesDumper tracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) {
-        return new TracesDumper(arrayListSpanProcessor);
-    }
-
-    static class ObservationHandlerRegistrar {
-
-        private final ObservationRegistry observationRegistry;
-
-        private final Tracer tracer;
-
-        private final Propagator propagator;
-
-        private final MeterRegistry meterRegistry;
-
-        ObservationHandlerRegistrar(ObservationRegistry observationRegistry, 
Tracer tracer, Propagator propagator, MeterRegistry meterRegistry) {
-            this.observationRegistry = observationRegistry;
-            this.tracer = tracer;
-            this.propagator = propagator;
-            this.meterRegistry = meterRegistry;
-        }
-
-        @PostConstruct
-        void setup() {
-            observationRegistry.observationConfig().observationHandler(new 
TracingAwareMeterObservationHandler<>(new 
DefaultMeterObservationHandler(meterRegistry), tracer));
-            observationRegistry.observationConfig()
-                .observationHandler(new 
ObservationHandler.FirstMatchingCompositeObservationHandler(new 
PropagatingReceiverTracingObservationHandler<>(tracer, propagator), new 
PropagatingSenderTracingObservationHandler<>(tracer, propagator), new 
DefaultTracingObservationHandler(tracer)));
-        }
-    }
-
-
-    static class MetricsDumper {
-        private final MeterRegistry meterRegistry;
-
-        MetricsDumper(MeterRegistry meterRegistry) {
-            this.meterRegistry = meterRegistry;
-        }
-
-        @PreDestroy
-        void dumpMetrics() {
-            System.out.println("==== METRICS ====");
-            this.meterRegistry.getMeters().forEach(meter -> 
System.out.println(" - Metric type \t[" + meter.getId().getType() + "],\tname 
[" + meter.getId().getName() + "],\ttags " + meter.getId().getTags() + 
",\tmeasurements " + meter.measure()));
-            System.out.println("=================");
-        }
-    }
-
-
-    static class TracesDumper {
-        private final ArrayListSpanProcessor arrayListSpanProcessor;
-
-        TracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) {
-            this.arrayListSpanProcessor = arrayListSpanProcessor;
-        }
-
-        @PreDestroy
-        void dumpTraces() {
-            System.out.println("==== TRACES ====");
-            this.arrayListSpanProcessor.spans().forEach(System.out::println);
-            System.out.println("=================");
-        }
-    }
-}
diff --git 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml 
b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml
index fcb8ec1b11..ba32f8c70e 100644
--- a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml
+++ b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/pom.xml
@@ -133,14 +133,14 @@
         </dependency>
 
         <!-- Observability -->
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metrics-default</artifactId>
-        </dependency>
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-tracing-bridge-otel</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-spring-boot-observability-starter</artifactId>
+        </dependency>
 
     </dependencies>
 
diff --git 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java
 
b/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java
deleted file mode 100644
index 722427fcc5..0000000000
--- 
a/dubbo-demo/dubbo-demo-spring-boot/dubbo-demo-spring-boot-provider/src/main/java/org/apache/dubbo/springboot/demo/provider/ObservationConfiguration.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.dubbo.springboot.demo.provider;
-
-
-import io.micrometer.core.instrument.MeterRegistry;
-import 
io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
-import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
-import io.micrometer.observation.ObservationHandler;
-import io.micrometer.observation.ObservationRegistry;
-import io.micrometer.tracing.Tracer;
-import io.micrometer.tracing.handler.DefaultTracingObservationHandler;
-import 
io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler;
-import 
io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler;
-import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
-import io.micrometer.tracing.otel.bridge.ArrayListSpanProcessor;
-import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
-import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
-import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
-import io.micrometer.tracing.otel.bridge.OtelPropagator;
-import io.micrometer.tracing.otel.bridge.OtelTracer;
-import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
-import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
-import io.micrometer.tracing.propagation.Propagator;
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.context.ContextStorage;
-import io.opentelemetry.context.propagation.ContextPropagators;
-import io.opentelemetry.extension.trace.propagation.B3Propagator;
-import io.opentelemetry.sdk.OpenTelemetrySdk;
-import io.opentelemetry.sdk.resources.Resource;
-import io.opentelemetry.sdk.trace.SdkTracerProvider;
-import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
-import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import java.util.Collections;
-
-import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn;
-
-@Configuration
-public class ObservationConfiguration {
-
-    /**
-     * Default value for application name if {@code spring.application.name} 
is not set.
-     */
-    private static final String DEFAULT_APPLICATION_NAME = "application";
-    @javax.annotation.Resource
-    private ApplicationModel applicationModel;
-
-    @Bean
-    ObservationRegistry observationRegistry() {
-        ObservationRegistry observationRegistry = ObservationRegistry.create();
-        applicationModel.getBeanFactory().registerBean(observationRegistry);
-        return observationRegistry;
-    }
-
-    @Bean
-    MeterRegistry meterRegistry() {
-        return new SimpleMeterRegistry();
-    }
-
-    @Bean
-    ArrayListSpanProcessor spanExporter() {
-        return new ArrayListSpanProcessor();
-    }
-
-    @Bean
-    SdkTracerProvider sdkTracerProvider(Environment environment) {
-        String applicationName = 
environment.getProperty("dubbo.application.name", DEFAULT_APPLICATION_NAME);
-        return SdkTracerProvider.builder().setSampler(alwaysOn())
-            
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter()).build())
-            
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, 
applicationName)))
-            .build();
-    }
-
-    @Bean
-    ContextPropagators contextPropagators() {
-        return ContextPropagators.create(B3Propagator.injectingSingleHeader());
-    }
-
-    @Bean
-    OpenTelemetrySdk openTelemetrySdk(SdkTracerProvider sdkTracerProvider) {
-        return OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider)
-            .setPropagators(contextPropagators()).build();
-    }
-
-    @Bean
-    io.opentelemetry.api.trace.Tracer otelTracer(OpenTelemetrySdk 
openTelemetrySdk) {
-        return openTelemetrySdk.getTracerProvider()
-            .get("io.micrometer.micrometer-tracing");
-    }
-
-    @Bean
-    OtelCurrentTraceContext otelCurrentTraceContext() {
-        return new OtelCurrentTraceContext();
-    }
-
-    Slf4JEventListener slf4JEventListener() {
-        return new Slf4JEventListener();
-    }
-
-    Slf4JBaggageEventListener slf4JBaggageEventListener() {
-        return new Slf4JBaggageEventListener(Collections.emptyList());
-    }
-
-    @Bean
-    OtelTracer tracer(io.opentelemetry.api.trace.Tracer otelTracer, 
OtelCurrentTraceContext otelCurrentTraceContext) {
-        Slf4JEventListener slf4JEventListener = slf4JEventListener();
-        Slf4JBaggageEventListener slf4JBaggageEventListener = 
slf4JBaggageEventListener();
-        OtelTracer.EventPublisher eventPublisher = event -> {
-            slf4JEventListener.onEvent(event);
-            slf4JBaggageEventListener.onEvent(event);
-        };
-        ContextStorage.addWrapper(new 
EventPublishingContextWrapper(eventPublisher));
-        return new OtelTracer(otelTracer, otelCurrentTraceContext, 
eventPublisher, new OtelBaggageManager(otelCurrentTraceContext, 
Collections.emptyList(), Collections.emptyList()));
-    }
-
-    @Bean
-    Propagator propagator(io.opentelemetry.api.trace.Tracer otelTracer) {
-        return new OtelPropagator(contextPropagators(), otelTracer);
-    }
-
-    @Bean
-    ObservationHandlerRegistrar 
observationHandlerRegistrar(ObservationRegistry observationRegistry, OtelTracer 
tracer, Propagator propagator, MeterRegistry meterRegistry) {
-        return new ObservationHandlerRegistrar(observationRegistry, tracer, 
propagator, meterRegistry);
-    }
-
-    @Bean
-    MetricsDumper metricsDumper(MeterRegistry meterRegistry) {
-        return new MetricsDumper(meterRegistry);
-    }
-
-    @Bean
-    TracesDumper tracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) {
-        return new TracesDumper(arrayListSpanProcessor);
-    }
-
-    static class ObservationHandlerRegistrar {
-
-        private final ObservationRegistry observationRegistry;
-
-        private final Tracer tracer;
-
-        private final Propagator propagator;
-
-        private final MeterRegistry meterRegistry;
-
-        ObservationHandlerRegistrar(ObservationRegistry observationRegistry, 
Tracer tracer, Propagator propagator, MeterRegistry meterRegistry) {
-            this.observationRegistry = observationRegistry;
-            this.tracer = tracer;
-            this.propagator = propagator;
-            this.meterRegistry = meterRegistry;
-        }
-
-        @PostConstruct
-        void setup() {
-            observationRegistry.observationConfig().observationHandler(new 
TracingAwareMeterObservationHandler<>(new 
DefaultMeterObservationHandler(meterRegistry), tracer));
-            observationRegistry.observationConfig()
-                .observationHandler(new 
ObservationHandler.FirstMatchingCompositeObservationHandler(new 
PropagatingReceiverTracingObservationHandler<>(tracer, propagator), new 
PropagatingSenderTracingObservationHandler<>(tracer, propagator), new 
DefaultTracingObservationHandler(tracer)));
-        }
-    }
-
-
-    static class MetricsDumper {
-        private final MeterRegistry meterRegistry;
-
-        MetricsDumper(MeterRegistry meterRegistry) {
-            this.meterRegistry = meterRegistry;
-        }
-
-        @PreDestroy
-        void dumpMetrics() {
-            System.out.println("==== METRICS ====");
-            this.meterRegistry.getMeters().forEach(meter -> 
System.out.println(" - Metric type \t[" + meter.getId().getType() + "],\tname 
[" + meter.getId().getName() + "],\ttags " + meter.getId().getTags() + 
",\tmeasurements " + meter.measure()));
-            System.out.println("=================");
-        }
-    }
-
-
-    static class TracesDumper {
-        private final ArrayListSpanProcessor arrayListSpanProcessor;
-
-        TracesDumper(ArrayListSpanProcessor arrayListSpanProcessor) {
-            this.arrayListSpanProcessor = arrayListSpanProcessor;
-        }
-
-        @PreDestroy
-        void dumpTraces() {
-            System.out.println("==== TRACES ====");
-            this.arrayListSpanProcessor.spans().forEach(System.out::println);
-            System.out.println("=================");
-        }
-    }
-}
diff --git a/dubbo-demo/dubbo-demo-spring-boot/pom.xml 
b/dubbo-demo/dubbo-demo-spring-boot/pom.xml
index 4cd2703b11..18546bdbec 100644
--- a/dubbo-demo/dubbo-demo-spring-boot/pom.xml
+++ b/dubbo-demo/dubbo-demo-spring-boot/pom.xml
@@ -36,7 +36,27 @@
         <maven.compiler.source>8</maven.compiler.source>
         <maven.compiler.target>8</maven.compiler.target>
         <skip_maven_deploy>true</skip_maven_deploy>
+        <spring-boot.version>2.7.8</spring-boot.version>
         
<spring-boot-maven-plugin.version>2.7.8</spring-boot-maven-plugin.version>
+        <micrometer-core.version>1.10.4</micrometer-core.version>
     </properties>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>io.micrometer</groupId>
+                <artifactId>micrometer-core</artifactId>
+                <version>${micrometer-core.version}</version>
+            </dependency>
+        </dependencies>
+
+    </dependencyManagement>
+
 
 </project>
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 7208334a6e..e5d57f3907 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -135,6 +135,7 @@
         <protostuff_version>1.8.0</protostuff_version>
         <envoy_api_version>0.1.35</envoy_api_version>
         <micrometer.version>1.10.4</micrometer.version>
+        
         <micrometer-tracing.version>1.0.2</micrometer-tracing.version>
         <t_digest.version>3.3</t_digest.version>
         <prometheus_client.version>0.16.0</prometheus_client.version>
diff --git a/dubbo-distribution/dubbo-bom/pom.xml 
b/dubbo-distribution/dubbo-bom/pom.xml
index 988e6cc411..9e04c68747 100644
--- a/dubbo-distribution/dubbo-bom/pom.xml
+++ b/dubbo-distribution/dubbo-bom/pom.xml
@@ -487,6 +487,11 @@
                 <type>pom</type>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                
<artifactId>dubbo-spring-boot-observability-starter</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- test -->
             <dependency>
diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml
new file mode 100644
index 0000000000..5922c1450c
--- /dev/null
+++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-spring-boot</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-spring-boot-observability-starter</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-tracing</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-observation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-tracing-bridge-otel</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.micrometer</groupId>
+            <artifactId>micrometer-tracing-bridge-brave</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metrics-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java
new file mode 100644
index 0000000000..5e6d05f9ce
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/annotation/ConditionalOnDubboTracingEnable.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.annotation;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.TYPE,ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+@ConditionalOnProperty(prefix = "dubbo.tracing", name = "enabled", 
matchIfMissing = true)
+public @interface ConditionalOnDubboTracingEnable {
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java
new file mode 100644
index 0000000000..a1f44a1867
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboMicrometerTracingAutoConfiguration.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure;
+
+import io.micrometer.tracing.Tracer;
+import io.micrometer.tracing.handler.DefaultTracingObservationHandler;
+import 
io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler;
+import 
io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler;
+import io.micrometer.tracing.propagation.Propagator;
+import 
org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.annotation.Order;
+
+/**
+ * copy from {@link 
org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration}
+ * this class is available starting from Boot 3.0. It's not available if 
you're using Boot < 3.0
+ */
+@ConditionalOnClass(Tracer.class)
+@ConditionalOnDubboTracingEnable
+@AutoConfigureAfter(name = 
"org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration")
+public class DubboMicrometerTracingAutoConfiguration {
+
+    /**
+     * {@code @Order} value of
+     * {@link #propagatingReceiverTracingObservationHandler(Tracer, 
Propagator)}.
+     */
+    public static final int RECEIVER_TRACING_OBSERVATION_HANDLER_ORDER = 1000;
+
+    /**
+     * {@code @Order} value of
+     * {@link #propagatingSenderTracingObservationHandler(Tracer, Propagator)}.
+     */
+    public static final int SENDER_TRACING_OBSERVATION_HANDLER_ORDER = 2000;
+
+    @Bean
+    @ConditionalOnMissingBean
+    @ConditionalOnBean(Tracer.class)
+    public DefaultTracingObservationHandler 
defaultTracingObservationHandler(Tracer tracer) {
+        return new DefaultTracingObservationHandler(tracer);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @ConditionalOnBean({Tracer.class, Propagator.class})
+    @Order(SENDER_TRACING_OBSERVATION_HANDLER_ORDER)
+    public PropagatingSenderTracingObservationHandler<?> 
propagatingSenderTracingObservationHandler(Tracer tracer,
+                                                                               
                     Propagator propagator) {
+        return new PropagatingSenderTracingObservationHandler<>(tracer, 
propagator);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @ConditionalOnBean({Tracer.class, Propagator.class})
+    @Order(RECEIVER_TRACING_OBSERVATION_HANDLER_ORDER)
+    public PropagatingReceiverTracingObservationHandler<?> 
propagatingReceiverTracingObservationHandler(Tracer tracer,
+                                                                               
                         Propagator propagator) {
+        return new PropagatingReceiverTracingObservationHandler<>(tracer, 
propagator);
+    }
+
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java
new file mode 100644
index 0000000000..d50881e3c4
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure;
+
+import io.micrometer.core.instrument.MeterRegistry;
+import 
io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
+import io.micrometer.core.instrument.observation.MeterObservationHandler;
+import io.micrometer.observation.Observation;
+import io.micrometer.observation.ObservationHandler;
+import io.micrometer.observation.ObservationRegistry;
+import io.micrometer.tracing.Tracer;
+import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
+import io.micrometer.tracing.handler.TracingObservationHandler;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import 
org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.SmartInitializingSingleton;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Arrays;
+
+/**
+ * Register observationRegistry to ApplicationModel.
+ * Create observationRegistry when you are using Boot <3.0 or you are not 
using spring-boot-starter-actuator
+ */
+@AutoConfiguration(after 
=DubboMicrometerTracingAutoConfiguration.class,afterName = 
"org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
+@ConditionalOnDubboTracingEnable
+public class DubboObservationAutoConfiguration implements BeanFactoryAware, 
SmartInitializingSingleton {
+
+    public DubboObservationAutoConfiguration(ApplicationModel 
applicationModel) {
+        this.applicationModel = applicationModel;
+    }
+
+    private final ApplicationModel applicationModel;
+
+    private BeanFactory beanFactory;
+
+    @Bean
+    @ConditionalOnMissingBean
+    ObservationRegistry observationRegistry() {
+        return ObservationRegistry.create();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(type = 
"org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor")
+    public ObservationRegistryPostProcessor 
dubboObservationRegistryPostProcessor(ObjectProvider<ObservationHandlerGrouping>
 observationHandlerGrouping,
+                                                                               
   ObjectProvider<ObservationHandler<?>> observationHandlers) {
+        return new 
ObservationRegistryPostProcessor(observationHandlerGrouping, 
observationHandlers);
+    }
+
+    @Override
+    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+        this.beanFactory = beanFactory;
+    }
+
+    @Override
+    public void afterSingletonsInstantiated() {
+        
applicationModel.getBeanFactory().registerBean(beanFactory.getBean(ObservationRegistry.class));
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnClass(MeterRegistry.class)
+    @ConditionalOnMissingClass("io.micrometer.tracing.Tracer")
+    @ConditionalOnMissingBean(type = 
"org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor")
+    static class OnlyMetricsConfiguration {
+
+        @Bean
+        ObservationHandlerGrouping metricsObservationHandlerGrouping() {
+            return new 
ObservationHandlerGrouping(MeterObservationHandler.class);
+        }
+
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnClass(Tracer.class)
+    @ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry")
+    @ConditionalOnMissingBean(type = 
"org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor")
+    static class OnlyTracingConfiguration {
+
+        @Bean
+        ObservationHandlerGrouping tracingObservationHandlerGrouping() {
+            return new 
ObservationHandlerGrouping(TracingObservationHandler.class);
+        }
+
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnClass({ MeterRegistry.class, Tracer.class })
+    @ConditionalOnMissingBean(type = 
"org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryPostProcessor")
+    static class MetricsWithTracingConfiguration {
+
+        @Bean
+        ObservationHandlerGrouping 
metricsAndTracingObservationHandlerGrouping() {
+            return new ObservationHandlerGrouping(
+               Arrays.asList(TracingObservationHandler.class, 
MeterObservationHandler.class));
+        }
+
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnBean(MeterRegistry.class)
+    @ConditionalOnMissingBean(MeterObservationHandler.class)
+    static class MeterObservationHandlerConfiguration {
+
+        @ConditionalOnMissingBean(type = "io.micrometer.tracing.Tracer")
+        @Configuration(proxyBeanMethods = false)
+        static class OnlyMetricsMeterObservationHandlerConfiguration {
+
+            @Bean
+            DefaultMeterObservationHandler 
defaultMeterObservationHandler(MeterRegistry meterRegistry) {
+                return new DefaultMeterObservationHandler(meterRegistry);
+            }
+
+        }
+
+        @ConditionalOnBean(Tracer.class)
+        @Configuration(proxyBeanMethods = false)
+        static class TracingAndMetricsObservationHandlerConfiguration {
+
+            @Bean
+            TracingAwareMeterObservationHandler<Observation.Context> 
tracingAwareMeterObservationHandler(
+                MeterRegistry meterRegistry, Tracer tracer) {
+                DefaultMeterObservationHandler delegate = new 
DefaultMeterObservationHandler(meterRegistry);
+                return new TracingAwareMeterObservationHandler<>(delegate, 
tracer);
+            }
+
+        }
+
+    }
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java
new file mode 100644
index 0000000000..1c3df96886
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationHandlerGrouping.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure;
+
+import io.micrometer.observation.ObservationHandler;
+import io.micrometer.observation.ObservationRegistry;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Groups {@link ObservationHandler ObservationHandlers} by type.
+ * copy from {@link 
org.springframework.boot.actuate.autoconfigure.observation.ObservationHandlerGrouping}
+ * this class is available starting from Boot 3.0. It's not available if 
you're using Boot < 3.0
+ *
+ * @author Andy Wilkinson
+ */
+class ObservationHandlerGrouping {
+
+    private final List<Class<? extends ObservationHandler>> categories;
+
+    ObservationHandlerGrouping(Class<? extends ObservationHandler> category) {
+        this(Collections.singletonList(category));
+    }
+
+    ObservationHandlerGrouping(List<Class<? extends ObservationHandler>> 
categories) {
+        this.categories = categories;
+    }
+
+    void apply(List<ObservationHandler<?>> handlers, 
ObservationRegistry.ObservationConfig config) {
+        MultiValueMap<Class<? extends ObservationHandler>, 
ObservationHandler<?>> groupings = new LinkedMultiValueMap<>();
+        for (ObservationHandler<?> handler : handlers) {
+            Class<? extends ObservationHandler> category = 
findCategory(handler);
+            if (category != null) {
+                groupings.add(category, handler);
+            } else {
+                config.observationHandler(handler);
+            }
+        }
+        for (Class<? extends ObservationHandler> category : this.categories) {
+            List<ObservationHandler<?>> handlerGroup = groupings.get(category);
+            if (!CollectionUtils.isEmpty(handlerGroup)) {
+                config.observationHandler(new 
ObservationHandler.FirstMatchingCompositeObservationHandler(handlerGroup));
+            }
+        }
+    }
+
+    private Class<? extends ObservationHandler> 
findCategory(ObservationHandler<?> handler) {
+        for (Class<? extends ObservationHandler> category : this.categories) {
+            if (category.isInstance(handler)) {
+                return category;
+            }
+        }
+        return null;
+    }
+
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java
new file mode 100644
index 0000000000..47344b3f40
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/ObservationRegistryPostProcessor.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure;
+
+import io.micrometer.observation.ObservationHandler;
+import io.micrometer.observation.ObservationRegistry;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * registry observationHandlers to observationConfig
+ */
+public class ObservationRegistryPostProcessor implements BeanPostProcessor {
+    private final ObjectProvider<ObservationHandlerGrouping> 
observationHandlerGrouping;
+    private final ObjectProvider<ObservationHandler<?>> observationHandlers;
+
+    public 
ObservationRegistryPostProcessor(ObjectProvider<ObservationHandlerGrouping> 
observationHandlerGrouping,
+                                            
ObjectProvider<ObservationHandler<?>> observationHandlers){
+        this.observationHandlerGrouping = observationHandlerGrouping;
+        this.observationHandlers = observationHandlers;
+
+    }
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanName) 
throws BeansException {
+        if(bean instanceof ObservationRegistry){
+            ObservationRegistry observationRegistry = (ObservationRegistry) 
bean;
+            List<ObservationHandler<?>> observationHandlerList =
+                
observationHandlers.orderedStream().collect(Collectors.toList());
+            observationHandlerGrouping.ifAvailable(grouping->{
+                grouping.apply(observationHandlerList,
+                    observationRegistry.observationConfig());
+            });
+        }
+        return bean;
+    }
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java
new file mode 100644
index 0000000000..dd6c1cc6cc
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure.brave;
+
+import brave.CurrentSpanCustomizer;
+import brave.SpanCustomizer;
+import brave.Tracing;
+import brave.TracingCustomizer;
+import brave.baggage.BaggageField;
+import brave.baggage.BaggagePropagation;
+import brave.baggage.BaggagePropagationConfig;
+import brave.baggage.BaggagePropagationCustomizer;
+import brave.baggage.CorrelationScopeConfig;
+import brave.baggage.CorrelationScopeCustomizer;
+import brave.baggage.CorrelationScopeDecorator;
+import brave.context.slf4j.MDCScopeDecorator;
+import brave.handler.SpanHandler;
+import brave.propagation.B3Propagation;
+import brave.propagation.CurrentTraceContext;
+import brave.propagation.CurrentTraceContextCustomizer;
+import brave.propagation.Propagation;
+import brave.propagation.ThreadLocalCurrentTraceContext;
+import brave.sampler.Sampler;
+import io.micrometer.tracing.Tracer;
+import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
+import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext;
+import io.micrometer.tracing.brave.bridge.BravePropagator;
+import io.micrometer.tracing.brave.bridge.BraveSpanCustomizer;
+import io.micrometer.tracing.brave.bridge.BraveTracer;
+import io.micrometer.tracing.brave.bridge.CompositeSpanHandler;
+import io.micrometer.tracing.brave.bridge.W3CPropagation;
+import io.micrometer.tracing.exporter.SpanExportingPredicate;
+import io.micrometer.tracing.exporter.SpanFilter;
+import io.micrometer.tracing.exporter.SpanReporter;
+import 
org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
+import 
org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration;
+import 
org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.env.Environment;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * provider Brave when you are using Boot <3.0 or you are not using 
spring-boot-starter-actuator
+ */
+@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, 
afterName = 
"org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration")
+@ConditionalOnClass({Tracer.class, BraveTracer.class})
+@EnableConfigurationProperties(DubboTracingProperties.class)
+@ConditionalOnDubboTracingEnable
+public class BraveAutoConfiguration {
+
+    private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new 
BraveBaggageManager();
+
+    /**
+     * Default value for application name if {@code spring.application.name} 
is not set.
+     */
+    private static final String DEFAULT_APPLICATION_NAME = "application";
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Order(Ordered.HIGHEST_PRECEDENCE)
+    CompositeSpanHandler 
compositeSpanHandler(ObjectProvider<SpanExportingPredicate> predicates,
+                                              ObjectProvider<SpanReporter> 
reporters, ObjectProvider<SpanFilter> filters) {
+        return new 
CompositeSpanHandler(predicates.orderedStream().collect(Collectors.toList()),
+            reporters.orderedStream().collect(Collectors.toList()),
+            filters.orderedStream().collect(Collectors.toList()));
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public Tracing braveTracing(Environment environment, List<SpanHandler> 
spanHandlers,
+                                List<TracingCustomizer> tracingCustomizers, 
CurrentTraceContext currentTraceContext,
+                                Propagation.Factory propagationFactory, 
Sampler sampler) {
+        String applicationName = 
environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
+        Tracing.Builder builder = 
Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true)
+            
.supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler)
+            .localServiceName(applicationName);
+        spanHandlers.forEach(builder::addSpanHandler);
+        for (TracingCustomizer tracingCustomizer : tracingCustomizers) {
+            tracingCustomizer.customize(builder);
+        }
+        return builder.build();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public brave.Tracer braveTracer(Tracing tracing) {
+        return tracing.tracer();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public CurrentTraceContext 
braveCurrentTraceContext(List<CurrentTraceContext.ScopeDecorator> 
scopeDecorators,
+                                                        
List<CurrentTraceContextCustomizer> currentTraceContextCustomizers) {
+        ThreadLocalCurrentTraceContext.Builder builder = 
ThreadLocalCurrentTraceContext.newBuilder();
+        scopeDecorators.forEach(builder::addScopeDecorator);
+        for (CurrentTraceContextCustomizer currentTraceContextCustomizer : 
currentTraceContextCustomizers) {
+            currentTraceContextCustomizer.customize(builder);
+        }
+        return builder.build();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public Sampler braveSampler(DubboTracingProperties properties) {
+        return Sampler.create(properties.getSampling().getProbability());
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(io.micrometer.tracing.Tracer.class)
+    BraveTracer braveTracerBridge(brave.Tracer tracer, CurrentTraceContext 
currentTraceContext) {
+        return new BraveTracer(tracer, new 
BraveCurrentTraceContext(currentTraceContext), BRAVE_BAGGAGE_MANAGER);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    BravePropagator bravePropagator(Tracing tracing) {
+        return new BravePropagator(tracing);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(SpanCustomizer.class)
+    CurrentSpanCustomizer currentSpanCustomizer(Tracing tracing) {
+        return CurrentSpanCustomizer.create(tracing);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(io.micrometer.tracing.SpanCustomizer.class)
+    BraveSpanCustomizer braveSpanCustomizer(SpanCustomizer spanCustomizer) {
+        return new BraveSpanCustomizer(spanCustomizer);
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", 
havingValue = "false")
+    static class BraveNoBaggageConfiguration {
+
+        @Bean
+        @ConditionalOnMissingBean
+        Propagation.Factory propagationFactory(DubboTracingProperties tracing) 
{
+            DubboTracingProperties.Propagation.PropagationType type = 
tracing.getPropagation().getType();
+            switch (type) {
+                case B3:
+                    return 
B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
+                case W3C:
+                    return new W3CPropagation();
+                default:
+                    throw new IllegalArgumentException("UnSupport propagation 
type");
+            }
+        }
+
+    }
+
+    @ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", 
matchIfMissing = true)
+    @Configuration(proxyBeanMethods = false)
+    static class BraveBaggageConfiguration {
+        private final DubboTracingProperties dubboTracingProperties;
+
+        public BraveBaggageConfiguration(DubboTracingProperties 
dubboTracingProperties) {
+            this.dubboTracingProperties = dubboTracingProperties;
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = 
"type", havingValue = "B3")
+        BaggagePropagation.FactoryBuilder b3PropagationFactoryBuilder(
+            ObjectProvider<BaggagePropagationCustomizer> 
baggagePropagationCustomizers) {
+            Propagation.Factory delegate =
+                
B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
+
+            BaggagePropagation.FactoryBuilder builder = 
BaggagePropagation.newFactoryBuilder(delegate);
+            baggagePropagationCustomizers.orderedStream().forEach((customizer) 
-> customizer.customize(builder));
+            return builder;
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = 
"type", havingValue = "W3C", matchIfMissing = true)
+        BaggagePropagation.FactoryBuilder w3cPropagationFactoryBuilder(
+            ObjectProvider<BaggagePropagationCustomizer> 
baggagePropagationCustomizers) {
+            Propagation.Factory delegate = new 
W3CPropagation(BRAVE_BAGGAGE_MANAGER, Collections.emptyList());
+
+            BaggagePropagation.FactoryBuilder builder = 
BaggagePropagation.newFactoryBuilder(delegate);
+            baggagePropagationCustomizers.orderedStream().forEach((customizer) 
-> customizer.customize(builder));
+            return builder;
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @Order(0)
+        BaggagePropagationCustomizer 
remoteFieldsBaggagePropagationCustomizer() {
+            return (builder) -> {
+                List<String> remoteFields = 
dubboTracingProperties.getBaggage().getRemoteFields();
+                for (String fieldName : remoteFields) {
+                    
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
+                }
+            };
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        Propagation.Factory 
propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) {
+            return factoryBuilder.build();
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
+            ObjectProvider<CorrelationScopeCustomizer> 
correlationScopeCustomizers) {
+            CorrelationScopeDecorator.Builder builder = 
MDCScopeDecorator.newBuilder();
+            correlationScopeCustomizers.orderedStream().forEach((customizer) 
-> customizer.customize(builder));
+            return builder;
+        }
+
+        @Bean
+        @Order(0)
+        @ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", 
name = "enabled",
+            matchIfMissing = true)
+        CorrelationScopeCustomizer 
correlationFieldsCorrelationScopeCustomizer() {
+            return (builder) -> {
+                List<String> correlationFields = 
this.dubboTracingProperties.getBaggage().getCorrelation().getFields();
+                for (String field : correlationFields) {
+                    
builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
+                        .flushOnUpdate().build());
+                }
+            };
+        }
+
+        @Bean
+        @ConditionalOnMissingBean(CurrentTraceContext.ScopeDecorator.class)
+        CurrentTraceContext.ScopeDecorator 
correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) {
+            return builder.build();
+        }
+
+    }
+
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java
new file mode 100644
index 0000000000..c2903fa46d
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.autoconfigure.otel;
+
+import io.micrometer.tracing.SpanCustomizer;
+import io.micrometer.tracing.exporter.SpanExportingPredicate;
+import io.micrometer.tracing.exporter.SpanFilter;
+import io.micrometer.tracing.exporter.SpanReporter;
+import io.micrometer.tracing.otel.bridge.CompositeSpanExporter;
+import io.micrometer.tracing.otel.bridge.EventListener;
+import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper;
+import io.micrometer.tracing.otel.bridge.OtelBaggageManager;
+import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext;
+import io.micrometer.tracing.otel.bridge.OtelPropagator;
+import io.micrometer.tracing.otel.bridge.OtelSpanCustomizer;
+import io.micrometer.tracing.otel.bridge.OtelTracer;
+import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
+import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
+import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator;
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
+import io.opentelemetry.context.ContextStorage;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import io.opentelemetry.context.propagation.TextMapPropagator;
+import io.opentelemetry.extension.trace.propagation.B3Propagator;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.resources.Resource;
+import io.opentelemetry.sdk.trace.SdkTracerProvider;
+import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
+import io.opentelemetry.sdk.trace.export.SpanExporter;
+import io.opentelemetry.sdk.trace.samplers.Sampler;
+import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
+import org.apache.dubbo.common.Version;
+import 
org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
+import 
org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration;
+import 
org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * provider OpenTelemetry when you are using Boot <3.0 or you are not using 
spring-boot-starter-actuator
+ */
+@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, 
afterName = 
"org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration")
+@ConditionalOnDubboTracingEnable
+@ConditionalOnClass({OtelTracer.class, SdkTracerProvider.class, 
OpenTelemetry.class})
+@EnableConfigurationProperties(DubboTracingProperties.class)
+public class OpenTelemetryAutoConfiguration {
+
+    /**
+     * Default value for application name if {@code spring.application.name} 
is not set.
+     */
+    private static final String DEFAULT_APPLICATION_NAME = "application";
+
+    private final DubboTracingProperties dubboTracingProperties;
+
+    OpenTelemetryAutoConfiguration(DubboTracingProperties 
dubboTracingProperties) {
+        this.dubboTracingProperties = dubboTracingProperties;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    OpenTelemetry openTelemetry(SdkTracerProvider sdkTracerProvider, 
ContextPropagators contextPropagators) {
+        return 
OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider).setPropagators(contextPropagators)
+            .build();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    SdkTracerProvider otelSdkTracerProvider(Environment environment, 
ObjectProvider<SpanProcessor> spanProcessors,
+                                            Sampler sampler) {
+        String applicationName = 
environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
+        SdkTracerProviderBuilder builder = 
SdkTracerProvider.builder().setSampler(sampler)
+            
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, 
applicationName)));
+        spanProcessors.orderedStream().forEach(builder::addSpanProcessor);
+        return builder.build();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    ContextPropagators 
otelContextPropagators(ObjectProvider<TextMapPropagator> textMapPropagators) {
+        return 
ContextPropagators.create(TextMapPropagator.composite(textMapPropagators.orderedStream().collect(Collectors.toList())));
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    Sampler otelSampler() {
+        Sampler rootSampler = 
Sampler.traceIdRatioBased(this.dubboTracingProperties.getSampling().getProbability());
+        return Sampler.parentBased(rootSampler);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    SpanProcessor otelSpanProcessor(ObjectProvider<SpanExporter> spanExporters,
+                                    ObjectProvider<SpanExportingPredicate> 
spanExportingPredicates, ObjectProvider<SpanReporter> spanReporters,
+                                    ObjectProvider<SpanFilter> spanFilters) {
+        return BatchSpanProcessor.builder(new 
CompositeSpanExporter(spanExporters.orderedStream().collect(Collectors.toList()),
+            
spanExportingPredicates.orderedStream().collect(Collectors.toList()), 
spanReporters.orderedStream().collect(Collectors.toList()),
+            spanFilters.orderedStream().collect(Collectors.toList()))).build();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    Tracer otelTracer(OpenTelemetry openTelemetry) {
+        return openTelemetry.getTracer("org.apache.dubbo", 
Version.getVersion());
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(io.micrometer.tracing.Tracer.class)
+    OtelTracer micrometerOtelTracer(Tracer tracer, OtelTracer.EventPublisher 
eventPublisher,
+                                    OtelCurrentTraceContext 
otelCurrentTraceContext) {
+        return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher,
+            new OtelBaggageManager(otelCurrentTraceContext, 
this.dubboTracingProperties.getBaggage().getRemoteFields(),
+                Collections.emptyList()));
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    OtelPropagator otelPropagator(ContextPropagators contextPropagators, 
Tracer tracer) {
+        return new OtelPropagator(contextPropagators, tracer);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    OtelTracer.EventPublisher otelTracerEventPublisher(List<EventListener> 
eventListeners) {
+        return new OTelEventPublisher(eventListeners);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    OtelCurrentTraceContext otelCurrentTraceContext(OtelTracer.EventPublisher 
publisher) {
+        ContextStorage.addWrapper(new 
EventPublishingContextWrapper(publisher));
+        return new OtelCurrentTraceContext();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    Slf4JEventListener otelSlf4JEventListener() {
+        return new Slf4JEventListener();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(SpanCustomizer.class)
+    OtelSpanCustomizer otelSpanCustomizer() {
+        return new OtelSpanCustomizer();
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", 
matchIfMissing = true)
+    static class BaggageConfiguration {
+
+        private final DubboTracingProperties tracingProperties;
+
+        BaggageConfiguration(DubboTracingProperties tracingProperties) {
+            this.tracingProperties = tracingProperties;
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = 
"type", havingValue = "W3C",
+            matchIfMissing = true)
+        TextMapPropagator 
w3cTextMapPropagatorWithBaggage(OtelCurrentTraceContext 
otelCurrentTraceContext) {
+            List<String> remoteFields = 
this.tracingProperties.getBaggage().getRemoteFields();
+            return 
TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(),
+                W3CBaggagePropagator.getInstance(), new 
BaggageTextMapPropagator(remoteFields,
+                    new OtelBaggageManager(otelCurrentTraceContext, 
remoteFields, Collections.emptyList())));
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = 
"type", havingValue = "B3")
+        TextMapPropagator b3BaggageTextMapPropagator(OtelCurrentTraceContext 
otelCurrentTraceContext) {
+            List<String> remoteFields = 
this.tracingProperties.getBaggage().getRemoteFields();
+            return 
TextMapPropagator.composite(B3Propagator.injectingSingleHeader(),
+                new BaggageTextMapPropagator(remoteFields,
+                    new OtelBaggageManager(otelCurrentTraceContext, 
remoteFields, Collections.emptyList())));
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", 
name = "enabled",
+            matchIfMissing = true)
+        Slf4JBaggageEventListener otelSlf4JBaggageEventListener() {
+            return new 
Slf4JBaggageEventListener(this.tracingProperties.getBaggage().getCorrelation().getFields());
+        }
+
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", 
havingValue = "false")
+    static class NoBaggageConfiguration {
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = 
"type", havingValue = "B3")
+        B3Propagator b3TextMapPropagator() {
+            return B3Propagator.injectingSingleHeader();
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        @ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = 
"type", havingValue = "W3C",
+            matchIfMissing = true)
+        W3CTraceContextPropagator w3cTextMapPropagatorWithoutBaggage() {
+            return W3CTraceContextPropagator.getInstance();
+        }
+
+    }
+
+    static class OTelEventPublisher implements OtelTracer.EventPublisher {
+
+        private final List<EventListener> listeners;
+
+        OTelEventPublisher(List<EventListener> listeners) {
+            this.listeners = listeners;
+        }
+
+        @Override
+        public void publishEvent(Object event) {
+            for (EventListener listener : this.listeners) {
+                listener.onEvent(event);
+            }
+        }
+
+    }
+
+}
+
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java
new file mode 100644
index 0000000000..72d4b967df
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/java/org/apache/dubbo/spring/boot/observability/config/DubboTracingProperties.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.spring.boot.observability.config;
+
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@ConfigurationProperties("dubbo.tracing")
+public class DubboTracingProperties {
+
+    /**
+     * Whether auto-configuration of tracing is enabled.
+     */
+    private boolean enabled = true;
+
+    /**
+     * Sampling configuration.
+     */
+    private final Sampling sampling = new Sampling();
+
+    /**
+     * Baggage configuration.
+     */
+    private final Baggage baggage = new Baggage();
+
+    /**
+     * Propagation configuration.
+     */
+    private final Propagation propagation = new Propagation();
+
+    public boolean isEnabled() {
+        return this.enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Sampling getSampling() {
+        return this.sampling;
+    }
+
+    public Baggage getBaggage() {
+        return this.baggage;
+    }
+
+    public Propagation getPropagation() {
+        return this.propagation;
+    }
+
+    public static class Sampling {
+
+        /**
+         * Probability in the range from 0.0 to 1.0 that a trace will be 
sampled.
+         */
+        private float probability = 0.10f;
+
+        public float getProbability() {
+            return this.probability;
+        }
+
+        public void setProbability(float probability) {
+            this.probability = probability;
+        }
+
+    }
+
+    public static class Baggage {
+
+        /**
+         * Whether to enable Micrometer Tracing baggage propagation.
+         */
+        private boolean enabled = true;
+
+        /**
+         * Correlation configuration.
+         */
+        private Correlation correlation = new Correlation();
+
+        /**
+         * List of fields that are referenced the same in-process as it is on 
the wire.
+         * For example, the field "x-vcap-request-id" would be set as-is 
including the
+         * prefix.
+         */
+        private List<String> remoteFields = new ArrayList<>();
+
+        public boolean isEnabled() {
+            return this.enabled;
+        }
+
+        public void setEnabled(boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        public Correlation getCorrelation() {
+            return this.correlation;
+        }
+
+        public void setCorrelation(Correlation correlation) {
+            this.correlation = correlation;
+        }
+
+        public List<String> getRemoteFields() {
+            return this.remoteFields;
+        }
+
+        public void setRemoteFields(List<String> remoteFields) {
+            this.remoteFields = remoteFields;
+        }
+
+        public static class Correlation {
+
+            /**
+             * Whether to enable correlation of the baggage context with 
logging contexts.
+             */
+            private boolean enabled = true;
+
+            /**
+             * List of fields that should be correlated with the logging 
context. That
+             * means that these fields would end up as key-value pairs in e.g. 
MDC.
+             */
+            private List<String> fields = new ArrayList<>();
+
+            public boolean isEnabled() {
+                return this.enabled;
+            }
+
+            public void setEnabled(boolean enabled) {
+                this.enabled = enabled;
+            }
+
+            public List<String> getFields() {
+                return this.fields;
+            }
+
+            public void setFields(List<String> fields) {
+                this.fields = fields;
+            }
+
+        }
+
+    }
+
+    public static class Propagation {
+
+        /**
+         * Tracing context propagation type.
+         */
+        private PropagationType type = PropagationType.W3C;
+
+        public PropagationType getType() {
+            return this.type;
+        }
+
+        public void setType(PropagationType type) {
+            this.type = type;
+        }
+
+        public enum PropagationType {
+
+            /**
+             * B3 propagation type.
+             */
+            B3,
+
+            /**
+             * W3C propagation type.
+             */
+            W3C
+
+        }
+
+    }
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json
new file mode 100644
index 0000000000..3ae084b1f1
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -0,0 +1,82 @@
+{
+  "groups": [
+    {
+      "name": "dubbo.tracing",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties"
+    },
+    {
+      "name": "dubbo.tracing.baggage",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
+      "sourceMethod": "getBaggage()"
+    },
+    {
+      "name": "dubbo.tracing.baggage.correlation",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
+      "sourceMethod": "getCorrelation()"
+    },
+    {
+      "name": "dubbo.tracing.propagation",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
+      "sourceMethod": "getPropagation()"
+    },
+    {
+      "name": "dubbo.tracing.sampling",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
+      "sourceMethod": "getSampling()"
+    }
+  ],
+  "properties": [
+    {
+      "name": "dubbo.tracing.baggage.correlation.enabled",
+      "type": "java.lang.Boolean",
+      "description": "Whether to enable correlation of the baggage context 
with logging contexts.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation",
+      "defaultValue": true
+    },
+    {
+      "name": "dubbo.tracing.baggage.correlation.fields",
+      "type": "java.util.List<java.lang.String>",
+      "description": "List of fields that should be correlated with the 
logging context. That means that these fields would end up as key-value pairs 
in e.g. MDC.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation"
+    },
+    {
+      "name": "dubbo.tracing.baggage.enabled",
+      "type": "java.lang.Boolean",
+      "description": "Whether to enable Micrometer Tracing baggage 
propagation.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
+      "defaultValue": true
+    },
+    {
+      "name": "dubbo.tracing.baggage.remote-fields",
+      "type": "java.util.List<java.lang.String>",
+      "description": "List of fields that are referenced the same in-process 
as it is on the wire. For example, the field \"x-vcap-request-id\" would be set 
as-is including the prefix.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage"
+    },
+    {
+      "name": "dubbo.tracing.enabled",
+      "type": "java.lang.Boolean",
+      "description": "Whether auto-configuration of tracing is enabled.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
+      "defaultValue": true
+    },
+    {
+      "name": "dubbo.tracing.propagation.type",
+      "type": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation$PropagationType",
+      "description": "Tracing context propagation type.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation"
+    },
+    {
+      "name": "dubbo.tracing.sampling.probability",
+      "type": "java.lang.Float",
+      "description": "Probability in the range from 0.0 to 1.0 that a trace 
will be sampled.",
+      "sourceType": 
"org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling",
+      "defaultValue": 0.1
+    }
+  ],
+  "hints": []
+}
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..b7a570ea76
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,6 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.dubbo.spring.boot.observability.autoconfigure.otel.OpenTelemetryAutoConfiguration,\
+org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration,\
+org.apache.dubbo.spring.boot.observability.autoconfigure.DubboObservationAutoConfiguration,\
+org.apache.dubbo.spring.boot.observability.autoconfigure.brave.BraveAutoConfiguration
+
diff --git 
a/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000000..9d3769fc9c
--- /dev/null
+++ 
b/dubbo-spring-boot/dubbo-spring-boot-observability-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,4 @@
+org.apache.dubbo.spring.boot.observability.autoconfigure.otel.OpenTelemetryAutoConfiguration
+org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration
+org.apache.dubbo.spring.boot.observability.autoconfigure.DubboObservationAutoConfiguration
+org.apache.dubbo.spring.boot.observability.autoconfigure.brave.BraveAutoConfiguration
diff --git a/dubbo-spring-boot/pom.xml b/dubbo-spring-boot/pom.xml
index 4c43c07955..2d6991aac4 100644
--- a/dubbo-spring-boot/pom.xml
+++ b/dubbo-spring-boot/pom.xml
@@ -36,6 +36,7 @@
         <module>dubbo-spring-boot-autoconfigure</module>
         <module>dubbo-spring-boot-compatible</module>
         <module>dubbo-spring-boot-starter</module>
+        <module>dubbo-spring-boot-observability-starter</module>
     </modules>
 
     <properties>
@@ -45,6 +46,7 @@
         <log4j2_version>2.19.0</log4j2_version>
         <!-- Spring boot buddy is lower than the delivery dependency package 
version and can only show the defined dependency version -->
         <byte-buddy.version>1.13.0</byte-buddy.version>
+        <micrometer-core.version>1.10.4</micrometer-core.version>
     </properties>
 
     <dependencyManagement>
@@ -57,6 +59,11 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>io.micrometer</groupId>
+                <artifactId>micrometer-core</artifactId>
+                <version>${micrometer-core.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml 
b/dubbo-test/dubbo-dependencies-all/pom.xml
index 5e9a515d5a..90e91d7e4d 100644
--- a/dubbo-test/dubbo-dependencies-all/pom.xml
+++ b/dubbo-test/dubbo-dependencies-all/pom.xml
@@ -318,6 +318,11 @@
             <artifactId>dubbo-spring-boot-starter</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-spring-boot-observability-starter</artifactId>
+        </dependency>
+
         <!-- test -->
         <dependency>
             <groupId>org.apache.dubbo</groupId>


Reply via email to