diff --git a/spring-boot-modules/spring-boot-3-observation/pom.xml b/spring-boot-modules/spring-boot-3-observation/pom.xml
index 79fa04688521..a67f0c3a2450 100644
--- a/spring-boot-modules/spring-boot-3-observation/pom.xml
+++ b/spring-boot-modules/spring-boot-3-observation/pom.xml
@@ -103,12 +103,33 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 21
+ 21
+
+
+
+
+
+ io.micrometer
+ micrometer-bom
+ ${micrometer.version}
+ pom
+ import
+
+
+
+
com.baeldung.samples.SimpleObservationApplication
1.9.0
+ 1.15.3
diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/Application.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/Application.java
new file mode 100644
index 000000000000..5a488c2b1c22
--- /dev/null
+++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/Application.java
@@ -0,0 +1,36 @@
+package com.baeldung.micrometer.tags;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+import io.micrometer.core.aop.CountedAspect;
+import io.micrometer.core.aop.CountedMeterTagAnnotationHandler;
+import io.micrometer.core.aop.MeterTagAnnotationHandler;
+import io.micrometer.core.aop.TimedAspect;
+
+@SpringBootApplication
+class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public MeterTagAnnotationHandler meterTagAnnotationHandler() {
+ return new MeterTagAnnotationHandler(
+ aClass -> Object::toString,
+ aClass -> (exp, param) -> "");
+ }
+
+ @Bean
+ public CountedAspect countedAspect() {
+ CountedAspect aspect = new CountedAspect();
+ CountedMeterTagAnnotationHandler tagAnnotationHandler = new CountedMeterTagAnnotationHandler(
+ aClass -> Object::toString,
+ aClass -> (exp, param) -> "");
+ aspect.setMeterTagAnnotationHandler(tagAnnotationHandler);
+ return aspect;
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyService.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyService.java
new file mode 100644
index 000000000000..858dbd540c9a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyService.java
@@ -0,0 +1,79 @@
+package com.baeldung.micrometer.tags.dummy;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import io.micrometer.core.annotation.Counted;
+import io.micrometer.core.annotation.Timed;
+import io.micrometer.core.aop.MeterTag;
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Timer;
+
+@Service
+class DummyService {
+
+ private static final Logger log = LoggerFactory.getLogger(DummyService.class);
+
+ private final MeterRegistry meterRegistry;
+ private final Meter.MeterProvider counterProvider;
+ private final Meter.MeterProvider timerProvider;
+
+ public DummyService(MeterRegistry meterRegistry) {
+ this.meterRegistry = meterRegistry;
+
+ this.counterProvider = Counter.builder("bar.count")
+ .withRegistry(meterRegistry);
+ this.timerProvider = Timer.builder("bar.time")
+ .withRegistry(meterRegistry);
+ }
+
+ public String foo(String deviceType) {
+ log.info("foo({})", deviceType);
+
+ Counter.builder("foo.count")
+ .tag("device.type", deviceType)
+ .register(meterRegistry)
+ .increment();
+ String response = Timer.builder("foo.time")
+ .tag("device.type", deviceType)
+ .register(meterRegistry)
+ .record(this::invokeSomeLogic);
+
+ return response;
+ }
+
+ public String bar(String device) {
+ log.info("bar({})", device);
+
+ counterProvider.withTag("device.type", device)
+ .increment();
+ String response = timerProvider.withTag("device.type", device)
+ .record(this::invokeSomeLogic);
+
+ return response;
+ }
+
+ @Timed("buzz.time")
+ @Counted("buzz.count")
+ public String buzz(@MeterTag("device.type") String device) {
+ log.info("buzz({})", device);
+ return invokeSomeLogic();
+ }
+
+ private String invokeSomeLogic() {
+ long sleepMs = ThreadLocalRandom.current()
+ .nextInt(0, 100);
+ try {
+ Thread.sleep(sleepMs);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ return "dummy response";
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyStartupListener.java b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyStartupListener.java
new file mode 100644
index 000000000000..6f1b90f99559
--- /dev/null
+++ b/spring-boot-modules/spring-boot-3-observation/src/main/java/com/baeldung/micrometer/tags/dummy/DummyStartupListener.java
@@ -0,0 +1,33 @@
+package com.baeldung.micrometer.tags.dummy;
+
+import java.util.List;
+import java.util.stream.IntStream;
+
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+
+@Component
+class DummyStartupListener {
+
+ private static final List deviceTypes = List.of("desktop", "mobile", "tablet", "smart_tv", "wearable");
+
+ private final DummyService service;
+
+ @EventListener(ApplicationReadyEvent.class)
+ void sendRequests() {
+ IntStream.range(0, 100)
+ .map(it -> it % deviceTypes.size())
+ .mapToObj(deviceTypes::get)
+ .parallel()
+ .forEach(deviceType -> {
+ service.foo(deviceType);
+ service.bar(deviceType);
+ service.buzz(deviceType);
+ });
+ }
+
+ DummyStartupListener(DummyService service) {
+ this.service = service;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-3-observation/src/main/resources/application.yml b/spring-boot-modules/spring-boot-3-observation/src/main/resources/application.yml
index 9f91e8a03a14..8a228a66cddb 100644
--- a/spring-boot-modules/spring-boot-3-observation/src/main/resources/application.yml
+++ b/spring-boot-modules/spring-boot-3-observation/src/main/resources/application.yml
@@ -1,4 +1,7 @@
management:
+ observations:
+ annotations:
+ enabled: true
endpoints:
web:
exposure: