@@ -310,6 +310,61 @@ public void doFilterWhenMatchesThenObservationRegistryObserves() throws Exceptio
310
310
assertFilterChainObservation (contexts .next (), "after" , 1 );
311
311
}
312
312
313
+ // gh-12610
314
+ @ Test
315
+ void parentObservationIsTakenIntoAccountDuringDispatchError () throws Exception {
316
+ ObservationHandler <Observation .Context > handler = mock (ObservationHandler .class );
317
+ given (handler .supportsContext (any ())).willReturn (true );
318
+ ObservationRegistry registry = ObservationRegistry .create ();
319
+ registry .observationConfig ().observationHandler (handler );
320
+
321
+ given (this .matcher .matches (any ())).willReturn (true );
322
+ SecurityFilterChain sec = new DefaultSecurityFilterChain (this .matcher , Arrays .asList (this .filter ));
323
+ FilterChainProxy fcp = new FilterChainProxy (sec );
324
+ fcp .setFilterChainDecorator (new ObservationFilterChainDecorator (registry ));
325
+ Filter initialFilter = ObservationFilterChainDecorator .FilterObservation
326
+ .create (Observation .createNotStarted ("wrap" , registry ))
327
+ .wrap (fcp );
328
+
329
+ ServletRequest initialRequest = new MockHttpServletRequest ("GET" , "/" );
330
+ initialFilter .doFilter (initialRequest , new MockHttpServletResponse (), this .chain );
331
+
332
+ // simulate request attribute copying in case dispatching to ERROR
333
+ ObservationFilterChainDecorator .AroundFilterObservation parentObservation = (ObservationFilterChainDecorator .AroundFilterObservation ) initialRequest .getAttribute (ObservationFilterChainDecorator .ATTRIBUTE );
334
+ assertThat (parentObservation ).isNotNull ();
335
+
336
+ // simulate dispatching error-related request
337
+ Filter errorRelatedFilter = ObservationFilterChainDecorator .FilterObservation
338
+ .create (Observation .createNotStarted ("wrap" , registry ))
339
+ .wrap (fcp );
340
+ ServletRequest errorRelatedRequest = new MockHttpServletRequest ("GET" , "/error" );
341
+ errorRelatedRequest .setAttribute (ObservationFilterChainDecorator .ATTRIBUTE , parentObservation );
342
+ errorRelatedFilter .doFilter (errorRelatedRequest , new MockHttpServletResponse (), this .chain );
343
+
344
+ ArgumentCaptor <Observation .Context > captor = ArgumentCaptor .forClass (Observation .Context .class );
345
+ verify (handler , times (8 )).onStart (captor .capture ());
346
+ verify (handler , times (8 )).onStop (any ());
347
+ List <Observation .Context > contexts = captor .getAllValues ();
348
+
349
+ Observation .Context initialRequestObservationContextBefore = contexts .get (1 );
350
+ Observation .Context initialRequestObservationContextAfter = contexts .get (3 );
351
+ assertFilterChainObservation (initialRequestObservationContextBefore , "before" , 1 );
352
+ assertFilterChainObservation (initialRequestObservationContextAfter , "after" , 1 );
353
+
354
+ assertThat (initialRequestObservationContextBefore .getParentObservation ()).isNotNull ();
355
+ assertThat (initialRequestObservationContextBefore .getParentObservation ()).isSameAs (initialRequestObservationContextAfter .getParentObservation ());
356
+
357
+ Observation .Context errorRelatedRequestObservationContextBefore = contexts .get (5 );
358
+ Observation .Context errorRelatedRequestObservationContextAfter = contexts .get (7 );
359
+ assertFilterChainObservation (errorRelatedRequestObservationContextBefore , "before" , 1 );
360
+ assertFilterChainObservation (errorRelatedRequestObservationContextAfter , "after" , 1 );
361
+
362
+ assertThat (errorRelatedRequestObservationContextBefore .getParentObservation ()).isNotNull ();
363
+ assertThat (errorRelatedRequestObservationContextBefore .getParentObservation ()).isSameAs (initialRequestObservationContextBefore .getParentObservation ());
364
+ assertThat (errorRelatedRequestObservationContextAfter .getParentObservation ()).isNotNull ();
365
+ assertThat (errorRelatedRequestObservationContextAfter .getParentObservation ()).isSameAs (initialRequestObservationContextBefore .getParentObservation ());
366
+ }
367
+
313
368
@ Test
314
369
public void doFilterWhenMultipleFiltersThenObservationRegistryObserves () throws Exception {
315
370
ObservationHandler <Observation .Context > handler = mock (ObservationHandler .class );
0 commit comments