Enhance logging and cleanup.
MODIFY
dd-java-agent-ittests/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java
dd-java-agent-ittests/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java
@@ -15,10 +15,6 @@ import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
-/**
- * Duplication of TestUtils in testing project. Cannot directly depend on testing project due to
- * classpath issues.
- */
public class IntegrationTestUtils {
public static <T extends Object> Object runUnderTrace(

MODIFY
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/DatadogClassLoader.java
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/DatadogClassLoader.java
@@ -14,10 +14,10 @@ public class DatadogClassLoader extends URLClassLoader {
/**
* Construct a new DatadogClassLoader
*
- * <p>{@param bootstrapJarLocation} Location of the bootstrap jar. Will be used for resource
- * lookups. {@param agentJarLocation} Location of the agent tooling and instrumentation jar. Will
- * be the classpath of this classloader. {@param parent} Parent of this classloader. Should null
- * (bootstrap), or the platform classloader for java 9+.
+ * @param bootstrapJarLocation Used for resource lookups.
+ * @param agentJarLocation Classpath of this classloader.
+ * @param parent Classloader parent. Should null (bootstrap), or the platform classloader for java
+ * 9+.
*/
public DatadogClassLoader(URL bootstrapJarLocation, URL agentJarLocation, ClassLoader parent) {
super(new URL[] {agentJarLocation}, parent);

ADD
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/ExceptionLogger.java
+package datadog.trace.agent.bootstrap;
+
+/**
+ * Class used for exception handler logging.
+ *
+ * <p>See datadog.trace.agent.tooling.ExceptionHandlers
+ */
+public class ExceptionLogger {}

MODIFY
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/JDBCMaps.java
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/JDBCMaps.java
@@ -7,6 +7,11 @@ import java.util.Map;
import java.util.WeakHashMap;
import lombok.Data;
+/**
+ * JDBC instrumentation shares a global map of connection info.
+ *
+ * <p>In the bootstrap project to ensure visibility by all classes.
+ */
public class JDBCMaps {
public static final Map<Connection, DBInfo> connectionInfo =
Collections.synchronizedMap(new WeakHashMap<Connection, DBInfo>());

RENAME
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/PatchLogger.java
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/agent/bootstrap/PatchLogger.java
-package datadog.trace.agent;
+package datadog.trace.agent.bootstrap;
import java.util.ResourceBundle;
import java.util.logging.Level;
@@ -11,7 +11,6 @@ import java.util.logging.LogRecord;
* <p>Shadow rewrites will redirect those calls to this class, which will return a safe logger.
*/
public class PatchLogger {
- // FIXME: Use "datadog.trace.agent.bootstrap" package name for clarity
private static final PatchLogger SAFE_LOGGER = new PatchLogger("datadogSafeLogger", "bundle");
public static PatchLogger getLogger(String name) {

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java
@@ -88,7 +88,7 @@ public class AgentInstaller {
final JavaModule module,
final boolean loaded,
final Throwable throwable) {
- log.debug("Failed to handle " + typeName + " for transformation", throwable);
+ log.debug("Failed to handle {} for transformation: {}", typeName, throwable.getMessage());
}
@Override

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ExceptionHandlers.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ExceptionHandlers.java
package datadog.trace.agent.tooling;
+import datadog.trace.agent.bootstrap.ExceptionLogger;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.StackSize;
@@ -13,8 +14,8 @@ import org.slf4j.LoggerFactory;
public class ExceptionHandlers {
private static final String LOG_FACTORY_NAME = LoggerFactory.class.getName().replace('.', '/');
private static final String LOGGER_NAME = Logger.class.getName().replace('.', '/');
- // Object.class will always be resolvable, so we'll use it in the log name
- private static final String HANDLER_NAME = Object.class.getName().replace('.', '/');
+ // Bootstrap ExceptionHandler.class will always be resolvable, so we'll use it in the log name
+ private static final String HANDLER_NAME = ExceptionLogger.class.getName().replace('.', '/');
private static final StackManipulation EXCEPTION_STACK_HANDLER =
new StackManipulation() {
@@ -29,7 +30,7 @@ public class ExceptionHandlers {
public Size apply(MethodVisitor mv, Implementation.Context context) {
// writes the following bytecode:
// try {
- // org.slf4j.LoggerFactory.getLogger((Class)Object.class).debug("exception in instrumentation", t);
+ // org.slf4j.LoggerFactory.getLogger((Class)ExceptionLogger.class).debug("exception in instrumentation", t);
// } catch (Throwable t2) {
// }
Label logStart = new Label();

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/HelperInjector.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/HelperInjector.java
@@ -88,8 +88,10 @@ public class HelperInjector implements Transformer {
log.error(
"Error preparing helpers for "
+ typeDescription
- + ". Failed to inject helper classes into "
- + classLoader,
+ + ". Failed to inject helper classes into instance "
+ + classLoader
+ + " of type "
+ + classLoader.getClass().getName(),
e);
throw new RuntimeException(e);
}

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/TracerInstaller.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/TracerInstaller.java
@@ -29,5 +29,8 @@ public class TracerInstaller {
DDTraceOTInfo.VERSION.toString();
DDTraceApiInfo.VERSION.toString();
DDJavaAgentInfo.VERSION.toString();
+ log.debug(GlobalTracer.class.getName() + " loaded on " + GlobalTracer.class.getClassLoader());
+ log.debug(
+ AgentInstaller.class.getName() + " loaded on " + AgentInstaller.class.getClassLoader());
}
}

MODIFY
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy
package datadog.trace.agent.test
+import datadog.trace.agent.bootstrap.ExceptionLogger
import datadog.trace.agent.tooling.ExceptionHandlers
import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.dynamic.ClassFileLocator
@@ -37,8 +38,7 @@ class ExceptionHandlerTest extends Specification {
ByteBuddyAgent.install()
builder.installOn(ByteBuddyAgent.getInstrumentation())
- // ExceptionHandlers uses java.lang.Object for logging
- final Logger logger = (Logger) LoggerFactory.getLogger(java.lang.Object)
+ final Logger logger = (Logger) LoggerFactory.getLogger(ExceptionLogger)
testAppender.setContext(logger.getLoggerContext())
logger.addAppender(testAppender)
testAppender.start()

MODIFY
dd-java-agent/dd-java-agent.gradle
dd-java-agent/dd-java-agent.gradle
@@ -42,7 +42,10 @@ def includeShadowJar(subproject, jarname) {
exclude(dependency('org.projectlombok:lombok:1.16.20'))
}
- relocate 'org.slf4j', 'datadog.slf4j' // Prevents conflict with other SLF4J instances. Important for premain.
+ // Prevents conflict with other SLF4J instances. Important for premain.
+ relocate 'org.slf4j', 'datadog.slf4j'
+ // rewrite dependencies calling Logger.getLogger
+ relocate 'java.util.logging.Logger', 'datadog.trace.agent.bootstrap.PatchLogger'
if (!project.hasProperty("disableShadowRelocate") || !disableShadowRelocate) {
@@ -65,9 +68,6 @@ def includeShadowJar(subproject, jarname) {
// This is used in the Cassandra Cluster.connectAsync signature so we can't relocate it. :fingers_crossed:
exclude 'com.google.common.util.concurrent.ListenableFuture'
}
-
- // rewrite dependencies calling Logger.getLogger
- relocate 'java.util.logging.Logger', 'datadog.trace.agent.PatchLogger'
}
}
}

MODIFY
dd-java-agent/src/main/java/datadog/trace/agent/TracingAgent.java
dd-java-agent/src/main/java/datadog/trace/agent/TracingAgent.java
@@ -19,6 +19,7 @@ package datadog.trace.agent;
import java.io.*;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.jar.JarFile;
@@ -71,9 +72,6 @@ public class TracingAgent {
final Method tracerInstallerMethod =
tracerInstallerClass.getMethod("installGlobalTracer");
tracerInstallerMethod.invoke(null);
- // TODO
- // - assert global tracer class is on bootstrap
- // - assert global tracer impl class is on agent classloader
final Method logVersionInfoMethod = tracerInstallerClass.getMethod("logVersionInfo");
logVersionInfoMethod.invoke(null);
}
@@ -101,7 +99,7 @@ public class TracingAgent {
agentParent = null; // bootstrap
} else {
// platform classloader is parent of system in java 9+
- agentParent = ClassLoader.getSystemClassLoader().getParent();
+ agentParent = getPlatformClassLoader();
}
Class<?> loaderClass =
ClassLoader.getSystemClassLoader()
@@ -113,10 +111,7 @@ public class TracingAgent {
bootstrapJar.toURI().toURL(), toolingJar.toURI().toURL(), agentParent);
}
- /**
- * Extract {@param loader}'s resource, {@param sourcePath}, to a temporary file named {@param
- * destName}.
- */
+ /** Extract sourcePath out of loader to a temporary file named destName. */
private static File extractToTmpFile(ClassLoader loader, String sourcePath, String destName)
throws Exception {
final String destPrefix;
@@ -159,6 +154,13 @@ public class TracingAgent {
}
}
+ private static ClassLoader getPlatformClassLoader()
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ // must invoke ClassLoader.getPlatformClassLoader by reflection to remain compatible with java 7 + 8.
+ final Method method = ClassLoader.class.getDeclaredMethod("getPlatformClassLoader");
+ return (ClassLoader) method.invoke(null);
+ }
+
public static void main(final String... args) {
try {
System.out.println(getAgentVersion());

Enhance logging and cleanup.