8338405: JFR: Use FILE type for dcmds
Reviewed-by: egahlin, lmesnik
This commit is contained in:
parent
caa751c561
commit
85aed87796
src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd
@ -30,7 +30,6 @@ import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@ -288,41 +287,4 @@ abstract class AbstractDCmd {
|
||||
return "/directory/recordings";
|
||||
}
|
||||
}
|
||||
|
||||
static String expandFilename(String filename) {
|
||||
if (filename == null || filename.indexOf('%') == -1) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
String pid = null;
|
||||
String time = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < filename.length(); i++) {
|
||||
char c = filename.charAt(i);
|
||||
if (c == '%' && i < filename.length() - 1) {
|
||||
char nc = filename.charAt(i + 1);
|
||||
if (nc == '%') { // %% ==> %
|
||||
sb.append('%');
|
||||
i++;
|
||||
} else if (nc == 'p') {
|
||||
if (pid == null) {
|
||||
pid = JVM.getPid();
|
||||
}
|
||||
sb.append(pid);
|
||||
i++;
|
||||
} else if (nc == 't') {
|
||||
if (time == null) {
|
||||
time = ValueFormatter.formatDateTime(LocalDateTime.now());
|
||||
}
|
||||
sb.append(time);
|
||||
i++;
|
||||
} else {
|
||||
sb.append('%');
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -25,14 +25,18 @@
|
||||
|
||||
package jdk.jfr.internal.dcmd;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import jdk.jfr.internal.JVM;
|
||||
import jdk.jfr.internal.util.SpellChecker;
|
||||
import jdk.jfr.internal.util.TimespanUnit;
|
||||
import jdk.jfr.internal.util.ValueFormatter;
|
||||
|
||||
final class ArgumentParser {
|
||||
private final Map<String, Object> options = new HashMap<>();
|
||||
@ -226,10 +230,54 @@ final class ArgumentParser {
|
||||
case "BOOLEAN" -> parseBoolean(name, text);
|
||||
case "NANOTIME" -> parseNanotime(name, text);
|
||||
case "MEMORY SIZE" -> parseMemorySize(name, text);
|
||||
case "FILE" -> text == null ? "" : parseFilename(text);
|
||||
default -> throw new InternalError("Unknown type: " + type);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands filename arguments replacing '%p' with the PID
|
||||
* and '%t' with the time in 'yyyy_MM_dd_HH_mm_ss' format.
|
||||
* @param filename a filename to be expanded
|
||||
* @return filename with expanded arguments
|
||||
*/
|
||||
private String parseFilename(String filename) {
|
||||
if (filename == null || filename.indexOf('%') == -1) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
String pid = null;
|
||||
String time = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < filename.length(); i++) {
|
||||
char c = filename.charAt(i);
|
||||
if (c == '%' && i < filename.length() - 1) {
|
||||
char nc = filename.charAt(i + 1);
|
||||
if (nc == '%') { // %% ==> %
|
||||
sb.append('%');
|
||||
i++;
|
||||
} else if (nc == 'p') {
|
||||
if (pid == null) {
|
||||
pid = JVM.getPid();
|
||||
}
|
||||
sb.append(pid);
|
||||
i++;
|
||||
} else if (nc == 't') {
|
||||
if (time == null) {
|
||||
time = ValueFormatter.formatDateTime(LocalDateTime.now());
|
||||
}
|
||||
sb.append(time);
|
||||
i++;
|
||||
} else {
|
||||
sb.append('%');
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Long parseLong(String name, String text) {
|
||||
if (text == null) {
|
||||
throw new IllegalArgumentException("Parsing error long value: syntax error, value is null");
|
||||
|
@ -55,7 +55,7 @@ final class DCmdDump extends AbstractDCmd {
|
||||
public void execute(ArgumentParser parser) throws DCmdException {
|
||||
parser.checkUnknownArguments();
|
||||
String name = parser.getOption("name");
|
||||
String filename = expandFilename(parser.getOption("filename"));
|
||||
String filename = parser.getOption("filename");
|
||||
Long maxAge = parser.getOption("maxage");
|
||||
Long maxSize = parser.getOption("maxsize");
|
||||
String begin = parser.getOption("begin");
|
||||
@ -230,7 +230,7 @@ final class DCmdDump extends AbstractDCmd {
|
||||
dumped. If no filename is given, a filename is generated from the PID
|
||||
and the current date. The filename may also be a directory in which
|
||||
case, the filename is generated from the PID and the current date in
|
||||
the specified directory. (STRING, no default value)
|
||||
the specified directory. (FILE, no default value)
|
||||
|
||||
Note: If a filename is given, '%%p' in the filename will be
|
||||
replaced by the PID, and '%%t' will be replaced by the time in
|
||||
@ -284,7 +284,7 @@ final class DCmdDump extends AbstractDCmd {
|
||||
"STRING", false, true, null, false),
|
||||
new Argument("filename",
|
||||
"Copy recording data to file, e.g. \\\"" + exampleFilename() + "\\\"",
|
||||
"STRING", false, true, null, false),
|
||||
"FILE", false, true, null, false),
|
||||
new Argument("maxage",
|
||||
"Maximum duration to dump, in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit",
|
||||
"NANOTIME", false, true, null, false),
|
||||
|
@ -80,7 +80,7 @@ final class DCmdStart extends AbstractDCmd {
|
||||
Long delay = parser.getOption("delay");
|
||||
Long duration = parser.getOption("duration");
|
||||
Boolean disk = parser.getOption("disk");
|
||||
String path = expandFilename(parser.getOption("filename"));
|
||||
String path = parser.getOption("filename");
|
||||
Long maxAge = parser.getOption("maxage");
|
||||
Long maxSize = parser.getOption("maxsize");
|
||||
Long flush = parser.getOption("flush-interval");
|
||||
@ -377,7 +377,7 @@ final class DCmdStart extends AbstractDCmd {
|
||||
placed in the directory where the process was started. The
|
||||
filename may also be a directory in which case, the filename is
|
||||
generated from the PID and the current date in the specified
|
||||
directory. (STRING, no default value)
|
||||
directory. (FILE, no default value)
|
||||
|
||||
Note: If a filename is given, '%p' in the filename will be
|
||||
replaced by the PID, and '%t' will be replaced by the time in
|
||||
@ -501,7 +501,7 @@ final class DCmdStart extends AbstractDCmd {
|
||||
"BOOLEAN", false, true, "true", false),
|
||||
new Argument("filename",
|
||||
"Resulting recording filename, e.g. \\\"" + exampleFilename() + "\\\"",
|
||||
"STRING", false, true, "hotspot-pid-xxxxx-id-y-YYYY_MM_dd_HH_mm_ss.jfr", false),
|
||||
"FILE", false, true, "hotspot-pid-xxxxx-id-y-YYYY_MM_dd_HH_mm_ss.jfr", false),
|
||||
new Argument("maxage",
|
||||
"Maximum time to keep recorded data (on disk) in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit",
|
||||
"NANOTIME", false, true, "0", false),
|
||||
|
@ -44,7 +44,7 @@ final class DCmdStop extends AbstractDCmd {
|
||||
protected void execute(ArgumentParser parser) throws DCmdException {
|
||||
parser.checkUnknownArguments();
|
||||
String name = parser.getOption("name");
|
||||
String filename = expandFilename(parser.getOption("filename"));
|
||||
String filename = parser.getOption("filename");
|
||||
try {
|
||||
Recording recording = findRecording(name);
|
||||
WriteableUserPath path = PrivateAccess.getInstance().getPlatformRecording(recording).getDestination();
|
||||
@ -80,7 +80,7 @@ final class DCmdStop extends AbstractDCmd {
|
||||
|
||||
filename (Optional) Name of the file to which the recording is written when the
|
||||
recording is stopped. If no path is provided, the data from the recording
|
||||
is discarded. (STRING, no default value)
|
||||
is discarded. (FILE, no default value)
|
||||
|
||||
Note: If a path is given, '%%p' in the path will be replaced by the PID,
|
||||
and '%%t' will be replaced by the time in 'yyyy_MM_dd_HH_mm_ss' format.
|
||||
@ -107,7 +107,7 @@ final class DCmdStop extends AbstractDCmd {
|
||||
"STRING", true, true, null, false),
|
||||
new Argument("filename",
|
||||
"Copy recording data to file, e.g. \\\"" + exampleFilename() + "\\\"",
|
||||
"STRING", false, true, null, false)
|
||||
"FILE", false, true, null, false)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user