From 763e0a3ce15c8ba2e992d0fa426ae7a4350cc367 Mon Sep 17 00:00:00 2001 From: Tomasz Grzejszczyk Date: Fri, 25 Jul 2025 15:58:44 +0200 Subject: [PATCH] #6313 handle out-of-order scope closure Signed-off-by: Tomasz Grzejszczyk --- .../observation/ObservationRegistry.java | 9 +++++++++ .../observation/SimpleObservation.java | 5 ++++- .../observation/SimpleObservationRegistry.java | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationRegistry.java b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationRegistry.java index c883c77769..ddd78b9662 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationRegistry.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationRegistry.java @@ -73,6 +73,15 @@ static ObservationRegistry create() { */ void setCurrentObservationScope(Observation.@Nullable Scope current); + /** + * Sets the observation scope as current only if the candidate is present in the + * registry. + * @param candidate observation scope + */ + default void setCurrentObservationScopeIfExists(Observation.@Nullable Scope candidate) { + setCurrentObservationScope(candidate); + } + /** * Configuration options for this registry. * @return observation configuration diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java index 591f3b0bd7..dd4e2e0f57 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java @@ -313,7 +313,10 @@ else if (currentObservation != null && !currentObservation.isNoop()) { else { log.trace("NoOp observation used with SimpleScope"); } - this.registry.setCurrentObservationScope(previousObservationScope); + // DB connections might be closed out of order, so only set the previous scope + // as current if it has not been already closed (by checking if it still + // exists in the registry). + this.registry.setCurrentObservationScopeIfExists(previousObservationScope); } private @Nullable SimpleScope getLastScope(SimpleScope simpleScope) { diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservationRegistry.java b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservationRegistry.java index 09307d08b8..8d76dc1070 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservationRegistry.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservationRegistry.java @@ -50,6 +50,23 @@ public void setCurrentObservationScope(Observation.@Nullable Scope current) { localObservationScope.set(current); } + @Override + public void setCurrentObservationScopeIfExists(Observation.@Nullable Scope candidate) { + if (candidate == null) { + setCurrentObservationScope(null); + } + else { + Observation.Scope scope = localObservationScope.get(); + while (scope != null) { + if (scope.equals(candidate)) { + setCurrentObservationScope(candidate); + break; + } + scope = scope.getPreviousObservationScope(); + } + } + } + @Override public ObservationConfig observationConfig() { return this.observationConfig;