18
18
*/
19
19
package co .elastic .otel .dynamicconfig ;
20
20
21
- import static co .elastic .otel .dynamicconfig .DynamicConfiguration .INSTRUMENTATION_NAME_PREPEND ;
22
-
23
- import io .opentelemetry .api .trace .Tracer ;
24
21
import io .opentelemetry .api .trace .TracerProvider ;
25
- import io .opentelemetry .sdk .common .InstrumentationScopeInfo ;
26
- import io .opentelemetry .sdk .internal .ComponentRegistry ;
27
22
import io .opentelemetry .sdk .internal .ScopeConfigurator ;
28
23
import io .opentelemetry .sdk .trace .SdkTracerProvider ;
29
24
import io .opentelemetry .sdk .trace .SdkTracerProviderBuilder ;
30
25
import io .opentelemetry .sdk .trace .internal .TracerConfig ;
31
26
import java .lang .reflect .Field ;
32
27
import java .lang .reflect .InvocationTargetException ;
33
28
import java .lang .reflect .Method ;
34
- import java .util .ArrayList ;
35
- import java .util .List ;
36
- import java .util .logging .Level ;
37
- import java .util .logging .Logger ;
38
29
39
30
/**
40
31
* Notes: 1. The instrumentation can't have been disabled by configuration, eg using
41
32
* -Dotel.instrumentation.[name].enabled=false as in that case it is never initialized so can't be
42
- * "re-enabled" 2. The specific instrumentation name is used, you can see these by setting this
43
- * class logging level to j.u.l.Level.CONFIG 3. The disable/re-enable is eventually consistent,
44
- * needing the application to pass a synchronization barrier to take effect - but for most
45
- * applications these are very frequent
33
+ * "re-enabled" 2. The disable/re-enable is eventually consistent, needing the application to pass a
34
+ * synchronization barrier to take effect - but for most applications these are very frequent
46
35
*/
47
36
public class DynamicInstrumentation {
48
37
49
- private static final Logger logger = Logger .getLogger (DynamicInstrumentation .class .getName ());
50
-
51
38
private static Object getField (String fieldname , Object target ) {
52
39
try {
53
40
Field field = target .getClass ().getDeclaredField (fieldname );
@@ -59,17 +46,6 @@ private static Object getField(String fieldname, Object target) {
59
46
}
60
47
}
61
48
62
- private static Object call (String methodname , Object target ) {
63
- try {
64
- Method method = target .getClass ().getDeclaredMethod (methodname );
65
- method .setAccessible (true );
66
- return method .invoke (target );
67
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) {
68
- throw new IllegalStateException (
69
- "Error calling " + methodname + " on " + target .getClass (), e );
70
- }
71
- }
72
-
73
49
private static <T > Object call (
74
50
String methodname , Object target , T arg1 , Class <? super T > arg1Class ) {
75
51
try {
@@ -91,75 +67,19 @@ public static SdkTracerProviderBuilder setTracerConfigurator(
91
67
return sdkTracerProviderBuilder ;
92
68
}
93
69
94
- // SdkTracerProvider.getTracerConfig(InstrumentationScopeInfo instrumentationScopeInfo)
95
- // here because it's not currently public
96
- private static TracerConfig getTracerConfig (
97
- SdkTracerProvider provider , InstrumentationScopeInfo instrumentationScopeInfo ) {
98
- return (TracerConfig )
99
- call ("getTracerConfig" , provider , instrumentationScopeInfo , InstrumentationScopeInfo .class );
100
- }
101
-
102
- // SdkTracer.getInstrumentationScopeInfo()
70
+ // SdkTracerProvider.setTracerConfigurator(ScopeConfigurator tracerConfigurator)
103
71
// here because it's not currently public
104
- private static InstrumentationScopeInfo getInstrumentationScopeInfo (Tracer sdkTracer )
105
- throws NoSuchFieldException , IllegalAccessException {
106
- return (InstrumentationScopeInfo ) call ("getInstrumentationScopeInfo" , sdkTracer );
107
- }
108
-
109
- // Not an existing method
110
- // SdkTracerProvider.updateTracerConfigurations()
111
- // updates all tracers with the current SdkTracerProvider.tracerConfigurator
112
- // Code implementation equivalent to
113
- // this.tracerSdkComponentRegistry
114
- // .getComponents()
115
- // .forEach(
116
- // sdkTracer ->
117
- // sdkTracer.updateTracerConfig(
118
- // getTracerConfig(sdkTracer.getInstrumentationScopeInfo())));
119
- // where SdkTracer.updateTracerConfig(TracerConfig tracerConfig) is equivalent to
120
- // this.tracerEnabled = tracerConfig.isEnabled();
121
- static void updateTracerConfigurations (TracerProvider provider ) {
72
+ public static TracerConfig setProviderTracerConfigurator (
73
+ TracerProvider provider , ScopeConfigurator <TracerConfig > tracerConfigurator ) {
122
74
if (!(provider instanceof SdkTracerProvider )) {
123
75
provider = (TracerProvider ) getField ("delegate" , provider );
124
76
}
125
- ComponentRegistry <Tracer > tracerSdkComponentRegistry =
126
- (ComponentRegistry <Tracer >) getField ("tracerSdkComponentRegistry" , provider );
127
- SdkTracerProvider finalProvider = (SdkTracerProvider ) provider ;
128
- final List <String > activatedTracers ;
129
- if (logger .isLoggable (Level .CONFIG )) {
130
- activatedTracers = new ArrayList <>();
77
+ if (provider instanceof SdkTracerProvider ) {
78
+ return (TracerConfig )
79
+ call ("setTracerConfigurator" , provider , tracerConfigurator , ScopeConfigurator .class );
131
80
} else {
132
- activatedTracers = null ;
133
- }
134
- tracerSdkComponentRegistry
135
- .getComponents ()
136
- .forEach (
137
- sdkTracer -> {
138
- try {
139
- InstrumentationScopeInfo instrumentationScopeInfo =
140
- getInstrumentationScopeInfo (sdkTracer );
141
- TracerConfig tConfig = getTracerConfig (finalProvider , instrumentationScopeInfo );
142
- Field tracerEnabledField = sdkTracer .getClass ().getDeclaredField ("tracerEnabled" );
143
- tracerEnabledField .setAccessible (true );
144
- // Update is synced but the reader is NOT necessarily so this is eventual
145
- // consistency, takes effect when the application passes a sync boundary
146
- synchronized (sdkTracer ) {
147
- tracerEnabledField .set (sdkTracer , tConfig .isEnabled ());
148
- }
149
- if (logger .isLoggable (Level .CONFIG )) {
150
- String name = instrumentationScopeInfo .getName ();
151
- if (name .startsWith (INSTRUMENTATION_NAME_PREPEND )) {
152
- name = name .substring (INSTRUMENTATION_NAME_PREPEND .length ());
153
- }
154
- activatedTracers .add (name );
155
- activatedTracers .add (tConfig .isEnabled () ? "enabled" : "disabled" );
156
- }
157
- } catch (NoSuchFieldException | IllegalAccessException e ) {
158
- throw new RuntimeException (e );
159
- }
160
- });
161
- if (logger .isLoggable (Level .CONFIG )) {
162
- logger .log (Level .CONFIG , "Activated Tracers: " + activatedTracers );
81
+ throw new IllegalStateException (
82
+ "Expected SdkTracerProvider but got " + provider .getClass ().getName ());
163
83
}
164
84
}
165
85
0 commit comments