From 60c9937ad9cb3fdf631ee077384288b7b4f73a99 Mon Sep 17 00:00:00 2001 From: Tigran Mkrtchyan Date: Wed, 22 Feb 2023 11:50:59 +0100 Subject: [PATCH] cells: add commands to start/stop java flight recording Motivation: a simple way for admins to collect information useful to developers, especially when unexpected CPU load or exceptions are observed. Modification: Add admin commands "jfr enable/disable" in the SystemCell. Result: An easy way to start/stop java flight recorder at the runtime. Acked-by: Albert Rossi Acked-by: Lea Morschel Acked-by: Paul Millar Target: master Require-book: no Require-notes: yes --- .../java/dmg/cells/nucleus/SystemCell.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/modules/cells/src/main/java/dmg/cells/nucleus/SystemCell.java b/modules/cells/src/main/java/dmg/cells/nucleus/SystemCell.java index ce9f993a324..207eaaeca5d 100644 --- a/modules/cells/src/main/java/dmg/cells/nucleus/SystemCell.java +++ b/modules/cells/src/main/java/dmg/cells/nucleus/SystemCell.java @@ -6,12 +6,15 @@ import com.google.common.util.concurrent.MoreExecutors; import dmg.util.AuthorizedString; import dmg.util.command.Command; +import dmg.util.command.Option; import dmg.util.logback.FilterShell; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.io.Serializable; import java.net.InetAddress; import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -23,6 +26,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Function; +import jdk.jfr.Configuration; +import jdk.jfr.Recording; import org.apache.curator.framework.CuratorFramework; import org.dcache.alarms.AlarmMarkerFactory; import org.dcache.alarms.PredefinedAlarm; @@ -42,6 +47,9 @@ public class SystemCell private final CellShell _cellShell; private final CellNucleus _nucleus; + + private volatile Recording recording; + private int _packetsReceived, _packetsAnswered, _packetsForwarded, @@ -137,6 +145,48 @@ public String call() { } } + + @Command(name = "jfr start", hint = "Starts Java flight recorder", description = "Starts JFR") + public class StartJFR implements Callable { + + @Override + public String call() throws Exception { + + if (recording != null) { + return "Another record in progress."; + } + + Configuration configuration = Configuration.getConfiguration("default"); + recording = new Recording(configuration); + recording.setName(getCellDomainName()); + recording.start(); + + return "enabled"; + } + } + + @Command(name = "jfr stop", hint = "Stops Java flight recorder", description = "Stops JFR") + public class StopJFR implements Callable { + + @Option(name = "out", usage = "Path where to write flight recorder output") + String outFileName; + + @Override + public String call() throws Exception { + + recording.stop(); + try { + var outFile = + outFileName == null ? Files.createTempFile(getCellDomainName() + "_", ".jfr") + : Path.of(outFileName); + recording.dump(outFile); + return "recorded into " + outFile.toAbsolutePath(); + } finally { + recording = null; + } + } + } + private void shutdownSystem() { List names = _nucleus.getCellNames(); List nonSystem = new ArrayList<>(names.size());