Skip to content

Commit c0fb986

Browse files
committed
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.
1 parent 7459c6f commit c0fb986

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.micrometer.observation.Observation;
1919
import io.micrometer.observation.ObservationRegistry;
20+
import io.micrometer.observation.ObservationView;
2021
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
2122

2223
import java.util.function.BiConsumer;
@@ -191,7 +192,13 @@ private void stopObservation(@Nullable RequestContext requestContext,
191192
log.debug(
192193
"Restoring parent observation [" + observation + "] for Mongo instrumentation and put it in Mongo context");
193194
}
194-
requestContext.put(ObservationThreadLocalAccessor.KEY, observation.getContext().getParentObservation());
195+
ObservationView parentObservation = observation.getContext().getParentObservation();
196+
197+
if (parentObservation == null) {
198+
requestContext.delete(ObservationThreadLocalAccessor.KEY);
199+
} else {
200+
requestContext.put(ObservationThreadLocalAccessor.KEY, parentObservation);
201+
}
195202
}
196203
}
197204

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.micrometer.observation.Observation;
2727
import io.micrometer.observation.ObservationRegistry;
2828
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
29+
import reactor.core.publisher.BaseSubscriber;
2930

3031
import org.assertj.core.api.Assertions;
3132
import org.bson.BsonDocument;
@@ -43,6 +44,7 @@
4344
import com.mongodb.event.CommandFailedEvent;
4445
import com.mongodb.event.CommandStartedEvent;
4546
import com.mongodb.event.CommandSucceededEvent;
47+
import com.mongodb.reactivestreams.client.ReactiveContextProvider;
4648

4749
/**
4850
* Series of test cases exercising {@link MongoObservationCommandListener}.
@@ -113,6 +115,25 @@ void commandStartedShouldAlwaysIncludeCollection() {
113115
Tags.of("db.mongodb.collection", "none"));
114116
}
115117

118+
@Test // GH-5082
119+
void reactiveContextCompletesNormally() {
120+
121+
ReactiveContextProvider rcp = (ReactiveContextProvider) ContextProviderFactory.create(observationRegistry);
122+
RequestContext context = rcp.getContext(new BaseSubscriber<>() {});
123+
124+
listener.commandStarted(new CommandStartedEvent(context, 0, 0, //
125+
new ConnectionDescription( //
126+
new ServerId( //
127+
new ClusterId("description"), //
128+
new ServerAddress("localhost", 1234))),
129+
"database", "insert", //
130+
new BsonDocument("collection", new BsonString("user"))));
131+
listener.commandSucceeded(new CommandSucceededEvent(context, 0, 0, null, "insert", null, null, 0));
132+
133+
// then
134+
assertThatTimerRegisteredWithTags();
135+
}
136+
116137
@Test
117138
void successfullyCompletedCommandShouldCreateTimerWhenParentSampleInRequestContext() {
118139

0 commit comments

Comments
 (0)