Browse Source

Remove parent observation key instead of setting null.

When completing a MongoObservation without a parent observation, we now remove the parent observation key from the request context instead of setting it to null.

In reactive usage, the context map is a ConcurrentHashMap that does not allow null values.

Closes #5082
Original pull request #5083
issue/aot-doc
Mark Paluch 2 months ago committed by Jens Schauder
parent
commit
791d64f1ac
No known key found for this signature in database
GPG Key ID: 2BE5D185CD2A1CE6
  1. 9
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java
  2. 21
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java

9
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoObservationCommandListener.java

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.observability; @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.observability;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.ObservationView;
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
import java.util.function.BiConsumer;
@ -191,7 +192,13 @@ public class MongoObservationCommandListener implements CommandListener { @@ -191,7 +192,13 @@ public class MongoObservationCommandListener implements CommandListener {
log.debug(
"Restoring parent observation [" + observation + "] for Mongo instrumentation and put it in Mongo context");
}
requestContext.put(ObservationThreadLocalAccessor.KEY, observation.getContext().getParentObservation());
ObservationView parentObservation = observation.getContext().getParentObservation();
if (parentObservation == null) {
requestContext.delete(ObservationThreadLocalAccessor.KEY);
} else {
requestContext.put(ObservationThreadLocalAccessor.KEY, parentObservation);
}
}
}

21
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/observability/MongoObservationCommandListenerTests.java

@ -26,6 +26,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; @@ -26,6 +26,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
import reactor.core.publisher.BaseSubscriber;
import org.assertj.core.api.Assertions;
import org.bson.BsonDocument;
@ -43,6 +44,7 @@ import com.mongodb.connection.ServerId; @@ -43,6 +44,7 @@ import com.mongodb.connection.ServerId;
import com.mongodb.event.CommandFailedEvent;
import com.mongodb.event.CommandStartedEvent;
import com.mongodb.event.CommandSucceededEvent;
import com.mongodb.reactivestreams.client.ReactiveContextProvider;
/**
* Series of test cases exercising {@link MongoObservationCommandListener}.
@ -113,6 +115,25 @@ class MongoObservationCommandListenerTests { @@ -113,6 +115,25 @@ class MongoObservationCommandListenerTests {
Tags.of("db.mongodb.collection", "none"));
}
@Test // GH-5082
void reactiveContextCompletesNormally() {
ReactiveContextProvider rcp = (ReactiveContextProvider) ContextProviderFactory.create(observationRegistry);
RequestContext context = rcp.getContext(new BaseSubscriber<>() {});
listener.commandStarted(new CommandStartedEvent(context, 0, 0, //
new ConnectionDescription( //
new ServerId( //
new ClusterId("description"), //
new ServerAddress("localhost", 1234))),
"database", "insert", //
new BsonDocument("collection", new BsonString("user"))));
listener.commandSucceeded(new CommandSucceededEvent(context, 0, 0, null, "insert", null, null, 0));
// then
assertThatTimerRegisteredWithTags();
}
@Test
void successfullyCompletedCommandShouldCreateTimerWhenParentSampleInRequestContext() {

Loading…
Cancel
Save