33import static datadog .trace .agent .tooling .Utils .getConfigEnabled ;
44import static net .bytebuddy .matcher .ElementMatchers .any ;
55
6+ import datadog .trace .agent .tooling .muzzle .Reference ;
7+ import datadog .trace .agent .tooling .muzzle .ReferenceMatcher ;
8+ import java .security .ProtectionDomain ;
69import java .util .Arrays ;
710import java .util .HashSet ;
11+ import java .util .List ;
812import java .util .Map ;
913import java .util .Set ;
1014import lombok .extern .slf4j .Slf4j ;
1115import net .bytebuddy .agent .builder .AgentBuilder ;
1216import net .bytebuddy .description .type .TypeDescription ;
1317import net .bytebuddy .matcher .ElementMatcher ;
18+ import net .bytebuddy .utility .JavaModule ;
1419
1520/**
1621 * Built-in bytebuddy-based instrumentation for the datadog javaagent.
@@ -42,11 +47,13 @@ public interface Instrumenter {
4247 @ Slf4j
4348 abstract class Default implements Instrumenter {
4449 private final Set <String > instrumentationNames ;
50+ private final String instrumentationPrimaryName ;
4551 protected final boolean enabled ;
4652
4753 public Default (final String instrumentationName , final String ... additionalNames ) {
4854 this .instrumentationNames = new HashSet <>(Arrays .asList (additionalNames ));
4955 instrumentationNames .add (instrumentationName );
56+ instrumentationPrimaryName = instrumentationName ;
5057
5158 // If default is enabled, we want to enable individually,
5259 // if default is disabled, we want to disable individually.
@@ -74,6 +81,35 @@ public AgentBuilder instrument(final AgentBuilder agentBuilder) {
7481 AgentBuilder .Identified .Extendable advice =
7582 agentBuilder
7683 .type (typeMatcher (), classLoaderMatcher ())
84+ .and (
85+ new AgentBuilder .RawMatcher () {
86+ @ Override
87+ public boolean matches (
88+ TypeDescription typeDescription ,
89+ ClassLoader classLoader ,
90+ JavaModule module ,
91+ Class <?> classBeingRedefined ,
92+ ProtectionDomain protectionDomain ) {
93+ // Optimization: calling getInstrumentationMuzzle() inside this method prevents unnecessary loading of muzzle references during agentBuilder setup.
94+ final ReferenceMatcher muzzle = getInstrumentationMuzzle ();
95+ if (null != muzzle ) {
96+ List <Reference .Mismatch > mismatches =
97+ muzzle .getMismatchedReferenceSources (classLoader );
98+ if (mismatches .size () > 0 ) {
99+ log .debug (
100+ "Instrumentation muzzled: {} -- {} on {}" ,
101+ instrumentationPrimaryName ,
102+ this .getClass ().getName (),
103+ classLoader );
104+ }
105+ for (Reference .Mismatch mismatch : mismatches ) {
106+ log .debug ("-- {}" , mismatch );
107+ }
108+ return mismatches .size () == 0 ;
109+ }
110+ return true ;
111+ }
112+ })
77113 .transform (DDTransformers .defaultTransformers ());
78114 final String [] helperClassNames = helperClassNames ();
79115 if (helperClassNames .length > 0 ) {
@@ -85,6 +121,15 @@ public AgentBuilder instrument(final AgentBuilder agentBuilder) {
85121 return advice .asDecorator ();
86122 }
87123
124+ /**
125+ * This method is implemented dynamically by compile-time bytecode transformations.
126+ *
127+ * <p>{@see datadog.trace.agent.tooling.muzzle.MuzzleGradlePlugin}
128+ */
129+ protected ReferenceMatcher getInstrumentationMuzzle () {
130+ return null ;
131+ }
132+
88133 @ Override
89134 public String [] helperClassNames () {
90135 return new String [0 ];
@@ -105,11 +150,13 @@ protected boolean defaultEnabled() {
105150 return getConfigEnabled ("dd.integrations.enabled" , true );
106151 }
107152
108- protected static String getPropOrEnv (final String name ) {
153+ // TODO: move common config helpers to Utils
154+
155+ public static String getPropOrEnv (final String name ) {
109156 return System .getProperty (name , System .getenv (propToEnvName (name )));
110157 }
111158
112- private static String propToEnvName (final String name ) {
159+ public static String propToEnvName (final String name ) {
113160 return name .toUpperCase ().replace ("." , "_" );
114161 }
115162 }
0 commit comments