8295650: JFR: jfr scrub should warn if an event type doesn't exist

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2022-10-21 17:14:24 +00:00
parent 0c13d66622
commit f41711ef63
5 changed files with 66 additions and 22 deletions
src/jdk.jfr/share/classes/jdk/jfr/internal/tool
test/jdk/jdk/jfr/tool

@ -40,7 +40,7 @@ import jdk.jfr.consumer.RecordedEvent;
*/
public class Filters {
static Predicate<EventType> createCategoryFilter(String filterText) throws UserSyntaxException {
static Predicate<EventType> createCategoryFilter(String filterText, List<EventType> types) throws UserSyntaxException {
List<String> filters = explodeFilter(filterText);
Predicate<EventType> f = eventType -> {
for (String category : eventType.getCategoryNames()) {
@ -55,10 +55,13 @@ public class Filters {
}
return false;
};
if (unknownEventType(f, types)) {
System.out.println("Warning, no event type matched category filter: " + filterText);
}
return createCache(f, EventType::getId);
}
static Predicate<EventType> createEventTypeFilter(String filterText) throws UserSyntaxException {
static Predicate<EventType> createEventTypeFilter(String filterText, List<EventType> types) throws UserSyntaxException {
List<String> filters = explodeFilter(filterText);
Predicate<EventType> f = eventType -> {
for (String filter : filters) {
@ -73,9 +76,19 @@ public class Filters {
}
return false;
};
if (unknownEventType(f, types)) {
System.out.println("Warning, no event type matched filter: " + filterText);
}
return createCache(f, EventType::getId);
}
private static boolean unknownEventType(Predicate<EventType> f, List<EventType> types) {
if (types.isEmpty()) {
return false;
}
return !types.stream().anyMatch(f);
}
public static <T> Predicate<T> matchAny(List<Predicate<T>> filters) {
if (filters.isEmpty()) {
return t -> true;

@ -178,7 +178,7 @@ final class Metadata extends Command {
foundEventFilter = true;
String filterStr = options.remove();
warnForWildcardExpansion("--events", filterStr);
filters.add(Filters.createEventTypeFilter(filterStr));
filters.add(Filters.createEventTypeFilter(filterStr, List.of()));
}
if (acceptFilterOption(options, "--categories")) {
if (foundCategoryFilter) {
@ -187,7 +187,7 @@ final class Metadata extends Command {
foundCategoryFilter = true;
String filterStr = options.remove();
warnForWildcardExpansion("--categories", filterStr);
filters.add(Filters.createCategoryFilter(filterStr));
filters.add(Filters.createCategoryFilter(filterStr, List.of()));
}
if (optionCount == options.size()) {
// No progress made

@ -116,7 +116,7 @@ final class Print extends Command {
foundEventFilter = true;
String filter = options.remove();
warnForWildcardExpansion("--events", filter);
eventFilters.add(Filters.createEventTypeFilter(filter));
eventFilters.add(Filters.createEventTypeFilter(filter, List.of()));
}
if (acceptFilterOption(options, "--categories")) {
if (foundCategoryFilter) {
@ -125,7 +125,7 @@ final class Print extends Command {
foundCategoryFilter = true;
String filter = options.remove();
warnForWildcardExpansion("--categories", filter);
eventFilters.add(Filters.createCategoryFilter(filter));
eventFilters.add(Filters.createCategoryFilter(filter, List.of()));
}
if (acceptOption(options, "--stack-depth")) {
String value = options.pop();

@ -34,6 +34,7 @@ import java.util.Deque;
import java.util.List;
import java.util.function.Predicate;
import jdk.jfr.EventType;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile;
@ -135,31 +136,43 @@ final class Scrub extends Command {
}
ensureUsableOutput(input, output);
try (RecordingFile rf = new RecordingFile(input)) {
List<EventType> types = rf.readEventTypes();
Predicate<RecordedEvent> filter = createFilter(options, types);
rf.write(output, filter);
} catch (IOException ioe) {
couldNotReadError(input, ioe);
}
println("Scrubbed recording file written to:");
println(output.toAbsolutePath().toString());
}
private Predicate<RecordedEvent> createFilter(Deque<String> options, List<EventType> types) throws UserSyntaxException, UserDataException {
List<Predicate<RecordedEvent>> filters = new ArrayList<>();
int optionCount = options.size();
while (optionCount > 0) {
if (acceptFilterOption(options, "--include-events")) {
String filter = options.remove();
warnForWildcardExpansion("--include-events", filter);
var f = Filters.createEventTypeFilter(filter);
var f = Filters.createEventTypeFilter(filter, types);
filters.add(Filters.fromEventType(f));
}
if (acceptFilterOption(options, "--exclude-events")) {
String filter = options.remove();
warnForWildcardExpansion("--exclude-events", filter);
var f = Filters.createEventTypeFilter(filter);
var f = Filters.createEventTypeFilter(filter, types);
filters.add(Filters.fromEventType(f.negate()));
}
if (acceptFilterOption(options, "--include-categories")) {
String filter = options.remove();
warnForWildcardExpansion("--include-categories", filter);
var f = Filters.createCategoryFilter(filter);
var f = Filters.createCategoryFilter(filter, types);
filters.add(Filters.fromEventType(f));
}
if (acceptFilterOption(options, "--exclude-categories")) {
String filter = options.remove();
warnForWildcardExpansion("--exclude-categories", filter);
var f = Filters.createCategoryFilter(filter);
var f = Filters.createCategoryFilter(filter, types);
filters.add(Filters.fromEventType(f.negate()));
}
if (acceptFilterOption(options, "--include-threads")) {
@ -183,14 +196,7 @@ final class Scrub extends Command {
}
optionCount = options.size();
}
try (RecordingFile rf = new RecordingFile(input)) {
rf.write(output, Filters.matchAny(filters));
} catch (IOException ioe) {
couldNotReadError(input, ioe);
}
println("Scrubbed recording file written to:");
println(output.toAbsolutePath().toString());
return Filters.matchAny(filters);
}
private void ensureUsableOutput(Path input, Path output) throws UserSyntaxException, UserDataException {

@ -23,16 +23,12 @@
package jdk.jfr.tool;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jdk.test.lib.Utils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.jfr.Name;
import jdk.jfr.Recording;
@ -91,6 +87,8 @@ public class TestScrub {
testThreadExclude(file);
testThreadInclude(file);
testMissingEventType(file);
}
private static void testInputOutput(Path file) throws Throwable {
@ -250,6 +248,33 @@ public class TestScrub {
}
}
private static void testMissingEventType(Path input) throws Throwable {
Path output = Path.of("scrubbed.jfr");
String[] args = {
"scrub",
"--exclude-events", "Foo",
"--include-events", "example.Zebra",
"--include-events", "jdk.Bar",
"--include-events", "example.Tigerfish",
"--exclude-categories", "Mammal",
"--exclude-categories", "jdk.Baz",
"--include-categories", "Fish",
"--include-categories", "jdk.Qux,jdk.Quuz",
input.toAbsolutePath().toString(),
output.toAbsolutePath().toString()
};
var outp = ExecuteHelper.jfr(args);
outp.shouldContain("Warning, no event type matched filter: Foo");
outp.shouldContain("Warning, no event type matched filter: jdk.Bar");
outp.shouldContain("Warning, no event type matched category filter: jdk.Baz");
outp.shouldContain("Warning, no event type matched category filter: jdk.Qux,jdk.Quuz");
outp.shouldNotContain("Warning, no event type matched filter: example.Zebra");
outp.shouldNotContain("Warning, no event type matched filter: example.Tigerfish");
outp.shouldNotContain("Warning, no event type matched category filter: Mammal");
outp.shouldNotContain("Warning, no event type matched category filter: Fish");
Files.delete(output);
}
private static void assertNotThread(RecordedEvent event, String... threadNames) {
String s = event.getThread().getJavaName();
for (String threadName : threadNames) {