1
1
package org .digma ;
2
2
3
- import net .bytebuddy .ByteBuddy ;
4
3
import org .digma .configuration .Configuration ;
5
4
import org .digma .instrumentation .digma .agent .BuildVersion ;
5
+ import org .digma .jdbc .JDBCTrackingTransformer ;
6
6
7
7
import java .lang .instrument .Instrumentation ;
8
8
import java .lang .reflect .Field ;
9
9
10
10
import static org .digma .configuration .Configuration .JAVA_VERSION ;
11
11
import static org .digma .configuration .Configuration .OS_NAME ;
12
- import static org .digma .OtelClassNames .WITH_SPAN_CLASS_NAME ;
13
12
14
13
public class DigmaAgent {
15
14
@@ -34,59 +33,48 @@ private static void startAgent(Instrumentation inst, boolean fromPremain) {
34
33
35
34
Configuration configuration = Configuration .getInstance ();
36
35
37
-
38
- if (configuration .getIncludePackages ().isEmpty ()) {
39
- Log .debug ("No configured packages for instrumentation in Digma agent, doing nothing." );
40
- return ;
41
- }
42
-
43
- installInstrumentationOnBytebuddyAgent (inst );
44
-
45
-
46
36
//this must be the first thing the agent does, other classes rely on non-null
47
37
InstrumentationHolder .instrumentation = inst ;
48
38
39
+ boolean agentActivated = false ;
49
40
50
- //todo: this is temporary until a more clever injection is implemented.
51
- // when trying to inject otel api lazy just before transforming, it works but otel doesn't
52
- // instrument the methods. its because otel agent has a class loader optimization, if it tried once to check
53
- // if class loader has WIthSpan and it was false it will not instrument classes from this class loader anymore.
54
- // if otel transformer was executed before our transformer encountered a relevant type then it will be too late
55
- // to inject.
56
- // one solution may be to add a transformer that does nothing but registers class loaders and checks if they have
57
- // a relevant package for us and if yes inject otel api if necessary.
58
-
59
- //even if injection fails the agent will still install the transformer,
60
- // maybe WithSpan is available in higher class loaders, worst thing transformation will fail
61
- // and user should see the logs.
62
- makeSureWithSpanClassIsAvailable ();
63
-
41
+ if (configuration .isExposePreparedStatementsParametersEnabled ()) {
42
+ System .setProperty ("otel.instrumentation.jdbc.statement-sanitizer.enabled" ,"false" );
43
+ JDBCTrackingTransformer .install (inst );
44
+ agentActivated = true ;
45
+ } else {
46
+ Log .debug ("otel statement sanitizer is enabled , not installing jdbc tracking transformer." );
47
+ }
64
48
65
- Log .debug ("Digma agent started with configuration: includePackages="
66
- + configuration .getIncludePackages ()
67
- + ",excludeNames=" + configuration .getExcludeNames ());
68
49
50
+ if (configuration .isExtendedObservabilityEnabled ()) {
51
+ WithSpanTransformer .install (inst );
52
+ agentActivated = true ;
53
+ } else {
54
+ Log .debug ("Extended observability is not configured, not installing WithSpan transformer." );
55
+ }
69
56
70
- //if we fail to load bytebuddy nothing will work
71
- Class <ByteBuddy > byteBuddyClass = ByteBuddy .class ;
72
- Log .debug ("byteBuddy Class " + byteBuddyClass .getName () + ", class loader: " + byteBuddyClass .getClassLoader ());
73
57
74
- WithSpanTransformer .install (inst );
58
+ if (agentActivated ) {
59
+ installInstrumentationOnBytebuddyAgent (inst );
60
+ }
75
61
76
62
} catch (Throwable ex ) {
77
- // Don't rethrow.
63
+ // Don't rethrow so users don't get an exception in their application .
78
64
Log .error ("got exception while starting Digma agent" , ex );
79
65
}
80
66
}
81
67
82
68
69
+
70
+
83
71
//see : https://github.com/raphw/byte-buddy/discussions/1658
84
72
private static void installInstrumentationOnBytebuddyAgent (Instrumentation myInstrumentation ) {
85
73
86
74
if (!OS_NAME .toLowerCase ().startsWith ("mac" )) {
87
75
return ;
88
76
}
89
- if (!JAVA_VERSION .startsWith ("17" )){
77
+ if (!JAVA_VERSION .startsWith ("17" )) {
90
78
return ;
91
79
}
92
80
@@ -95,67 +83,23 @@ private static void installInstrumentationOnBytebuddyAgent(Instrumentation myIns
95
83
//need to change the Installer fq name otherwise gradle shadow will relocate it
96
84
Class <?> byteBuddyInstaller = Class .forName ("net_bytebuddy_agent_Installer" .replaceAll ("_" , "." ), false , ClassLoader .getSystemClassLoader ());
97
85
Field instrumentationField = byteBuddyInstaller .getDeclaredField ("instrumentation" );
86
+ boolean isAccessible = instrumentationField .isAccessible ();
98
87
instrumentationField .setAccessible (true );
99
88
100
89
Instrumentation instrumentation = (Instrumentation ) instrumentationField .get (null );
101
90
if (instrumentation == null ) {
102
91
instrumentationField .set (null , myInstrumentation );
103
92
}
104
- instrumentationField .setAccessible (false );
93
+ instrumentationField .setAccessible (isAccessible );
105
94
Log .debug ("Installation of Instrumentation on ByteBuddy Installer succeeded" );
106
95
} catch (Exception e ) {
107
96
Log .debug ("Could not install instrumentation on bytebuddy Installer " + e );
108
97
}
109
98
}
110
99
111
100
112
- private static void makeSureWithSpanClassIsAvailable () {
113
101
114
- //if configuration is true inject and return
115
- if (Configuration .getInstance ().shouldInjectOtelApiToSystemClassLoader ()) {
116
- Log .debug ("configuration for injecting otel api to system class loader is true, injecting otel api to system class loader." );
117
- injectOtelApiToSystemClassLoader ();
118
- return ;
119
- }
120
102
121
103
122
- //if configuration exists and is false quit and don't inject
123
- if (Configuration .getInstance ().shouldInjectOtelApiToSystemClassLoaderExist () &&
124
- !Configuration .getInstance ().shouldInjectOtelApiToSystemClassLoader ()) {
125
- Log .debug ("configuration for injecting otel api to system class loader is false, not injecting." );
126
- return ;
127
- }
128
-
129
- //else try to inject if WithSpan is not in system classpath
130
- try {
131
- Log .debug ("checking if WithSpan class is available in classpath" );
132
- Class .forName (WITH_SPAN_CLASS_NAME );
133
- Log .debug ("WithSpan class is available in classpath" );
134
-
135
- } catch (ClassNotFoundException e ) {
136
- Log .debug ("WithSpan class is NOT available in classpath, trying to inject otel api" );
137
- injectOtelApiToSystemClassLoader ();
138
- }
139
- }
140
-
141
- private static void injectOtelApiToSystemClassLoader () {
142
- if (Configuration .getInstance ().shouldInjectOtelApiToSystemClassLoaderExist () &&
143
- !Configuration .getInstance ().shouldInjectOtelApiToSystemClassLoader ()) {
144
- Log .debug ("injectOtelApiToSystemClassLoader was called but configuration is false, not injecting" );
145
- return ;
146
- }
147
-
148
- Log .debug ("injecting otel api to system class loader." );
149
- try {
150
- OtelApiInjector .injectOtelApiJarToSystemClassLoader ();
151
- } catch (UnsupportedOperationException e ) {
152
- Log .error ("got exception trying to inject otel api to system class loader. maybe this jvm doesn't support injecting a jar to " +
153
- "system class loader. please add otel api top the classpath in a different way" , e );
154
- } catch (Throwable e ) {
155
- Log .error ("got exception trying to inject otel api to system class loader. " +
156
- "please fix the issue and try again , or add otel api to the classpath in a different way" , e );
157
- }
158
-
159
- }
160
104
161
105
}
0 commit comments