2929import io .micrometer .observation .Observation ;
3030import io .micrometer .observation .ObservationConvention ;
3131import io .micrometer .observation .ObservationRegistry ;
32+ import io .micrometer .observation .ObservationView ;
3233import jakarta .servlet .Filter ;
3334import jakarta .servlet .FilterChain ;
3435import jakarta .servlet .ServletException ;
@@ -54,6 +55,12 @@ public final class ObservationFilterChainDecorator implements FilterChainProxy.F
5455
5556 private static final String ATTRIBUTE = ObservationFilterChainDecorator .class + ".observation" ;
5657
58+ private static final String ATTRIBUTE_BEFORE_OBSERVATION_VIEW = ObservationFilterChainDecorator .class
59+ + ".observation.view.before" ;
60+
61+ private static final String ATTRIBUTE_AFTER_OBSERVATION_VIEW = ObservationFilterChainDecorator .class
62+ + ".observation.view.after" ;
63+
5764 static final String UNSECURED_OBSERVATION_NAME = "spring.security.http.unsecured.requests" ;
5865
5966 static final String SECURED_OBSERVATION_NAME = "spring.security.http.secured.requests" ;
@@ -250,9 +257,30 @@ private void wrapFilter(ServletRequest request, ServletResponse response, Filter
250257 private AroundFilterObservation parent (HttpServletRequest request ) {
251258 FilterChainObservationContext beforeContext = FilterChainObservationContext .before ();
252259 FilterChainObservationContext afterContext = FilterChainObservationContext .after ();
260+
261+ Object maybeBeforeObservationView = request .getAttribute (ATTRIBUTE_BEFORE_OBSERVATION_VIEW );
262+ if (maybeBeforeObservationView != null ) {
263+ ObservationView observationView = (ObservationView ) maybeBeforeObservationView ;
264+ beforeContext .setParentObservation (observationView );
265+ }
266+
267+ Object maybeAfterObservationView = request .getAttribute (ATTRIBUTE_AFTER_OBSERVATION_VIEW );
268+ if (maybeAfterObservationView != null ) {
269+ ObservationView observationView = (ObservationView ) maybeAfterObservationView ;
270+ afterContext .setParentObservation (observationView );
271+ }
272+
253273 Observation before = Observation .createNotStarted (this .convention , () -> beforeContext , this .registry );
254274 Observation after = Observation .createNotStarted (this .convention , () -> afterContext , this .registry );
255275 AroundFilterObservation parent = AroundFilterObservation .create (before , after );
276+
277+ if (request .getAttribute (ATTRIBUTE_BEFORE_OBSERVATION_VIEW ) == null ) {
278+ request .setAttribute (ATTRIBUTE_BEFORE_OBSERVATION_VIEW , before .getContext ().getParentObservation ());
279+ }
280+ if (request .getAttribute (ATTRIBUTE_AFTER_OBSERVATION_VIEW ) == null ) {
281+ request .setAttribute (ATTRIBUTE_AFTER_OBSERVATION_VIEW , after .getContext ().getParentObservation ());
282+ }
283+
256284 request .setAttribute (ATTRIBUTE , parent );
257285 return parent ;
258286 }
0 commit comments