File tree Expand file tree Collapse file tree 8 files changed +90
-0
lines changed
agent-bootstrap/src/main/java/datadog/trace/bootstrap
agent-profiling/profiling-utils
dd-smoke-tests/profiling-integration-tests/src/test/java/datadog/smoketest
src/main_java11/java/datadog/trace/util
src/main/java/datadog/trace/util Expand file tree Collapse file tree 8 files changed +90
-0
lines changed Original file line number Diff line number Diff line change 4242import datadog .trace .util .AgentTaskScheduler ;
4343import datadog .trace .util .AgentThreadFactory .AgentThread ;
4444import datadog .trace .util .throwable .FatalAgentMisconfigurationError ;
45+ import de .thetaphi .forbiddenapis .SuppressForbidden ;
4546import java .lang .instrument .Instrumentation ;
4647import java .lang .reflect .InvocationTargetException ;
4748import java .lang .reflect .Method ;
@@ -278,6 +279,8 @@ public static void start(
278279 codeOriginEnabled = isFeatureEnabled (AgentFeature .CODE_ORIGIN );
279280 agentlessLogSubmissionEnabled = isFeatureEnabled (AgentFeature .AGENTLESS_LOG_SUBMISSION );
280281
282+ patchJPSAccess (inst );
283+
281284 if (profilingEnabled ) {
282285 if (!isOracleJDK8 ()) {
283286 // Profiling agent startup code is written in a way to allow `startProfilingAgent` be called
@@ -407,6 +410,20 @@ private static void injectAgentArgsConfig(String agentArgs) {
407410 }
408411 }
409412
413+ @ SuppressForbidden
414+ public static void patchJPSAccess (Instrumentation inst ) {
415+ if (Platform .isJavaVersionAtLeast (9 )) {
416+ // Unclear if supported for J9, may need to revisit
417+ try {
418+ Class .forName ("datadog.trace.util.JPMSJPSAccess" )
419+ .getMethod ("patchModuleAccess" )
420+ .invoke (inst );
421+ } catch (Exception e ) {
422+ log .warn ("Failed to patch module access for jvmstat" );
423+ }
424+ }
425+ }
426+
410427 public static void shutdown (final boolean sync ) {
411428 StaticEventLogger .end ("Agent" );
412429 StaticEventLogger .stop ();
Original file line number Diff line number Diff line change 11// Set properties before any plugins get loaded
22ext {
3+ // In order to patch access for jvmstat for JDK >8
4+ minJavaVersionForTests = JavaVersion . VERSION_11
35}
46
57apply from : " $rootDir /gradle/java.gradle"
Original file line number Diff line number Diff line change @@ -507,6 +507,8 @@ void testShutdown(final TestInfo testInfo) throws Exception {
507507 assertTrue (
508508 targetProcess .waitFor (
509509 duration + PROFILING_UPLOAD_TIMEOUT_SECONDS + 1 , TimeUnit .SECONDS ));
510+ assertTrue (
511+ checkLogLines (logFilePath , it -> it .contains ("Successfully invoked jvmstat" )));
510512 } finally {
511513 if (targetProcess != null ) {
512514 targetProcess .destroyForcibly ();
Original file line number Diff line number Diff line change @@ -175,6 +175,7 @@ excludedClassesCoverage += [
175175 " datadog.trace.util.ComparableVersion.LongItem" ,
176176 " datadog.trace.util.ComparableVersion.StringItem" ,
177177 " datadog.trace.util.ConcurrentEnumMap" ,
178+ " datadog.trace.util.JPSUtils" ,
178179 " datadog.trace.util.MethodHandles" ,
179180 " datadog.trace.util.PidHelper" ,
180181 " datadog.trace.util.PidHelper.Fallback" ,
Original file line number Diff line number Diff line change @@ -41,6 +41,10 @@ forbiddenApisMain {
4141 failOnMissingClasses = false
4242}
4343
44+ forbiddenApisMain_java11 {
45+ failOnMissingClasses = false
46+ }
47+
4448idea {
4549 module {
4650 jdkName = ' 11'
Original file line number Diff line number Diff line change 1+ package datadog .trace .util ;
2+
3+ import java .lang .instrument .Instrumentation ;
4+ import java .util .Collections ;
5+ import java .util .Map ;
6+ import java .util .Set ;
7+
8+ public class JPMSJPSAccess {
9+ public static void patchModuleAccess (Instrumentation inst ) {
10+ Module unnamedModule = JPMSJPSAccess .class .getClassLoader ().getUnnamedModule ();
11+ Module jvmstatModule = ModuleLayer .boot ().findModule ("jdk.internal.jvmstat" ).orElse (null );
12+
13+ if (jvmstatModule != null ) {
14+ Map <String , Set <Module >> extraOpens = Map .of ("sun.jvmstat.monitor" , Set .of (unnamedModule ));
15+
16+ // Redefine the module
17+ inst .redefineModule (
18+ jvmstatModule ,
19+ Collections .emptySet (),
20+ extraOpens ,
21+ extraOpens ,
22+ Collections .emptySet (),
23+ Collections .emptyMap ());
24+ }
25+ }
26+ }
Original file line number Diff line number Diff line change 1+ package datadog .trace .util ;
2+
3+ import de .thetaphi .forbiddenapis .SuppressForbidden ;
4+ import java .lang .reflect .Method ;
5+ import java .util .HashSet ;
6+ import java .util .List ;
7+ import java .util .Set ;
8+ import org .slf4j .Logger ;
9+ import org .slf4j .LoggerFactory ;
10+
11+ public final class JPSUtils {
12+ private static final Logger log = LoggerFactory .getLogger (JPSUtils .class );
13+
14+ @ SuppressForbidden
15+ public static Set <String > getVMPids () {
16+ Set <String > vmPids = new HashSet <>();
17+ try {
18+ Class <?> monitoredHostClass = Class .forName ("sun.jvmstat.monitor.MonitoredHost" );
19+ Method getMonitoredHostMethod =
20+ monitoredHostClass .getDeclaredMethod ("getMonitoredHost" , String .class );
21+ Object vmHost = getMonitoredHostMethod .invoke (null , "localhost" );
22+ for (Integer vmPid :
23+ (List <Integer >) monitoredHostClass .getDeclaredMethod ("activeVms" ).invoke (vmHost )) {
24+ vmPids .add (vmPid .toString ());
25+ }
26+ log .debug ("Successfully invoked jvmstat" );
27+ } catch (Exception e ) {
28+ log .debug ("Failed to invoke jvmstat with exception " , e );
29+ return null ;
30+ }
31+ return vmPids ;
32+ }
33+ }
Original file line number Diff line number Diff line change @@ -65,6 +65,11 @@ private static String findPid() {
6565 }
6666
6767 public static Set <String > getJavaPids () {
68+ // Attempt to use jvmstat directly, fall through to jps process fork strategy
69+ Set <String > directlyObtainedPids = JPSUtils .getVMPids ();
70+ if (directlyObtainedPids != null ) {
71+ return directlyObtainedPids ;
72+ }
6873 // there is no supported Java API to achieve this
6974 // one could use sun.jvmstat.monitor.MonitoredHost but it is an internal API and can go away at
7075 // any time -
You can’t perform that action at this time.
0 commit comments