diff --git a/spring-modulith-observability/pom.xml b/spring-modulith-observability/pom.xml
index e7f4de1c..89e485e5 100644
--- a/spring-modulith-observability/pom.xml
+++ b/spring-modulith-observability/pom.xml
@@ -13,7 +13,11 @@
org.springframework.modulith.observability
- 2021.0.0
+
+ 1.0.4
+ ${project.basedir}/src/main/java/
+ .*
+ ${project.build.directory}/observation-documentation/
@@ -79,6 +83,12 @@
true
+
+ io.opentelemetry
+ opentelemetry-api
+ true
+
+
@@ -95,4 +105,39 @@
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ generate-docs
+ prepare-package
+
+ java
+
+
+ io.micrometer.docs.DocsGeneratorCommand
+ true
+
+ ${micrometer-docs-generator.inputPath}
+ ${micrometer-docs-generator.inclusionPattern}
+ ${micrometer-docs-generator.outputPath}
+
+
+
+
+
+
+ io.micrometer
+ micrometer-docs-generator
+ ${micrometer-docs-generator.version}
+ jar
+
+
+
+
+
+
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultModulithObservationConvention.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultModulithObservationConvention.java
new file mode 100644
index 00000000..1f1cb5e5
--- /dev/null
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultModulithObservationConvention.java
@@ -0,0 +1,37 @@
+package org.springframework.modulith.observability;
+
+import java.lang.reflect.Method;
+
+import io.micrometer.common.KeyValues;
+import org.springframework.modulith.observability.ModulithObservations.HighKeys;
+import org.springframework.modulith.observability.ModulithObservations.LowKeys;
+
+public class DefaultModulithObservationConvention implements ModulithObservationConvention {
+
+ @Override
+ public KeyValues getLowCardinalityKeyValues(ModulithContext context) {
+ ObservedModule currentModule = context.getModule();
+ if (currentModule != null) {
+ return KeyValues.of(LowKeys.MODULE_KEY.withValue(currentModule.getName()));
+ }
+ return KeyValues.empty();
+ }
+
+ @Override
+ public KeyValues getHighCardinalityKeyValues(ModulithContext context) {
+ Method method = context.getInvocation().getMethod();
+ return KeyValues.of(HighKeys.MODULE_METHOD.withValue(method.getName()));
+ }
+
+ @Override
+ public String getName() {
+ return "module.requests";
+ }
+
+ @Override
+ public String getContextualName(ModulithContext context) {
+ // TODO: Change this to application name
+ return "[" + context.getModule().getDisplayName() + "] " + context.getModule()
+ .getDisplayName();
+ }
+}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultObservedModule.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultObservedModule.java
index 5a54e29a..e97fc963 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultObservedModule.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/DefaultObservedModule.java
@@ -25,6 +25,7 @@ import org.springframework.aop.support.AopUtils;
import org.springframework.modulith.core.ApplicationModule;
import org.springframework.modulith.core.ApplicationModuleIdentifier;
import org.springframework.modulith.core.ApplicationModules;
+import org.springframework.modulith.core.ArchitecturallyEvidentType;
import org.springframework.modulith.core.ArchitecturallyEvidentType.ReferenceMethod;
import org.springframework.modulith.core.FormattableType;
import org.springframework.modulith.core.SpringBean;
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEntryInterceptor.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEntryInterceptor.java
index ee6ffd74..20c67b49 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEntryInterceptor.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEntryInterceptor.java
@@ -15,17 +15,21 @@
*/
package org.springframework.modulith.observability;
-import io.micrometer.tracing.BaggageInScope;
-import io.micrometer.tracing.Tracer;
-import io.micrometer.tracing.Tracer.SpanInScope;
-
import java.util.HashMap;
import java.util.Map;
+import io.micrometer.common.KeyValue;
+import io.micrometer.observation.Observation;
+import io.micrometer.observation.ObservationRegistry;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.modulith.observability.ModulithObservations.LowKeys;
import org.springframework.util.Assert;
class ModuleEntryInterceptor implements MethodInterceptor {
@@ -34,28 +38,49 @@ class ModuleEntryInterceptor implements MethodInterceptor {
private static Map CACHE = new HashMap<>();
private static final String MODULE_KEY = ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY;
+ private static final ModulithObservationConvention DEFAULT = new DefaultModulithObservationConvention();
+
private final ObservedModule module;
- private final Tracer tracer;
+ private final ObservationRegistry observationRegistry;
+ @Nullable private final ModulithObservationConvention customModulithObservationConvention;
/**
- * Creates a new {@link ModuleEntryInterceptor} for the given {@link ObservedModule} and {@link Tracer}.
+ * Creates a new {@link ModuleEntryInterceptor} for the given {@link ObservedModule} and {@link ObservationRegistry}.
*
- * @param module must not be {@literal null}.
- * @param tracer must not be {@literal null}.
+ * @param module must not be {@literal null}.
+ * @param observationRegistry must not be {@literal null}.
*/
- private ModuleEntryInterceptor(ObservedModule module, Tracer tracer) {
-
- Assert.notNull(module, "ObservedModule must not be null!");
- Assert.notNull(tracer, "Tracer must not be null!");
-
- this.module = module;
- this.tracer = tracer;
+ private ModuleEntryInterceptor(ObservedModule module, ObservationRegistry observationRegistry) {
+ this(module, observationRegistry, null);
}
- public static ModuleEntryInterceptor of(ObservedModule module, Tracer tracer) {
+ /**
+ * Creates a new {@link ModuleEntryInterceptor} for the given {@link ObservedModule}, {@link ObservationRegistry}
+ * and {@link ModulithObservationConvention}.
+ *
+ * @param module must not be {@literal null}.
+ * @param observationRegistry must not be {@literal null}.
+ * @param custom must not be {@literal null}.
+ */
+ private ModuleEntryInterceptor(ObservedModule module, ObservationRegistry observationRegistry,
+ ModulithObservationConvention custom) {
+
+ Assert.notNull(module, "ObservedModule must not be null!");
+ Assert.notNull(observationRegistry, "Tracer must not be null!");
+
+ this.module = module; this.observationRegistry = observationRegistry;
+ this.customModulithObservationConvention = custom;
+ }
+
+ public static ModuleEntryInterceptor of(ObservedModule module, ObservationRegistry observationRegistry) {
+ return of(module, observationRegistry, null);
+ }
+
+ public static ModuleEntryInterceptor of(ObservedModule module, ObservationRegistry observationRegistry,
+ ModulithObservationConvention custom) {
return CACHE.computeIfAbsent(module.getName(), __ -> {
- return new ModuleEntryInterceptor(module, tracer);
+ return new ModuleEntryInterceptor(module, observationRegistry, custom);
});
}
@@ -63,15 +88,19 @@ class ModuleEntryInterceptor implements MethodInterceptor {
* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
- @Override
- public Object invoke(MethodInvocation invocation) throws Throwable {
+ @Override public Object invoke(MethodInvocation invocation) throws Throwable {
var moduleName = module.getName();
- var currentSpan = tracer.currentSpan();
- var currentBaggage = tracer.getBaggage(MODULE_KEY);
- var currentModule = currentBaggage != null ? currentBaggage.get() : null;
+ var currentObservation = observationRegistry.getCurrentObservation();
+ String currentModule = null;
- if (currentSpan != null && moduleName.equals(currentModule)) {
+ if (currentObservation != null) {
+ KeyValue moduleKey = currentObservation.getContextView().getLowCardinalityKeyValue(MODULE_KEY);
+ currentModule = moduleKey != null ? moduleKey.getValue() : null;
+ }
+
+ if (currentObservation != null && moduleName.equals(currentModule)) {
+ // Same module
return invocation.proceed();
}
@@ -79,21 +108,20 @@ class ModuleEntryInterceptor implements MethodInterceptor {
LOGGER.trace("Entering {} via {}.", module.getDisplayName(), invokedMethod);
- var span = tracer.spanBuilder()
- .name(moduleName)
- .tag("module.method", invokedMethod)
- .tag(MODULE_KEY, moduleName)
- .start();
-
- try (SpanInScope ws = tracer.withSpan(span);
- BaggageInScope baggage = tracer.createBaggageInScope(MODULE_KEY, moduleName)) {
-
- return invocation.proceed();
+ boolean isEventListener = module.isEventListenerInvocation(invocation);
+ // TODO: Good name for metrics
+ ModulithContext modulithContext = new ModulithContext(module, invocation);
+ var observation = Observation.createNotStarted(customModulithObservationConvention, DEFAULT,
+ () -> modulithContext, observationRegistry); if (isEventListener) {
+ observation.lowCardinalityKeyValue(LowKeys.INVOCATION_TYPE.withValue("event-listener"));
+ } try (Observation.Scope scope = observation.openScope()) {
+ Object proceed = invocation.proceed(); observation.event(ModulithObservations.Events.EVENT_PUBLICATION_SUCCESS);
+ return proceed;
+ } catch (Exception ex) {
+ observation.error(ex); observation.event(ModulithObservations.Events.EVENT_PUBLICATION_FAILURE); throw ex;
} finally {
-
- LOGGER.trace("Leaving {}", module.getDisplayName());
- span.end();
+ LOGGER.trace("Leaving {}", module.getDisplayName()); observation.stop();
}
}
-}
+}
\ No newline at end of file
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEventListener.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEventListener.java
index 64648865..a51ab7e0 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEventListener.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModuleEventListener.java
@@ -15,6 +15,8 @@
*/
package org.springframework.modulith.observability;
+import io.micrometer.observation.Observation.Event;
+import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Tracer;
import java.util.function.Supplier;
@@ -22,6 +24,7 @@ import java.util.function.Supplier;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
+import org.springframework.modulith.observability.ModulithObservations.Events;
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
import org.springframework.util.Assert;
@@ -31,21 +34,21 @@ import org.springframework.util.Assert;
public class ModuleEventListener implements ApplicationListener {
private final ApplicationModulesRuntime runtime;
- private final Supplier tracer;
+ private final Supplier observationRegistry;
/**
* Creates a new {@link ModuleEventListener} for the given {@link ApplicationModulesRuntime} and {@link Tracer}.
*
* @param runtime must not be {@literal null}.
- * @param tracer must not be {@literal null}.
+ * @param observationRegistrySupplier must not be {@literal null}.
*/
- public ModuleEventListener(ApplicationModulesRuntime runtime, Supplier tracer) {
+ public ModuleEventListener(ApplicationModulesRuntime runtime, Supplier observationRegistrySupplier) {
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
- Assert.notNull(tracer, "Tracer must not be null!");
+ Assert.notNull(observationRegistrySupplier, "Tracer must not be null!");
this.runtime = runtime;
- this.tracer = tracer;
+ this.observationRegistry = observationRegistrySupplier;
}
/*
@@ -74,12 +77,12 @@ public class ModuleEventListener implements ApplicationListener tracer;
+ private final Supplier observationRegistry;
private final Map advisors;
private final ConfigurableListableBeanFactory factory;
@@ -56,16 +57,16 @@ public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport impleme
* {@link Tracer}.
*
* @param runtime must not be {@literal null}.
- * @param tracer must not be {@literal null}.
+ * @param observationRegistry must not be {@literal null}.
*/
- public ModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier tracer,
+ public ModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier observationRegistry,
ConfigurableListableBeanFactory factory) {
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
- Assert.notNull(tracer, "Tracer must not be null!");
+ Assert.notNull(observationRegistry, "Tracer must not be null!");
this.runtime = runtime;
- this.tracer = tracer;
+ this.observationRegistry = observationRegistry;
this.advisors = new HashMap<>();
this.factory = factory;
}
@@ -120,7 +121,7 @@ public class ModuleTracingBeanPostProcessor extends ModuleTracingSupport impleme
private Advisor getOrBuildAdvisor(ObservedModule module, ObservedModuleType type) {
return advisors.computeIfAbsent(module.getName(), __ -> {
- return new ApplicationModuleObservingAdvisor(type, ModuleEntryInterceptor.of(module, tracer.get()));
+ return new ApplicationModuleObservingAdvisor(type, ModuleEntryInterceptor.of(module, observationRegistry.get()));
});
}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithContext.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithContext.java
new file mode 100644
index 00000000..d8cdbf45
--- /dev/null
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithContext.java
@@ -0,0 +1,30 @@
+package org.springframework.modulith.observability;
+
+import io.micrometer.observation.Observation;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * A {@link Observation.Context} for Modulithic applications.
+ *
+ * @author Marcin Grzejsczak
+ * @since 1.3
+ */
+public class ModulithContext extends Observation.Context {
+
+ private final ObservedModule module;
+
+ private final MethodInvocation invocation;
+
+ public ModulithContext(ObservedModule module, MethodInvocation invocation) {
+ this.module = module;
+ this.invocation = invocation;
+ }
+
+ public ObservedModule getModule() {
+ return module;
+ }
+
+ public MethodInvocation getInvocation() {
+ return invocation;
+ }
+}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservationConvention.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservationConvention.java
new file mode 100644
index 00000000..04185c77
--- /dev/null
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservationConvention.java
@@ -0,0 +1,18 @@
+package org.springframework.modulith.observability;
+
+import io.micrometer.observation.Observation.Context;
+import io.micrometer.observation.ObservationConvention;
+
+/**
+ * {@link ObservationConvention} for {@link ModulithContext}.
+ *
+ * @author Marcin Grzejszczak
+ * @since 1.3
+ */
+public interface ModulithObservationConvention extends ObservationConvention {
+
+ @Override
+ default boolean supportsContext(Context context) {
+ return context instanceof ModulithContext;
+ }
+}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservations.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservations.java
new file mode 100644
index 00000000..bf68bbe2
--- /dev/null
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ModulithObservations.java
@@ -0,0 +1,92 @@
+package org.springframework.modulith.observability;
+
+import io.micrometer.common.docs.KeyName;
+import io.micrometer.observation.Observation;
+import io.micrometer.observation.Observation.Context;
+import io.micrometer.observation.ObservationConvention;
+import io.micrometer.observation.docs.ObservationDocumentation;
+
+enum ModulithObservations implements ObservationDocumentation {
+
+ /**
+ * Observation related to entering a module.
+ */
+ MODULE_ENTRY {
+ @Override public Class extends ObservationConvention extends Context>> getDefaultConvention() {
+ return DefaultModulithObservationConvention.class;
+ }
+
+ @Override public KeyName[] getLowCardinalityKeyNames() {
+ return LowKeys.values();
+ }
+
+ @Override public KeyName[] getHighCardinalityKeyNames() {
+ return HighKeys.values();
+ }
+
+ @Override public Observation.Event[] getEvents() {
+ return Events.values();
+ }
+ };
+
+ enum LowKeys implements KeyName {
+
+ /**
+ * Name of the module.
+ */
+ MODULE_KEY {
+ @Override public String asString() {
+ return "module.key";
+ }
+ },
+
+ /**
+ * Type of invocation (e.g. event listener).
+ */
+ INVOCATION_TYPE {
+ @Override public String asString() {
+ return "module.invocation-type";
+ }
+ }
+ }
+
+ enum HighKeys implements KeyName {
+ /**
+ * Method executed on a module.
+ */
+ MODULE_METHOD {
+ @Override public String asString() {
+ return "module.method";
+ }
+ }
+ }
+
+ enum Events implements Observation.Event {
+
+ /**
+ * Published when an event is sent successfully.
+ */
+ EVENT_PUBLICATION_SUCCESS {
+ @Override public String getName() {
+ return "event.publication.success";
+ }
+
+ @Override public String getContextualName() {
+ return getName();
+ }
+ },
+
+ /**
+ * Published when an event is sent with a failure.
+ */
+ EVENT_PUBLICATION_FAILURE {
+ @Override public String getName() {
+ return "event.publication.failure";
+ }
+
+ @Override public String getContextualName() {
+ return getName();
+ }
+ }
+ }
+}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModule.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModule.java
index 763c0d8a..096929ac 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModule.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModule.java
@@ -24,11 +24,15 @@ import org.springframework.modulith.core.ApplicationModuleIdentifier;
import org.springframework.modulith.core.ApplicationModules;
import com.tngtech.archunit.core.domain.JavaClass;
+import org.springframework.modulith.core.ArchitecturallyEvidentType;
/**
+ * Information about observed module.
+ *
* @author Oliver Drotbohm
+ * @since 1.3
*/
-interface ObservedModule {
+public interface ObservedModule {
/**
* Returns the name of the application module.
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModuleType.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModuleType.java
index 357a1cc2..06658cc8 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModuleType.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/ObservedModuleType.java
@@ -35,8 +35,9 @@ import org.springframework.util.ReflectionUtils;
* Represents a type in an {@link ObservedModule}.
*
* @author Oliver Drotbohm
+ * @since 1.3
*/
-class ObservedModuleType {
+public class ObservedModuleType {
private static Collection> IGNORED_TYPES = List.of(Advised.class, TargetClassAware.class);
private static Predicate IS_USER_METHOD = it -> !Modifier.isPrivate(it.getModifiers())
@@ -115,4 +116,5 @@ class ObservedModuleType {
.map(it -> !module.isObservedModule(it))
.orElse(true);
}
+
}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/SpringDataRestModuleTracingBeanPostProcessor.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/SpringDataRestModuleTracingBeanPostProcessor.java
index 830baf25..b08a9f93 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/SpringDataRestModuleTracingBeanPostProcessor.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/SpringDataRestModuleTracingBeanPostProcessor.java
@@ -15,6 +15,7 @@
*/
package org.springframework.modulith.observability;
+import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Tracer;
import java.util.function.Supplier;
@@ -40,22 +41,22 @@ import org.springframework.util.Assert;
public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingSupport implements BeanPostProcessor {
private final ApplicationModulesRuntime runtime;
- private final Supplier tracer;
+ private final Supplier observationRegistry;
/**
* Creates a new {@link SpringDataRestModuleTracingBeanPostProcessor} for the given {@link ApplicationModulesRuntime}
* and {@link Tracer}.
*
* @param runtime must not be {@literal null}.
- * @param tracer must not be {@literal null}.
+ * @param observationRegistry must not be {@literal null}.
*/
- public SpringDataRestModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier tracer) {
+ public SpringDataRestModuleTracingBeanPostProcessor(ApplicationModulesRuntime runtime, Supplier observationRegistry) {
Assert.notNull(runtime, "ApplicationModulesRuntime must not be null!");
- Assert.notNull(tracer, "Tracer must not be null!");
+ Assert.notNull(observationRegistry, "ObservationRegistry must not be null!");
this.runtime = runtime;
- this.tracer = tracer;
+ this.observationRegistry = observationRegistry;
}
/*
@@ -71,7 +72,7 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
return bean;
}
- Advice interceptor = new DataRestControllerInterceptor(runtime, tracer);
+ Advice interceptor = new DataRestControllerInterceptor(runtime, observationRegistry);
Advisor advisor = new DefaultPointcutAdvisor(interceptor);
return addAdvisor(bean, advisor, it -> it.setProxyTargetClass(true));
@@ -80,21 +81,21 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
private static class DataRestControllerInterceptor implements MethodInterceptor {
private final Supplier modules;
- private final Supplier tracer;
+ private final Supplier observationRegistry;
/**
* Creates a new {@link DataRestControllerInterceptor} for the given {@link ApplicationModules} and {@link Tracer}.
*
* @param modules must not be {@literal null}.
- * @param tracer must not be {@literal null}.
+ * @param observationRegistry must not be {@literal null}.
*/
- private DataRestControllerInterceptor(Supplier modules, Supplier tracer) {
+ private DataRestControllerInterceptor(Supplier modules, Supplier observationRegistry) {
Assert.notNull(modules, "ApplicationModules must not be null!");
- Assert.notNull(tracer, "Tracer must not be null!");
+ Assert.notNull(observationRegistry, "Tracer must not be null!");
this.modules = modules;
- this.tracer = tracer;
+ this.observationRegistry = observationRegistry;
}
/*
@@ -112,7 +113,7 @@ public class SpringDataRestModuleTracingBeanPostProcessor extends ModuleTracingS
var observed = new DefaultObservedModule(module);
- return ModuleEntryInterceptor.of(observed, tracer.get()).invoke(invocation);
+ return ModuleEntryInterceptor.of(observed, observationRegistry.get()).invoke(invocation);
}
private ApplicationModule getModuleFrom(Object[] arguments) {
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/ModuleObservabilityAutoConfiguration.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/ModuleObservabilityAutoConfiguration.java
index 2023d3d5..eeeba7fa 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/ModuleObservabilityAutoConfiguration.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/ModuleObservabilityAutoConfiguration.java
@@ -15,18 +15,10 @@
*/
package org.springframework.modulith.observability.autoconfigure;
-import brave.TracingCustomizer;
-import brave.baggage.BaggageField;
-import brave.baggage.BaggagePropagationConfig;
-import brave.baggage.BaggagePropagationCustomizer;
-import brave.handler.MutableSpan;
-import brave.handler.SpanHandler;
-import brave.propagation.TraceContext;
-import io.micrometer.tracing.Tracer;
+import io.micrometer.observation.ObservationRegistry;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
import org.springframework.boot.autoconfigure.thread.Threading;
@@ -48,16 +40,17 @@ class ModuleObservabilityAutoConfiguration {
@Bean
static ModuleTracingBeanPostProcessor moduleTracingBeanPostProcessor(ApplicationModulesRuntime runtime,
- ObjectProvider tracer, ConfigurableListableBeanFactory factory) {
- return new ModuleTracingBeanPostProcessor(runtime, () -> tracer.getObject(), factory);
+ ObjectProvider observationRegistry, ConfigurableListableBeanFactory factory) {
+ return new ModuleTracingBeanPostProcessor(runtime, observationRegistry::getObject, factory);
}
@Bean
static ModuleEventListener tracingModuleEventListener(ApplicationModulesRuntime runtime,
- ObjectProvider tracer) {
- return new ModuleEventListener(runtime, () -> tracer.getObject());
+ ObjectProvider observationRegistry) {
+ return new ModuleEventListener(runtime, observationRegistry::getObject);
}
+ // TODO: Have a custom thread pool for modulith
@Bean
@ConditionalOnThreading(Threading.VIRTUAL)
SimpleAsyncTaskExecutorCustomizer simpleAsyncTaskExecutorCustomizer() {
@@ -69,52 +62,4 @@ class ModuleObservabilityAutoConfiguration {
ThreadPoolTaskExecutorCustomizer threadPoolTaskExecutorCustomizer() {
return executor -> executor.setTaskDecorator(new ContextPropagatingTaskDecorator());
}
-
- /**
- * Brave-specific auto configuration.
- *
- * @author Oliver Drotbohm
- */
- @ConditionalOnClass(TracingCustomizer.class)
- static class ModulithsBraveIntegrationAutoConfiguration {
-
- @Bean
- BaggagePropagationCustomizer moduleBaggagePropagationCustomizer() {
-
- return builder -> builder
- .add(BaggagePropagationConfig.SingleBaggageField
- .local(BaggageField.create(ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY)));
- }
-
- @Bean
- SpanHandler spanHandler() {
-
- return new SpanHandler() {
-
- /*
- * (non-Javadoc)
- * @see brave.handler.SpanHandler#end(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.handler.SpanHandler.Cause)
- */
- @Override
- public boolean end(TraceContext context, MutableSpan span, Cause cause) {
-
- String value = span.tag(ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY);
-
- if (value != null) {
- span.localServiceName(value);
- return true;
- }
-
- BaggageField field = BaggageField.getByName(context, ModuleTracingBeanPostProcessor.MODULE_BAGGAGE_KEY);
- value = field.getValue();
-
- if (value != null) {
- span.localServiceName(value);
- }
-
- return true;
- }
- };
- }
- }
}
diff --git a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/SpringDataRestModuleObservabilityAutoConfiguration.java b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/SpringDataRestModuleObservabilityAutoConfiguration.java
index 2b71ac46..7b00cad7 100644
--- a/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/SpringDataRestModuleObservabilityAutoConfiguration.java
+++ b/spring-modulith-observability/src/main/java/org/springframework/modulith/observability/autoconfigure/SpringDataRestModuleObservabilityAutoConfiguration.java
@@ -15,6 +15,7 @@
*/
package org.springframework.modulith.observability.autoconfigure;
+import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Tracer;
import org.springframework.beans.factory.ObjectProvider;
@@ -34,8 +35,8 @@ class SpringDataRestModuleObservabilityAutoConfiguration {
@Bean
static SpringDataRestModuleTracingBeanPostProcessor springDataRestModuleTracingBeanPostProcessor(
- ApplicationModulesRuntime runtime, ObjectProvider tracer) {
+ ApplicationModulesRuntime runtime, ObjectProvider observationRegistry) {
- return new SpringDataRestModuleTracingBeanPostProcessor(runtime, () -> tracer.getObject());
+ return new SpringDataRestModuleTracingBeanPostProcessor(runtime, () -> observationRegistry.getObject());
}
}
diff --git a/spring-modulith-observability/src/test/java/org/springframework/modulith/observability/ModuleTracingBeanPostProcessorIntegrationTests.java b/spring-modulith-observability/src/test/java/org/springframework/modulith/observability/ModuleTracingBeanPostProcessorIntegrationTests.java
index 3e12cd76..57202e12 100644
--- a/spring-modulith-observability/src/test/java/org/springframework/modulith/observability/ModuleTracingBeanPostProcessorIntegrationTests.java
+++ b/spring-modulith-observability/src/test/java/org/springframework/modulith/observability/ModuleTracingBeanPostProcessorIntegrationTests.java
@@ -20,6 +20,7 @@ import static org.mockito.Mockito.*;
import example.ExampleApplication;
import example.sample.SampleComponent;
+import io.micrometer.observation.ObservationRegistry;
import io.micrometer.tracing.Tracer;
import org.junit.jupiter.api.Test;
@@ -70,7 +71,7 @@ class ModuleTracingBeanPostProcessorIntegrationTests {
var modulesRuntime = new ApplicationModulesRuntime(() -> TestApplicationModules.of(ExampleApplication.class),
runtime);
- return new ModuleTracingBeanPostProcessor(modulesRuntime, () -> mock(Tracer.class), context.getBeanFactory());
+ return new ModuleTracingBeanPostProcessor(modulesRuntime, () -> ObservationRegistry.NOOP, context.getBeanFactory());
}
}