66package io .opentelemetry .javaagent .instrumentation .spring .scheduling .v3_1 ;
77
88import io .opentelemetry .instrumentation .api .incubator .semconv .code .CodeAttributesGetter ;
9+ import java .lang .reflect .Field ;
910import org .springframework .scheduling .support .ScheduledMethodRunnable ;
1011
1112public class SpringSchedulingCodeAttributesGetter implements CodeAttributesGetter <Runnable > {
13+ private static final Class <?> outcomeTrackingRunnableClass = getOutcomeTrackingRunnableClass ();
14+ private static final Field outcomeTrackingRunnableField = getOutcomeTrackingRunnableField (outcomeTrackingRunnableClass );
15+
16+ private static Class <?> getOutcomeTrackingRunnableClass () {
17+ try {
18+ return Class .forName ("org.springframework.scheduling.config.Task$OutcomeTrackingRunnable" );
19+ } catch (ClassNotFoundException exception ) {
20+ return null ;
21+ }
22+ }
23+
24+ private static Field getOutcomeTrackingRunnableField (Class <?> clazz ) {
25+ try {
26+ Field field = clazz .getDeclaredField ("runnable" );
27+ field .setAccessible (true );
28+ return field ;
29+ } catch (Exception exception ) {
30+ return null ;
31+ }
32+ }
33+
34+ private static Runnable unwrap (Runnable runnable ) {
35+ if (outcomeTrackingRunnableClass != null && outcomeTrackingRunnableField != null && outcomeTrackingRunnableClass .isAssignableFrom (runnable .getClass ())) {
36+ try {
37+ // task may be wrapped multiple times so
38+ return unwrap ((Runnable ) outcomeTrackingRunnableField .get (runnable ));
39+ } catch (IllegalAccessException ignore ) {
40+ // should not happen because setAccessible was called
41+ }
42+ }
43+ return runnable ;
44+ }
1245
1346 @ Override
1447 public Class <?> getCodeClass (Runnable runnable ) {
48+ runnable = unwrap (runnable );
1549 if (runnable instanceof ScheduledMethodRunnable ) {
1650 ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
1751 return scheduledMethodRunnable .getMethod ().getDeclaringClass ();
@@ -22,6 +56,7 @@ public Class<?> getCodeClass(Runnable runnable) {
2256
2357 @ Override
2458 public String getMethodName (Runnable runnable ) {
59+ runnable = unwrap (runnable );
2560 if (runnable instanceof ScheduledMethodRunnable ) {
2661 ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
2762 return scheduledMethodRunnable .getMethod ().getName ();
0 commit comments