Skip to content

Commit

Permalink
cells: add commands to start/stop java flight recording
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kofemann committed Mar 16, 2023
1 parent 081fdf0 commit 60c9937
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions modules/cells/src/main/java/dmg/cells/nucleus/SystemCell.java
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -42,6 +47,9 @@ public class SystemCell

private final CellShell _cellShell;
private final CellNucleus _nucleus;

private volatile Recording recording;

private int _packetsReceived,
_packetsAnswered,
_packetsForwarded,
Expand Down Expand Up @@ -137,6 +145,48 @@ public String call() {
}
}


@Command(name = "jfr start", hint = "Starts Java flight recorder", description = "Starts JFR")
public class StartJFR implements Callable<String> {

@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<String> {

@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<String> names = _nucleus.getCellNames();
List<String> nonSystem = new ArrayList<>(names.size());
Expand Down

0 comments on commit 60c9937

Please sign in to comment.