OrderController#placeOrder is annotated @Observed(name = "place-order", contextualName = "order-controller#placeOrder"). Before ObservationConfig (an explicit ObservedAspect @Bean) existed in this repo, spring-boot-starter-opentelemetry, spring-boot-starter-aspectj (AspectJ weaver on the classpath) and micrometer-tracing were ALL already present and active -- and the annotation still did nothing. Real trace, fetched straight from Tempo's query API, before the fix: $ curl -s "http://localhost:3200/api/traces/" span: http post /orders/{id} | kind: SPAN_KIND_SERVER | parent: (root) # one span. @Observed's child span never appears. After adding: @Configuration(proxyBeanMethods = false) class ObservationConfig { @Bean ObservedAspect observedAspect(ObservationRegistry registry) { return new ObservedAspect(registry); } } Same annotation, same request, new trace: $ curl -s "http://localhost:3200/api/traces/" span: order-controller#placeOrder | kind: SPAN_KIND_INTERNAL | parent: span: http post /orders/{id} | kind: SPAN_KIND_SERVER | parent: (root) # two spans. The @Observed child span now nests correctly under the HTTP server span. Spring Boot's autoconfiguration wires an ObservationRegistry bean for you the moment Micrometer Tracing is on the classpath -- it does NOT also register an ObservedAspect. AspectJ weaving being present is necessary but not sufficient; without the aspect bean there is nothing for the weaver to apply. This is easy to miss because the app starts cleanly, the HTTP server span still shows up, and nothing logs a warning -- the method-level span is just silently absent.