diff --git a/buildSrc/src/main/groovy/VersionScanPlugin.groovy b/buildSrc/src/main/groovy/VersionScanPlugin.groovy index f2ddb703b9..abb2051f8d 100644 --- a/buildSrc/src/main/groovy/VersionScanPlugin.groovy +++ b/buildSrc/src/main/groovy/VersionScanPlugin.groovy @@ -38,9 +38,10 @@ class VersionScanPlugin implements Plugin { description = "Queries for all versions of configured modules and finds key classes" } - if (!project.gradle.startParameter.taskNames.each { it.endsWith('scanVersions') }.any()) { + if (!project.gradle.startParameter.taskNames.contains('scanVersions')) { return } + println "Adding scan tasks for $project" Set allInclude = Sets.newConcurrentHashSet() Set allExclude = Sets.newConcurrentHashSet() diff --git a/dd-java-agent/dd-java-agent.gradle b/dd-java-agent/dd-java-agent.gradle index d4ba3450ab..24e64f05ff 100644 --- a/dd-java-agent/dd-java-agent.gradle +++ b/dd-java-agent/dd-java-agent.gradle @@ -17,6 +17,8 @@ whitelistedInstructionClasses += whitelistedBranchClasses += [ 'com.datadoghq.trace.agent.InstrumentationChecker', 'com.datadoghq.trace.agent.DDJavaAgentInfo', 'io.opentracing.contrib.mongo.TracingCommandListenerFactory', + 'com.datadoghq.trace.agent.InstrumentationChecker.1', + 'com.datadoghq.trace.agent.InstrumentationChecker.ArtifactSupport', ] dependencies { diff --git a/dd-java-agent/src/main/java/com/datadoghq/trace/agent/InstrumentationChecker.java b/dd-java-agent/src/main/java/com/datadoghq/trace/agent/InstrumentationChecker.java index 1625510efe..b0fa8b2971 100644 --- a/dd-java-agent/src/main/java/com/datadoghq/trace/agent/InstrumentationChecker.java +++ b/dd-java-agent/src/main/java/com/datadoghq/trace/agent/InstrumentationChecker.java @@ -42,7 +42,7 @@ public class InstrumentationChecker { this.classLoader = classLoader; rules = FactoryUtils.loadConfigFromResource( - CONFIG_FILE, new TypeReference>>>() {}); + CONFIG_FILE, new TypeReference>>() {}); frameworks = scanLoadedLibraries(); } diff --git a/dd-java-agent/src/main/resources/dd-trace-supported-framework.yaml b/dd-java-agent/src/main/resources/dd-trace-supported-framework.yaml index ddd7294a15..a21b1679fe 100644 --- a/dd-java-agent/src/main/resources/dd-trace-supported-framework.yaml +++ b/dd-java-agent/src/main/resources/dd-trace-supported-framework.yaml @@ -11,9 +11,9 @@ opentracing-apache-httpclient: - artifact: httpclient supported_version: 4\.[3|4|5]\..* identifying_present_classes: - - org.apache.http.conn.SchemePortResolver - - org.apache.http.config.Lookup - - org.apache.http.conn.ssl.SSLContexts + - org.apache.http.conn.SchemePortResolver + - org.apache.http.config.Lookup + - org.apache.http.conn.ssl.SSLContexts - artifact: commons-httpclient supported_version: none @@ -22,52 +22,52 @@ opentracing-aws-sdk: - artifact: aws-java-sdk supported_version: 1\.11\..* identifying_present_classes: - - com.amazonaws.http.client.HttpClientFactory - - com.amazonaws.http.apache.utils.ApacheUtils - - com.amazonaws.http.request.HttpRequestFactory + - com.amazonaws.http.client.HttpClientFactory + - com.amazonaws.http.apache.utils.ApacheUtils + - com.amazonaws.http.request.HttpRequestFactory opentracing-cassandra-driver: - artifact: cassandra-driver-core supported_version: 3\.2.* identifying_present_classes: - - com.datastax.driver.core.utils.MoreObjects - - com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions - - com.datastax.driver.core.GuavaCompatibility + - com.datastax.driver.core.utils.MoreObjects + - com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions + - com.datastax.driver.core.GuavaCompatibility opentracing-web-servlet-filter: - artifact: jetty-server supported_version: (8\.|9\.).* - identifying_present_classes: +# identifying_present_classes: - artifact: tomcat_catalina supported_version: (8\.|9\.).* identifying_present_classes: - - org.apache.catalina.WebResource - - org.apache.catalina.webresources.TrackedInputStream - - org.apache.catalina.webresources.AbstractArchiveResource + - org.apache.catalina.WebResource + - org.apache.catalina.webresources.TrackedInputStream + - org.apache.catalina.webresources.AbstractArchiveResource - artifact: tomcat-embed-core supported_version: (8\.|9\.).* identifying_present_classes: - - org.apache.catalina.WebResource - - org.apache.catalina.webresources.TrackedInputStream - - org.apache.catalina.webresources.AbstractArchiveResource + - org.apache.catalina.WebResource + - org.apache.catalina.webresources.TrackedInputStream + - org.apache.catalina.webresources.AbstractArchiveResource opentracing-okhttp3: - artifact: okhttp supported_version: 3\..* identifying_present_classes: - - okhttp3.Cookie - - okhttp3.ConnectionPool - - okhttp3.Headers + - okhttp3.Cookie + - okhttp3.ConnectionPool + - okhttp3.Headers # For rules opentracing-jms-2_{consumer,producer} opentracing-jms-2: - artifact: javax.jms-api supported_version: 2\..* - identifying_present_classes - - javax.jms.JMSContext - - javax.jms.CompletionListener + identifying_present_classes: + - javax.jms.JMSContext + - javax.jms.CompletionListener opentracing-mongo-driver: - artifact: mongo-java-driver diff --git a/dd-java-agent/src/test/groovy/com/datadoghq/trace/agent/InstrumentationCheckerTest.groovy b/dd-java-agent/src/test/groovy/com/datadoghq/trace/agent/InstrumentationCheckerTest.groovy index ab50eed213..8ba490aeb7 100644 --- a/dd-java-agent/src/test/groovy/com/datadoghq/trace/agent/InstrumentationCheckerTest.groovy +++ b/dd-java-agent/src/test/groovy/com/datadoghq/trace/agent/InstrumentationCheckerTest.groovy @@ -7,7 +7,7 @@ import spock.lang.Specification class InstrumentationCheckerTest extends Specification { Map>> rules = FactoryUtils.loadConfigFromResource("supported-version-test", new TypeReference>>() { - }); + }) Map frameworks = [ "artifact-1": "1.2.3.1232", "artifact-2": "4.y.z", @@ -18,7 +18,7 @@ class InstrumentationCheckerTest extends Specification { def "test rules"() { setup: - def rules = InstrumentationChecker.getUnsupportedRules(java.lang.ClassLoader.getSystemClassLoader()); + def rules = InstrumentationChecker.getUnsupportedRules(java.lang.ClassLoader.getSystemClassLoader()) expect: rules.size() == 3 diff --git a/dd-trace/dd-trace.gradle b/dd-trace/dd-trace.gradle index 2ac83084f4..24aeb5ac3f 100644 --- a/dd-trace/dd-trace.gradle +++ b/dd-trace/dd-trace.gradle @@ -15,6 +15,7 @@ whitelistedInstructionClasses += whitelistedBranchClasses += [ 'com.datadoghq.trace.DDTags', 'com.datadoghq.trace.DDTraceInfo', 'com.datadoghq.trace.util.Clock', + 'com.datadoghq.trace.resolver.FactoryUtils', ] dependencies { diff --git a/dd-trace/src/main/java/com/datadoghq/trace/resolver/FactoryUtils.java b/dd-trace/src/main/java/com/datadoghq/trace/resolver/FactoryUtils.java index 85e8fed89a..5580994960 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/resolver/FactoryUtils.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/resolver/FactoryUtils.java @@ -15,8 +15,18 @@ public class FactoryUtils { public static A loadConfigFromFilePropertyOrResource( final String systemProperty, final String resourceName, final Class targetClass) { - return loadConfigFromFilePropertyOrResource( - systemProperty, resourceName, new TypeReference() {}); + final String filePath = System.getProperty(systemProperty); + if (filePath != null) { + try { + log.info("Loading config from file " + filePath); + return objectMapper.readValue(new File(filePath), targetClass); + } catch (final Exception e) { + log.error( + "Cannot read provided configuration file " + filePath + ". Using the default one.", e); + } + } + + return loadConfigFromResource(resourceName, targetClass); } public static A loadConfigFromFilePropertyOrResource( @@ -37,7 +47,31 @@ public class FactoryUtils { public static A loadConfigFromResource( final String resourceName, final Class targetClass) { - return loadConfigFromResource(resourceName, new TypeReference() {}); + A config = null; + + // Try loading both suffixes + if (!resourceName.endsWith(".yaml") && !resourceName.endsWith(".yml")) { + config = loadConfigFromResource(resourceName + ".yaml", targetClass); + if (config == null) { + config = loadConfigFromResource(resourceName + ".yml", targetClass); + } + if (config != null) { + return config; + } + } + + try { + final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + final URL resource = classLoader.getResource(resourceName); + if (resource != null) { + log.info("Loading config from resource " + resource); + config = objectMapper.readValue(resource.openStream(), targetClass); + } + } catch (final IOException e) { + log.warn("Could not load configuration file {}.", resourceName); + log.error("Error when loading config file", e); + } + return config; } public static A loadConfigFromResource(final String resourceName, final TypeReference type) {