Comments explaining jmxfetch delay
@@ -46,8 +46,15 @@ public class TracingAgent {
throws Exception {
startDatadogAgent(agentArgs, inst);
if (isAppUsingCustomLogManager()) {
- // Application is setting a custom log mananger. JMXFetch touches the global log manager and
- // must not be started until the app has initialized the global log manager.
+ /*
+ * java.util.logging.LogManager maintains a final static LogManager, which is created during class initialization.
+ *
+ * JMXFetch uses jre bootstrap classes which touch this class. This means applications which require a custom log manager may not have a chance to set the global log manager if jmxfetch runs first. JMXFetch will incorrectly set the global log manager in cases where the app sets the log manager system property or when the log manager class is not on the system classpath.
+ *
+ * Our solution is to delay the initilization of jmxfetch when we detect a custom log manager being used.
+ *
+ * Once we see the LogManager class loading, it's safe to start jmxfetch because the application is already setting the global log manager and jmxfetch won't be able to touch it due to classloader locking.
+ */
final Class<?> agentInstallerClass =
AGENT_CLASSLOADER.loadClass("datadog.trace.agent.tooling.AgentInstaller");
final Method registerCallbackMethod =
@@ -228,6 +235,12 @@ public class TracingAgent {
return (ClassLoader) method.invoke(null);
}
+ /**
+ * Search for java or datadog-tracer sysprops which indicate that a custom log manager will be
+ * used. Also search for any app classes known to set a custom log manager.
+ *
+ * @return true if we detect a custom log manager being used.
+ */
private static boolean isAppUsingCustomLogManager() {
final String tracerCustomLogManSysprop = "dd.app.customlogmanager";
return System.getProperty("java.util.logging.manager") != null
