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 =
15+ getOutcomeTrackingRunnableField (outcomeTrackingRunnableClass );
16+
17+ private static Class <?> getOutcomeTrackingRunnableClass () {
18+ try {
19+ return Class .forName ("org.springframework.scheduling.config.Task$OutcomeTrackingRunnable" );
20+ } catch (ClassNotFoundException exception ) {
21+ return null ;
22+ }
23+ }
24+
25+ private static Field getOutcomeTrackingRunnableField (Class <?> clazz ) {
26+ try {
27+ Field field = clazz .getDeclaredField ("runnable" );
28+ field .setAccessible (true );
29+ return field ;
30+ } catch (Exception exception ) {
31+ return null ;
32+ }
33+ }
34+
35+ private static Runnable unwrap (Runnable runnable ) {
36+ if (outcomeTrackingRunnableClass != null
37+ && outcomeTrackingRunnableField != null
38+ && outcomeTrackingRunnableClass .isAssignableFrom (runnable .getClass ())) {
39+ try {
40+ // task may be wrapped multiple times so
41+ return unwrap ((Runnable ) outcomeTrackingRunnableField .get (runnable ));
42+ } catch (IllegalAccessException ignore ) {
43+ // should not happen because setAccessible was called
44+ }
45+ }
46+ return runnable ;
47+ }
1248
1349 @ Override
1450 public Class <?> getCodeClass (Runnable runnable ) {
51+ runnable = unwrap (runnable );
1552 if (runnable instanceof ScheduledMethodRunnable ) {
1653 ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
1754 return scheduledMethodRunnable .getMethod ().getDeclaringClass ();
@@ -22,6 +59,7 @@ public Class<?> getCodeClass(Runnable runnable) {
2259
2360 @ Override
2461 public String getMethodName (Runnable runnable ) {
62+ runnable = unwrap (runnable );
2563 if (runnable instanceof ScheduledMethodRunnable ) {
2664 ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
2765 return scheduledMethodRunnable .getMethod ().getName ();
0 commit comments