1818import static com .datadog .profiling .controller .ProfilingSupport .*;
1919import static com .datadog .profiling .controller .ProfilingSupport .isObjectCountParallelized ;
2020import static datadog .trace .api .Platform .isJavaVersionAtLeast ;
21- import static datadog .trace .api .config .ProfilingConfig .PROFILING_DEBUG_CLEANUP_REPO ;
22- import static datadog .trace .api .config .ProfilingConfig .PROFILING_DEBUG_CLEANUP_REPO_DEFAULT ;
2321import static datadog .trace .api .config .ProfilingConfig .PROFILING_HEAP_HISTOGRAM_ENABLED ;
2422import static datadog .trace .api .config .ProfilingConfig .PROFILING_HEAP_HISTOGRAM_ENABLED_DEFAULT ;
2523import static datadog .trace .api .config .ProfilingConfig .PROFILING_HEAP_HISTOGRAM_MODE ;
3331import com .datadog .profiling .controller .ConfigurationException ;
3432import com .datadog .profiling .controller .Controller ;
3533import com .datadog .profiling .controller .ControllerContext ;
34+ import com .datadog .profiling .controller .TempLocationManager ;
3635import com .datadog .profiling .controller .jfr .JFRAccess ;
3736import com .datadog .profiling .controller .jfr .JfpUtils ;
3837import com .datadog .profiling .controller .openjdk .events .AvailableProcessorCoresEvent ;
4241import datadog .trace .bootstrap .config .provider .ConfigProvider ;
4342import datadog .trace .bootstrap .instrumentation .jfr .backpressure .BackpressureProfiling ;
4443import datadog .trace .bootstrap .instrumentation .jfr .exceptions .ExceptionProfiling ;
45- import datadog .trace .util .PidHelper ;
4644import de .thetaphi .forbiddenapis .SuppressForbidden ;
4745import java .io .IOException ;
48- import java .nio .file .FileVisitResult ;
49- import java .nio .file .FileVisitor ;
5046import java .nio .file .Files ;
5147import java .nio .file .Path ;
52- import java .nio .file .Paths ;
53- import java .nio .file .attribute .BasicFileAttributes ;
5448import java .time .Duration ;
5549import java .util .Collections ;
5650import java .util .Map ;
57- import java .util .Set ;
5851import org .slf4j .Logger ;
5952import org .slf4j .LoggerFactory ;
6053
@@ -92,14 +85,8 @@ public OpenJdkController(final ConfigProvider configProvider)
9285 // configure the JFR stackdepth before we try to load any JFR classes
9386 int requestedStackDepth = getConfiguredStackDepth (configProvider );
9487 this .jfrStackDepthApplied = JFRAccess .instance ().setStackDepth (requestedStackDepth );
95- boolean shouldCleanupJfrRepository =
96- configProvider .getBoolean (
97- PROFILING_DEBUG_CLEANUP_REPO , PROFILING_DEBUG_CLEANUP_REPO_DEFAULT );
98- String jfrRepositoryBase = null ;
99- if (shouldCleanupJfrRepository ) {
100- jfrRepositoryBase = getJfrRepositoryBase (configProvider );
101- JFRAccess .instance ().setBaseLocation (jfrRepositoryBase + "/pid_" + PidHelper .getPid ());
102- }
88+ String jfrRepositoryBase = getJfrRepositoryBase (configProvider );
89+ JFRAccess .instance ().setBaseLocation (jfrRepositoryBase );
10390 // Make sure we can load JFR classes before declaring that we have successfully created
10491 // factory and can use it.
10592 Class .forName ("jdk.jfr.Recording" );
@@ -112,10 +99,6 @@ public OpenJdkController(final ConfigProvider configProvider)
11299 Map <String , String > recordingSettings ;
113100
114101 try {
115- if (shouldCleanupJfrRepository ) {
116- cleanupJfrRepositories (Paths .get (jfrRepositoryBase ));
117- }
118-
119102 recordingSettings =
120103 JfpUtils .readNamedJfpResource (
121104 ultraMinimal ? JfpUtils .SAFEPOINTS_JFP : JfpUtils .DEFAULT_JFP );
@@ -270,21 +253,27 @@ && isEventEnabled(recordingSettings, "jdk.NativeMethodSample")) {
270253 }
271254
272255 private static String getJfrRepositoryBase (ConfigProvider configProvider ) {
273- return configProvider .getString (
274- ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE ,
275- ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE_DEFAULT );
276- }
277-
278- private static void cleanupJfrRepositories (Path repositoryBase ) {
279- try {
280- Files .walkFileTree (repositoryBase , new JfrCleanupVisitor (repositoryBase ));
281- } catch (IOException e ) {
282- if (log .isDebugEnabled ()) {
283- log .warn ("Unable to cleanup old JFR repositories" , e );
284- } else {
285- log .warn ("Unable to cleanup old JFR repositories" );
256+ String legacy =
257+ configProvider .getString (
258+ ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE ,
259+ ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE_DEFAULT );
260+ if (!legacy .equals (ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE_DEFAULT )) {
261+ log .warn (
262+ "The configuration key {} is deprecated. Please use {} instead." ,
263+ ProfilingConfig .PROFILING_JFR_REPOSITORY_BASE ,
264+ ProfilingConfig .PROFILING_TEMP_DIR );
265+ }
266+ Path repositoryPath = TempLocationManager .getInstance ().getTempDir ().resolve ("jfr" );
267+ if (!Files .exists (repositoryPath )) {
268+ try {
269+ Files .createDirectories (repositoryPath );
270+ } catch (IOException e ) {
271+ log .error ("Failed to create JFR repository directory: {}" , repositoryPath , e );
272+ throw new IllegalStateException (
273+ "Failed to create JFR repository directory: " + repositoryPath , e );
286274 }
287275 }
276+ return repositoryPath .toString ();
288277 }
289278
290279 int getMaxSize () {
@@ -331,58 +320,4 @@ private int getConfiguredStackDepth(ConfigProvider configProvider) {
331320 return configProvider .getInteger (
332321 ProfilingConfig .PROFILING_STACKDEPTH , ProfilingConfig .PROFILING_STACKDEPTH_DEFAULT );
333322 }
334-
335- private static class JfrCleanupVisitor implements FileVisitor <Path > {
336- private boolean shouldClean = false ;
337-
338- private final Path root ;
339- private final Set <String > pidSet = PidHelper .getJavaPids ();
340-
341- JfrCleanupVisitor (Path root ) {
342- this .root = root ;
343- }
344-
345- @ Override
346- public FileVisitResult preVisitDirectory (Path dir , BasicFileAttributes attrs )
347- throws IOException {
348- if (dir .equals (root )) {
349- return FileVisitResult .CONTINUE ;
350- }
351- String fileName = dir .getFileName ().toString ();
352- // the JFR repository directories are under <basedir>/pid_<pid>
353- String pid = fileName .startsWith ("pid_" ) ? fileName .substring (4 ) : null ;
354- shouldClean |= pid != null && !pidSet .contains (pid );
355- if (shouldClean ) {
356- log .debug ("Cleaning JFR repository under {}" , dir );
357- }
358- return shouldClean ? FileVisitResult .CONTINUE : FileVisitResult .SKIP_SUBTREE ;
359- }
360-
361- @ Override
362- public FileVisitResult visitFile (Path file , BasicFileAttributes attrs ) throws IOException {
363- if (file .toString ().toLowerCase ().endsWith (".jfr" )) {
364- Files .delete (file );
365- }
366- return FileVisitResult .CONTINUE ;
367- }
368-
369- @ Override
370- public FileVisitResult visitFileFailed (Path file , IOException exc ) throws IOException {
371- if (log .isDebugEnabled () && file .toString ().toLowerCase ().endsWith (".jfr" )) {
372- log .debug ("Failed to delete file {}" , file , exc );
373- }
374- return FileVisitResult .CONTINUE ;
375- }
376-
377- @ Override
378- public FileVisitResult postVisitDirectory (Path dir , IOException exc ) throws IOException {
379- if (shouldClean ) {
380- Files .delete (dir );
381- String fileName = dir .getFileName ().toString ();
382- // reset the flag only if we are done cleaning the top-level directory
383- shouldClean = !fileName .startsWith ("pid_" );
384- }
385- return FileVisitResult .CONTINUE ;
386- }
387- }
388323}
0 commit comments