6
6
package io .opentelemetry .javaagent .instrumentation .spring .scheduling .v3_1 ;
7
7
8
8
import io .opentelemetry .instrumentation .api .incubator .semconv .code .CodeAttributesGetter ;
9
+ import java .lang .reflect .Field ;
9
10
import org .springframework .scheduling .support .ScheduledMethodRunnable ;
10
11
11
12
public 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
+ }
12
48
13
49
@ Override
14
50
public Class <?> getCodeClass (Runnable runnable ) {
51
+ runnable = unwrap (runnable );
15
52
if (runnable instanceof ScheduledMethodRunnable ) {
16
53
ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
17
54
return scheduledMethodRunnable .getMethod ().getDeclaringClass ();
@@ -22,6 +59,7 @@ public Class<?> getCodeClass(Runnable runnable) {
22
59
23
60
@ Override
24
61
public String getMethodName (Runnable runnable ) {
62
+ runnable = unwrap (runnable );
25
63
if (runnable instanceof ScheduledMethodRunnable ) {
26
64
ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable ) runnable ;
27
65
return scheduledMethodRunnable .getMethod ().getName ();
0 commit comments