Skip to content

Commit dffe2ac

Browse files
committed
WIP
1 parent 56d4919 commit dffe2ac

File tree

2 files changed

+41
-22
lines changed

2 files changed

+41
-22
lines changed

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/Agent.java

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package datadog.trace.bootstrap;
22

33
import static datadog.trace.api.ConfigDefaults.DEFAULT_STARTUP_LOGS_ENABLED;
4-
import static datadog.trace.api.Platform.getRuntimeVendor;
54
import static datadog.trace.api.Platform.isJavaVersionAtLeast;
65
import static datadog.trace.api.Platform.isOracleJDK8;
76
import static datadog.trace.bootstrap.Library.WILDFLY;
@@ -329,7 +328,7 @@ public void run() {
329328
if (appUsingCustomJMXBuilder) {
330329
log.debug("Custom JMX builder detected. Delaying JMXFetch initialization.");
331330
registerMBeanServerBuilderCallback(new StartJmxCallback(jmxStartDelay));
332-
// one minute fail-safe in case nothing touches JMX and and callback isn't triggered
331+
// one minute fail-safe in case nothing touches JMX and callback isn't triggered
333332
scheduleJmxStart(60 + jmxStartDelay);
334333
} else if (appUsingCustomLogManager) {
335334
log.debug("Custom logger detected. Delaying JMXFetch initialization.");
@@ -339,20 +338,31 @@ public void run() {
339338
}
340339
}
341340

342-
boolean delayOkHttp = appUsingCustomLogManager && okHttpMayIndirectlyLoadJUL();
343-
344341
/*
345342
* Similar thing happens with DatadogTracer on (at least) zulu-8 because it uses OkHttp which indirectly loads JFR
346343
* events which in turn loads LogManager. This is not a problem on newer JDKs because there JFR uses different
347344
* logging facility. Likewise on IBM JDKs OkHttp may indirectly load 'IBMSASL' which in turn loads LogManager.
348345
*/
346+
boolean delayOkHttp = !ciVisibilityEnabled && okHttpMayIndirectlyLoadJUL();
347+
boolean waitForJUL = appUsingCustomLogManager && delayOkHttp;
348+
int okHttpDelayMillis;
349+
if (waitForJUL) {
350+
okHttpDelayMillis = 1_000;
351+
} else if (delayOkHttp) {
352+
okHttpDelayMillis = 10;
353+
} else {
354+
okHttpDelayMillis = 0;
355+
}
356+
349357
InstallDatadogTracerCallback installDatadogTracerCallback =
350-
new InstallDatadogTracerCallback(initTelemetry, inst, delayOkHttp);
351-
if (delayOkHttp) {
358+
new InstallDatadogTracerCallback(initTelemetry, inst, okHttpDelayMillis);
359+
if (waitForJUL) {
352360
log.debug("Custom logger detected. Delaying Datadog Tracer initialization.");
353361
registerLogManagerCallback(installDatadogTracerCallback);
362+
} else if (okHttpDelayMillis > 0) {
363+
installDatadogTracerCallback.run(); // start on different thread (after premain)
354364
} else {
355-
installDatadogTracerCallback.execute();
365+
installDatadogTracerCallback.execute(); // start during premain
356366
}
357367

358368
/*
@@ -362,7 +372,7 @@ public void run() {
362372
if (profilingEnabled && !isOracleJDK8()) {
363373
StaticEventLogger.begin("Profiling");
364374

365-
if (delayOkHttp) {
375+
if (waitForJUL) {
366376
log.debug("Custom logger detected. Delaying Profiling initialization.");
367377
registerLogManagerCallback(new StartProfilingAgentCallback(inst));
368378
} else {
@@ -499,18 +509,18 @@ protected static class InstallDatadogTracerCallback extends ClassLoadCallBack {
499509
private final Instrumentation instrumentation;
500510
private final Object sco;
501511
private final Class<?> scoClass;
502-
private final boolean delayOkHttp;
512+
private final int okHttpDelayMillis;
503513

504514
public InstallDatadogTracerCallback(
505515
InitializationTelemetry initTelemetry,
506516
Instrumentation instrumentation,
507-
boolean delayOkHttp) {
508-
this.delayOkHttp = delayOkHttp;
517+
int okHttpDelayMillis) {
518+
this.okHttpDelayMillis = okHttpDelayMillis;
509519
this.instrumentation = instrumentation;
510520
try {
511521
scoClass =
512522
AGENT_CLASSLOADER.loadClass("datadog.communication.ddagent.SharedCommunicationObjects");
513-
sco = scoClass.getConstructor(boolean.class).newInstance(delayOkHttp);
523+
sco = scoClass.getConstructor(boolean.class).newInstance(okHttpDelayMillis > 0);
514524
} catch (ClassNotFoundException
515525
| NoSuchMethodException
516526
| InstantiationException
@@ -521,6 +531,7 @@ public InstallDatadogTracerCallback(
521531

522532
installDatadogTracer(initTelemetry, scoClass, sco);
523533
maybeInstallLogsIntake(scoClass, sco);
534+
maybeStartIast(instrumentation);
524535
}
525536

526537
@Override
@@ -530,12 +541,11 @@ public AgentThread agentThread() {
530541

531542
@Override
532543
public void execute() {
533-
if (delayOkHttp) {
544+
if (okHttpDelayMillis > 0) {
534545
resumeRemoteComponents();
535546
}
536547

537548
maybeStartAppSec(scoClass, sco);
538-
maybeStartIast(instrumentation, scoClass, sco);
539549
maybeStartCiVisibility(instrumentation, scoClass, sco);
540550
// start debugger before remote config to subscribe to it before starting to poll
541551
maybeStartDebugger(instrumentation, scoClass, sco);
@@ -550,7 +560,7 @@ private void resumeRemoteComponents() {
550560
try {
551561
// remote components were paused for custom log-manager/jmx-builder
552562
// add small delay before resuming remote I/O to help stabilization
553-
Thread.sleep(1_000);
563+
Thread.sleep(okHttpDelayMillis);
554564
scoClass.getMethod("resume").invoke(sco);
555565
} catch (InterruptedException ignore) {
556566
} catch (Throwable e) {
@@ -837,14 +847,14 @@ private static boolean isSupportedAppSecArch() {
837847
return true;
838848
}
839849

840-
private static void maybeStartIast(Instrumentation instrumentation, Class<?> scoClass, Object o) {
850+
private static void maybeStartIast(Instrumentation instrumentation) {
841851
if (iastEnabled || !iastFullyDisabled) {
842852

843853
StaticEventLogger.begin("IAST");
844854

845855
try {
846856
SubscriptionService ss = AgentTracer.get().getSubscriptionService(RequestContextSlot.IAST);
847-
startIast(instrumentation, ss, scoClass, o);
857+
startIast(instrumentation, ss);
848858
} catch (Exception e) {
849859
log.error("Error starting IAST subsystem", e);
850860
}
@@ -853,8 +863,7 @@ private static void maybeStartIast(Instrumentation instrumentation, Class<?> sco
853863
}
854864
}
855865

856-
private static void startIast(
857-
Instrumentation instrumentation, SubscriptionService ss, Class<?> scoClass, Object sco) {
866+
private static void startIast(Instrumentation instrumentation, SubscriptionService ss) {
858867
try {
859868
final Class<?> appSecSysClass = AGENT_CLASSLOADER.loadClass("com.datadog.iast.IastSystem");
860869
final Method iastInstallerMethod =
@@ -1339,15 +1348,25 @@ private static String ddGetEnv(final String sysProp) {
13391348
}
13401349

13411350
private static boolean okHttpMayIndirectlyLoadJUL() {
1342-
if ("IBM Corporation".equals(getRuntimeVendor())) {
1343-
return true; // IBM JDKs ship with 'IBMSASL' which will load JUL when OkHttp accesses TLS
1351+
if (isIBMSASLInstalled() || isACCPInstalled()) {
1352+
return true; // 'IBMSASL' and 'ACCP' crypto providers can load JUL when OkHttp accesses TLS
13441353
}
13451354
if (isJavaVersionAtLeast(9)) {
13461355
return false; // JDKs since 9 have reworked JFR to use a different logging facility, not JUL
13471356
}
13481357
return isJFRSupported(); // assume OkHttp will indirectly load JUL via its JFR events
13491358
}
13501359

1360+
private static boolean isIBMSASLInstalled() {
1361+
return ClassLoader.getSystemResource("com/ibm/security/sasl/IBMSASL.class") != null;
1362+
}
1363+
1364+
private static boolean isACCPInstalled() {
1365+
return ClassLoader.getSystemResource(
1366+
"com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.class")
1367+
!= null;
1368+
}
1369+
13511370
private static boolean isJFRSupported() {
13521371
// FIXME: this is quite a hack because there maybe jfr classes on classpath somehow that have
13531372
// nothing to do with JDK - but this should be safe because only thing this does is to delay

dd-java-agent/agent-iast/src/test/groovy/com/datadog/iast/IastSystemTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class IastSystemTest extends DDSpecification {
136136
InstrumentationBridge.clearIastModules()
137137

138138
when:
139-
Agent.maybeStartIast(null, null, null)
139+
Agent.maybeStartIast(null)
140140

141141
then:
142142
InstrumentationBridge.iastModules.each {

0 commit comments

Comments
 (0)