1
1
package datadog .trace .bootstrap ;
2
2
3
3
import static datadog .trace .api .ConfigDefaults .DEFAULT_STARTUP_LOGS_ENABLED ;
4
- import static datadog .trace .api .Platform .getRuntimeVendor ;
5
4
import static datadog .trace .api .Platform .isJavaVersionAtLeast ;
6
5
import static datadog .trace .api .Platform .isOracleJDK8 ;
7
6
import static datadog .trace .bootstrap .Library .WILDFLY ;
@@ -329,7 +328,7 @@ public void run() {
329
328
if (appUsingCustomJMXBuilder ) {
330
329
log .debug ("Custom JMX builder detected. Delaying JMXFetch initialization." );
331
330
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
333
332
scheduleJmxStart (60 + jmxStartDelay );
334
333
} else if (appUsingCustomLogManager ) {
335
334
log .debug ("Custom logger detected. Delaying JMXFetch initialization." );
@@ -339,20 +338,31 @@ public void run() {
339
338
}
340
339
}
341
340
342
- boolean delayOkHttp = appUsingCustomLogManager && okHttpMayIndirectlyLoadJUL ();
343
-
344
341
/*
345
342
* Similar thing happens with DatadogTracer on (at least) zulu-8 because it uses OkHttp which indirectly loads JFR
346
343
* events which in turn loads LogManager. This is not a problem on newer JDKs because there JFR uses different
347
344
* logging facility. Likewise on IBM JDKs OkHttp may indirectly load 'IBMSASL' which in turn loads LogManager.
348
345
*/
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 = 100 ;
353
+ } else {
354
+ okHttpDelayMillis = 0 ;
355
+ }
356
+
349
357
InstallDatadogTracerCallback installDatadogTracerCallback =
350
- new InstallDatadogTracerCallback (initTelemetry , inst , delayOkHttp );
351
- if (delayOkHttp ) {
358
+ new InstallDatadogTracerCallback (initTelemetry , inst , okHttpDelayMillis );
359
+ if (waitForJUL ) {
352
360
log .debug ("Custom logger detected. Delaying Datadog Tracer initialization." );
353
361
registerLogManagerCallback (installDatadogTracerCallback );
362
+ } else if (okHttpDelayMillis > 0 ) {
363
+ installDatadogTracerCallback .run (); // complete on different thread (after premain)
354
364
} else {
355
- installDatadogTracerCallback .execute ();
365
+ installDatadogTracerCallback .execute (); // complete on primordial thread in premain
356
366
}
357
367
358
368
/*
@@ -362,7 +372,7 @@ public void run() {
362
372
if (profilingEnabled && !isOracleJDK8 ()) {
363
373
StaticEventLogger .begin ("Profiling" );
364
374
365
- if (delayOkHttp ) {
375
+ if (waitForJUL ) {
366
376
log .debug ("Custom logger detected. Delaying Profiling initialization." );
367
377
registerLogManagerCallback (new StartProfilingAgentCallback (inst ));
368
378
} else {
@@ -499,18 +509,18 @@ protected static class InstallDatadogTracerCallback extends ClassLoadCallBack {
499
509
private final Instrumentation instrumentation ;
500
510
private final Object sco ;
501
511
private final Class <?> scoClass ;
502
- private final boolean delayOkHttp ;
512
+ private final int okHttpDelayMillis ;
503
513
504
514
public InstallDatadogTracerCallback (
505
515
InitializationTelemetry initTelemetry ,
506
516
Instrumentation instrumentation ,
507
- boolean delayOkHttp ) {
508
- this .delayOkHttp = delayOkHttp ;
517
+ int okHttpDelayMillis ) {
518
+ this .okHttpDelayMillis = okHttpDelayMillis ;
509
519
this .instrumentation = instrumentation ;
510
520
try {
511
521
scoClass =
512
522
AGENT_CLASSLOADER .loadClass ("datadog.communication.ddagent.SharedCommunicationObjects" );
513
- sco = scoClass .getConstructor (boolean .class ).newInstance (delayOkHttp );
523
+ sco = scoClass .getConstructor (boolean .class ).newInstance (okHttpDelayMillis > 0 );
514
524
} catch (ClassNotFoundException
515
525
| NoSuchMethodException
516
526
| InstantiationException
@@ -530,7 +540,7 @@ public AgentThread agentThread() {
530
540
531
541
@ Override
532
542
public void execute () {
533
- if (delayOkHttp ) {
543
+ if (okHttpDelayMillis > 0 ) {
534
544
resumeRemoteComponents ();
535
545
}
536
546
@@ -550,7 +560,7 @@ private void resumeRemoteComponents() {
550
560
try {
551
561
// remote components were paused for custom log-manager/jmx-builder
552
562
// add small delay before resuming remote I/O to help stabilization
553
- Thread .sleep (1_000 );
563
+ Thread .sleep (okHttpDelayMillis );
554
564
scoClass .getMethod ("resume" ).invoke (sco );
555
565
} catch (InterruptedException ignore ) {
556
566
} catch (Throwable e ) {
@@ -1339,15 +1349,25 @@ private static String ddGetEnv(final String sysProp) {
1339
1349
}
1340
1350
1341
1351
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
1352
+ if (isIBMSASLInstalled () || isACCPInstalled ( )) {
1353
+ return true ; // 'IBMSASL' and 'ACCP' crypto providers can load JUL when OkHttp accesses TLS
1344
1354
}
1345
1355
if (isJavaVersionAtLeast (9 )) {
1346
1356
return false ; // JDKs since 9 have reworked JFR to use a different logging facility, not JUL
1347
1357
}
1348
1358
return isJFRSupported (); // assume OkHttp will indirectly load JUL via its JFR events
1349
1359
}
1350
1360
1361
+ private static boolean isIBMSASLInstalled () {
1362
+ return ClassLoader .getSystemResource ("com/ibm/security/sasl/IBMSASL.class" ) != null ;
1363
+ }
1364
+
1365
+ private static boolean isACCPInstalled () {
1366
+ return ClassLoader .getSystemResource (
1367
+ "com/amazon/corretto/crypto/provider/AmazonCorrettoCryptoProvider.class" )
1368
+ != null ;
1369
+ }
1370
+
1351
1371
private static boolean isJFRSupported () {
1352
1372
// FIXME: this is quite a hack because there maybe jfr classes on classpath somehow that have
1353
1373
// nothing to do with JDK - but this should be safe because only thing this does is to delay
0 commit comments