55
66package io .opentelemetry .javaagent .bootstrap .executors ;
77
8+ import io .opentelemetry .api .GlobalOpenTelemetry ;
9+ import io .opentelemetry .api .common .AttributeKey ;
10+ import io .opentelemetry .api .common .Attributes ;
11+ import io .opentelemetry .api .metrics .DoubleHistogram ;
812import io .opentelemetry .context .Context ;
913import io .opentelemetry .context .Scope ;
1014import io .opentelemetry .instrumentation .api .internal .ContextPropagationDebug ;
15+ import java .util .concurrent .TimeUnit ;
1116
1217public final class ContextPropagatingRunnable implements Runnable {
1318
@@ -22,18 +27,36 @@ public static boolean shouldDecorateRunnable(Runnable task) {
2227 public static Runnable propagateContext (Runnable task , Context context ) {
2328 return new ContextPropagatingRunnable (task , context );
2429 }
25-
30+ private static final double NANOS_PER_S = TimeUnit . SECONDS . toNanos ( 1 );
2631 private final Runnable delegate ;
2732 private final Context context ;
33+ private final Long startObservation ;
34+ private final DoubleHistogram pendingTimeHistogram ;
2835
2936 private ContextPropagatingRunnable (Runnable delegate , Context context ) {
3037 this .delegate = delegate ;
3138 this .context = ContextPropagationDebug .addDebugInfo (context , delegate );
39+ this .startObservation = System .nanoTime ();
40+
41+ this .pendingTimeHistogram =
42+ GlobalOpenTelemetry
43+ .getMeter ("thread.pending.duration" )
44+ .histogramBuilder ("thread.pending.duration" )
45+ .setUnit ("s" )
46+ .setDescription ("Duration of HTTP client requests." )
47+ .build ();
3248 }
3349
3450 @ Override
3551 public void run () {
3652 try (Scope ignored = context .makeCurrent ()) {
53+ pendingTimeHistogram
54+ .record (System .nanoTime () - startObservation / NANOS_PER_S ,
55+ Attributes .of (
56+ AttributeKey .stringKey ("thread" ),
57+ Thread .currentThread ().getName ()
58+ )
59+ );
3760 delegate .run ();
3861 }
3962 }
0 commit comments