From 27aad2d19a525efdcbbf2a1b6a0cdcc28fbd3a77 Mon Sep 17 00:00:00 2001 From: David Grieve Date: Tue, 11 Apr 2023 15:49:25 -0400 Subject: [PATCH] GCToolKit#addDataSourceParser (#288) * refactor: fix up mapping of aggregators to channels * add method GCToolkit#addDataSourceParser * Add GCToolKit#LOG_DEBUG_MESSAGE * improve debug messages * clean up formatting of debug message * s/producesEvents/eventsProduced/ --------- Co-authored-by: Kirk Pepperdine --- .../com/microsoft/gctoolkit/GCToolKit.java | 138 ++++++++++++++++-- .../gctoolkit/aggregator/Aggregator.java | 6 +- .../jvm/AbstractJavaVirtualMachine.java | 52 ++----- .../gctoolkit/jvm/JavaVirtualMachine.java | 3 +- .../gctoolkit/message/DataSourceParser.java | 4 + .../gctoolkit/io/RotatingGCLogTest.java | 26 ++++ .../microsoft/gctoolkit/io/TestLogFile.java | 49 +++++++ .../parser/CMSTenuredPoolParser.java | 7 + .../parser/GenerationalHeapParser.java | 12 +- .../gctoolkit/parser/JVMEventParser.java | 9 +- .../parser/PreUnifiedG1GCParser.java | 13 +- .../gctoolkit/parser/ShenandoahParser.java | 13 +- .../parser/SurvivorMemoryPoolParser.java | 8 + .../gctoolkit/parser/UnifiedG1GCParser.java | 12 +- .../parser/UnifiedGenerationalParser.java | 24 ++- .../parser/UnifiedJVMEventParser.java | 7 + .../UnifiedSurvivorMemoryPoolParser.java | 8 + .../microsoft/gctoolkit/parser/ZGCParser.java | 15 +- .../parser/vmops/SafepointParser.java | 7 + .../ConcurrentMarkSweepParserRulesTest.java | 23 +-- ...ncurrentMarkSweepPhaseParserRulesTest.java | 21 +-- .../parser/ParallelParserRulesTest.java | 2 - .../io/GarbageCollectionEventSourceTest.java | 11 +- 23 files changed, 366 insertions(+), 104 deletions(-) create mode 100644 api/src/test/java/com/microsoft/gctoolkit/io/RotatingGCLogTest.java create mode 100644 api/src/test/java/com/microsoft/gctoolkit/io/TestLogFile.java diff --git a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java index 10a1e3e8..c7341f17 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java +++ b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java @@ -3,6 +3,8 @@ package com.microsoft.gctoolkit; import com.microsoft.gctoolkit.aggregator.Aggregation; +import com.microsoft.gctoolkit.aggregator.Aggregator; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.io.GCLogFile; import com.microsoft.gctoolkit.io.RotatingGCLogFile; @@ -14,7 +16,9 @@ import com.microsoft.gctoolkit.message.JVMEventChannel; import java.io.IOException; +import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -22,8 +26,11 @@ import java.util.Optional; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import java.util.Set; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collector; import java.util.stream.Collectors; import static java.lang.Class.forName; @@ -35,6 +42,38 @@ public class GCToolKit { private static final Logger LOGGER = Logger.getLogger(GCToolKit.class.getName()); + private static final String GCTOOLKIT_DEBUG = System.getProperty("gctoolkit.debug"); + private static final boolean DEBUGGING = GCTOOLKIT_DEBUG != null; + + // returns true if gctoolkit.debug is set to "all" or contains "className", but does not contain "-className" + private static boolean isDebugging(String className) { + return DEBUGGING + && (GCTOOLKIT_DEBUG.isEmpty() + || ((GCTOOLKIT_DEBUG.contains("all") || GCTOOLKIT_DEBUG.contains(className)) + && !GCTOOLKIT_DEBUG.contains("-" + className))); + } + + /** + * Print a debug message to System.out if gctoolkit.debug is empty, is set to "all", + * or contains "className" but does not contain "-className". + * For example, to enable debug logging for all classes except UnifiedG1GCParser: + * -Dgctoolkit.debug=all,-com.microsoft.gctoolkit.parser.UnifiedG1GCParser + * + * @param message Supplies the message to log. If null, nothing will be logged. + */ + public static void LOG_DEBUG_MESSAGE(Supplier message) { + if (DEBUGGING && message != null) { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + String methodName = stackTrace[2].getMethodName(); + String className = stackTrace[2].getClassName(); + String fileName = stackTrace[2].getFileName(); + int lineNumber = stackTrace[2].getLineNumber(); + if (isDebugging(className)) { + System.out.println(String.format("DEBUG: %s.%s(%s:%d): %s", className, methodName, fileName, lineNumber, message.get())); + } + } + } + private final HashSet registeredDataSourceParsers = new HashSet<>(); private List registeredAggregations; private JVMEventChannel jvmEventChannel = null; @@ -71,10 +110,10 @@ public void loadAggregationsFromServiceLoader() { ServiceLoader.load(Aggregation.class) .stream() .map(ServiceLoader.Provider::get) - .forEach(registeredAggregations::add); - //Useful for debugging - if ( Level.FINER.equals(LOGGER.getLevel())) - registeredAggregations.forEach(a -> LOGGER.log(Level.FINER, "Registered " + a.toString())); + .forEach(aggregation -> { + registeredAggregations.add(aggregation); + LOG_DEBUG_MESSAGE(() -> "ServiceLoader provided: " + aggregation.getClass().getName()); + }); } /** @@ -154,11 +193,33 @@ private void loadJVMEventChannel() { } } + /** + * This method allows full control over which DataSourceParsers are used to parse the DataSource. + * This method should be called before the {@link #analyze(DataSource)} method. + * DataSourceParsers loaded by this method are used in place of those that are ordinarily loaded via + * the service provider interface. + * Use the {@link #addDataSourceParser(DataSourceParser)} method to load a DataSourceParser in addition + * to those loaded by the service provider interface. + * @param dataSourceParser An implementation of DataSourceParser that will be used to parse the DataSource. + */ public void loadDataSourceParser(DataSourceParser dataSourceParser) { registeredDataSourceParsers.add(dataSourceParser); } - private void loadDataSourceParsers(Diary diary) { + private List additiveParsers = new ArrayList<>(); + + /** + * Add a DataSourceParser to be used to parse a DataSource. The DataSourceParser will be used in addition + * to those loaded by the service provider interface. This method should be called before the + * {@link #analyze(DataSource)} method. + * @param dataSourceParser An implementation of DataSourceParser that will be used to parse the DataSource. + */ + public void addDataSourceParser(DataSourceParser dataSourceParser) { + additiveParsers.add(dataSourceParser); + } + + private Set loadDataSourceParsers(Diary diary) { + loadDataSourceChannel(); loadJVMEventChannel(); List dataSourceParsers; @@ -166,7 +227,7 @@ private void loadDataSourceParsers(Diary diary) { dataSourceParsers = ServiceLoader.load(DataSourceParser.class) .stream() .map(ServiceLoader.Provider::get) - .filter(consumer -> consumer.accepts(diary)) + .filter(dataSourceParser -> dataSourceParser.accepts(diary)) .collect(Collectors.toList()); } else{ dataSourceParsers = new ArrayList<>(); @@ -202,18 +263,28 @@ private void loadDataSourceParsers(Diary diary) { }) .filter(Optional::isPresent) .map(optional -> (DataSourceParser) optional.get()) - .filter(consumer -> consumer.accepts(diary)) + .filter(dataSourceParser -> dataSourceParser.accepts(diary)) .collect(Collectors.toList()); - if (dataSourceParsers.isEmpty()) { - throw new ServiceConfigurationError("Unable to find a suitable provider to create a DataSourceParser"); - } + + } + + // add in any additional parsers not provided by the module SPI. + dataSourceParsers.addAll(additiveParsers); + + if (dataSourceParsers.isEmpty()) { + throw new ServiceConfigurationError("Unable to find a suitable provider to create a DataSourceParser"); } for (DataSourceParser dataSourceParser : dataSourceParsers) { + LOG_DEBUG_MESSAGE(() -> "Registering " + dataSourceParser.getClass().getName() + " with " + dataSourceChannel.getClass().getName()); dataSourceParser.diary(diary); dataSourceChannel.registerListener(dataSourceParser); dataSourceParser.publishTo(jvmEventChannel); } + + return dataSourceParsers.stream() + .map(DataSourceParser::eventsProduced) + .collect(HashSet::new, Set::addAll, Set::addAll); } /** @@ -230,14 +301,57 @@ private void loadDataSourceParsers(Diary diary) { */ public JavaVirtualMachine analyze(DataSource dataSource) throws IOException { GCLogFile logFile = (GCLogFile)dataSource; - loadDataSourceParsers(logFile.diary()); + Set events = loadDataSourceParsers(logFile.diary()); JavaVirtualMachine javaVirtualMachine = loadJavaVirtualMachine(logFile); try { - javaVirtualMachine.analyze(registeredAggregations, jvmEventChannel, dataSourceChannel); + List> filteredAggregators = filterAggregations(events); + javaVirtualMachine.analyze(filteredAggregators, jvmEventChannel, dataSourceChannel); } catch(Throwable t) { LOGGER.log(Level.SEVERE, "Internal Error: Cannot invoke analyze method", t); } return javaVirtualMachine; } + private List> filterAggregations(Set events) { + List> aggregators = new ArrayList<>(); + for (Aggregation aggregation : registeredAggregations) { + LOG_DEBUG_MESSAGE(() -> "Evaluating: " + aggregation.getClass().getName()); + Constructor> constructor = constructor(aggregation); + if (constructor == null) { + LOGGER.log(Level.WARNING, "Cannot find one of: default constructor or @Collates annotation for " + aggregation.getClass().getName()); + continue; + } + + Aggregator aggregator = null; + try { + aggregator = constructor.newInstance(aggregation); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + continue; + } + if (events.stream().anyMatch(aggregator::aggregates)) { + LOG_DEBUG_MESSAGE(() -> "Including : " + aggregation.getClass().getName()); + aggregators.add(aggregator); + } else { + LOG_DEBUG_MESSAGE(() -> "Excluding : " + aggregation.getClass().getName()); + } + } + return aggregators; + + } + + @SuppressWarnings("unchecked") + private Constructor> constructor(Aggregation aggregation) { + Class> targetClazz = aggregation.collates(); + if ( targetClazz != null) { + Constructor[] constructors = targetClazz.getConstructors(); + for (Constructor constructor : constructors) { + Parameter[] parameters = constructor.getParameters(); + if (parameters.length == 1 && Aggregation.class.isAssignableFrom(parameters[0].getType())) + return (Constructor>) constructor; + } + } + return null; + } + } diff --git a/api/src/main/java/com/microsoft/gctoolkit/aggregator/Aggregator.java b/api/src/main/java/com/microsoft/gctoolkit/aggregator/Aggregator.java index 632aae74..ce11ab10 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/aggregator/Aggregator.java +++ b/api/src/main/java/com/microsoft/gctoolkit/aggregator/Aggregator.java @@ -121,10 +121,8 @@ public void onCompletion(Runnable task) { * Call a callback when aggregation is completed. */ private void complete() { - Runnable t = completionTask; - this.completionTask = null; - if (t != null) - Executors.newSingleThreadExecutor().execute(t); + if (completionTask != null) + Executors.newSingleThreadExecutor().execute(completionTask); } diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/AbstractJavaVirtualMachine.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/AbstractJavaVirtualMachine.java index 0818e2ec..bd7db30f 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/AbstractJavaVirtualMachine.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/AbstractJavaVirtualMachine.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.jvm; +import com.microsoft.gctoolkit.GCToolKit; import com.microsoft.gctoolkit.aggregator.Aggregation; import com.microsoft.gctoolkit.aggregator.Aggregator; import com.microsoft.gctoolkit.aggregator.EventSource; @@ -14,9 +15,6 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; import java.util.Optional; @@ -32,8 +30,6 @@ */ public abstract class AbstractJavaVirtualMachine implements JavaVirtualMachine { - private boolean debugging = Boolean.getBoolean("microsoft.debug.aggregation"); - private static final Logger LOGGER = Logger.getLogger(AbstractJavaVirtualMachine.class.getName()); private static final double LOG_FRAGMENT_THRESHOLD_SECONDS = 60.0d; //todo: replace magic threshold with a heuristic @@ -152,20 +148,6 @@ public Optional getAggregation(Class aggregationCl return Optional.ofNullable((T) aggregatedData.get(aggregationClass)); } - @SuppressWarnings("unchecked") - private Constructor> constructor(Aggregation aggregation) { - Class> targetClazz = aggregation.collates(); - if ( targetClazz != null) { - Constructor[] constructors = targetClazz.getConstructors(); - for (Constructor constructor : constructors) { - Parameter[] parameters = constructor.getParameters(); - if (parameters.length == 1 && Aggregation.class.isAssignableFrom(parameters[0].getType())) - return (Constructor>) constructor; - } - } - return null; - } - /** * Orchestrate the analysis of a GC log. Step wise * 1. find the aggregators that aggregate events generated by the gc log @@ -174,40 +156,24 @@ private Constructor> constructor(Aggregation aggregation * 4. Wait until all the aggregators have completed * 5. Set the start and end times * 6. Return to the caller - * @param registeredAggregations all of the aggregations loaded by the module SPI + * @param registeredAggregators all of the aggregations loaded by the module SPI * @param eventBus the bus to publish events on * @param dataSourceBus the bus that raw log lines are published on */ @Override - public void analyze(List registeredAggregations, JVMEventChannel eventBus, DataSourceChannel dataSourceBus) { + public void analyze(List> registeredAggregators, JVMEventChannel eventBus, DataSourceChannel dataSourceBus) { Phaser finishLine = new Phaser(); Set generatedEvents = diary.generatesEvents(); - for (Aggregation aggregation : registeredAggregations) { - if (debugging) - LOGGER.log(Level.INFO, "Evaluating: " + aggregation.toString()); - Constructor> constructor = constructor(aggregation); - if (constructor == null) { - LOGGER.log(Level.WARNING, "Cannot find one of: default constructor or @Collates annotation for " + aggregation.getClass().getName()); - continue; - } - if (debugging) - LOGGER.log(Level.INFO, "Loading : " + aggregation.toString()); - Aggregator aggregator = null; - try { - aggregator = constructor.newInstance(aggregation); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - continue; - } + for (Aggregator aggregator : registeredAggregators) { + Aggregation aggregation = aggregator.aggregation(); aggregatedData.put(aggregation.getClass(), aggregation); - Optional source = generatedEvents.stream().filter(aggregator::aggregates).findFirst(); - if (source.isPresent()) { - LOGGER.log(Level.FINE, "Registering: " + aggregation.getClass().getName()); + generatedEvents.stream().filter(aggregator::aggregates).forEach(eventSource -> { + GCToolKit.LOG_DEBUG_MESSAGE(() -> "Registering " + aggregator.getClass().getName() + " with " + eventSource.toChannel()); finishLine.register(); aggregator.onCompletion(finishLine::arriveAndDeregister); - JVMEventChannelAggregator eventChannelAggregator = new JVMEventChannelAggregator(source.get().toChannel(), aggregator); + JVMEventChannelAggregator eventChannelAggregator = new JVMEventChannelAggregator(eventSource.toChannel(), aggregator); eventBus.registerListener(eventChannelAggregator); - } + }); } try { diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java index 9cc2bf30..882f95be 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java @@ -5,6 +5,7 @@ import com.microsoft.gctoolkit.GCToolKit; import com.microsoft.gctoolkit.aggregator.Aggregation; +import com.microsoft.gctoolkit.aggregator.Aggregator; import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.message.DataSourceChannel; import com.microsoft.gctoolkit.message.JVMEventChannel; @@ -122,5 +123,5 @@ public interface JavaVirtualMachine { * @param eventChannel JVMEvent message channel * @param dataSourceChannel GC logging data channel */ - void analyze(List registeredAggregations, JVMEventChannel eventChannel, DataSourceChannel dataSourceChannel); + void analyze(List> registeredAggregations, JVMEventChannel eventChannel, DataSourceChannel dataSourceChannel); } \ No newline at end of file diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java index cc4acaf8..f63cc9cd 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java +++ b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java @@ -1,9 +1,13 @@ package com.microsoft.gctoolkit.message; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.jvm.Diary; +import java.util.Set; + public interface DataSourceParser extends DataSourceChannelListener { void publishTo(JVMEventChannel channel); void diary(Diary diary); boolean accepts(Diary diary); + Set eventsProduced(); } diff --git a/api/src/test/java/com/microsoft/gctoolkit/io/RotatingGCLogTest.java b/api/src/test/java/com/microsoft/gctoolkit/io/RotatingGCLogTest.java new file mode 100644 index 00000000..b59a6c8c --- /dev/null +++ b/api/src/test/java/com/microsoft/gctoolkit/io/RotatingGCLogTest.java @@ -0,0 +1,26 @@ +package com.microsoft.gctoolkit.io; + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +public class RotatingGCLogTest { + + @Test + void orderRotatingLogsTest() { + Path path = new TestLogFile("G1-80-16gbps2.log").getFile().toPath(); + try { + RotatingGCLogFile file = new RotatingGCLogFile(path); + assertEquals(2, file.getMetaData().getNumberOfFiles()); + assertEquals(2, file.getMetaData().logFiles().map(LogFileSegment::getPath).map(Path::toFile).map(File::getName).filter(s -> s.startsWith("G1-80-16gbps2")).count()); + file.getMetaData().logFiles().map(LogFileSegment::getEndTime).forEach(System.out::println); + } catch (IOException ioe) { + fail(ioe); + } + } +} diff --git a/api/src/test/java/com/microsoft/gctoolkit/io/TestLogFile.java b/api/src/test/java/com/microsoft/gctoolkit/io/TestLogFile.java new file mode 100644 index 00000000..48374c7a --- /dev/null +++ b/api/src/test/java/com/microsoft/gctoolkit/io/TestLogFile.java @@ -0,0 +1,49 @@ +package com.microsoft.gctoolkit.io; + +import java.io.File; +import java.util.Arrays; + +public class TestLogFile { + private final File logFile; + + private static final String[] relativePaths = { + "./", + "preunified/", + "preunified/cms/parnew/details/tenuring/", + "preunified/verbose/tenuring/", + "preunified/ps/details/tenuring/", + "preunified/ps/details/", + "unified/", + "unified/g1gc", + "streaming/", + "safepoint/", + }; + + public TestLogFile(String fileName) { + logFile = Arrays.stream(relativePaths) + .flatMap(path -> Arrays.stream(new String[]{ + "./" + path, + "../" + path, + "../../" + path, + "./gclogs/" + path, + "../gclogs/" + path, + "../../gclogs/" + path, + })) + .map(path -> new File(path + File.separator + fileName)) + .filter(File::exists) + .findFirst() + .orElseThrow(() -> new RuntimeException(fileName + " not found")); + } + + public TestLogFile(File file) { + this.logFile = file; + } + + public String getPath() { + return logFile.getPath(); + } + + public File getFile() { + return logFile; + } +} diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/CMSTenuredPoolParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/CMSTenuredPoolParser.java index e7c90f85..cd9d67fc 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/CMSTenuredPoolParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/CMSTenuredPoolParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.MemoryPoolSummary; import com.microsoft.gctoolkit.event.generational.AbortablePreClean; @@ -18,6 +19,7 @@ import com.microsoft.gctoolkit.message.JVMEventChannel; import com.microsoft.gctoolkit.time.DateTimeStamp; +import java.util.Set; import java.util.logging.Logger; public class CMSTenuredPoolParser extends PreUnifiedGCLogParser implements SimplePatterns, ICMSPatterns { @@ -28,6 +30,11 @@ public class CMSTenuredPoolParser extends PreUnifiedGCLogParser implements Simpl public CMSTenuredPoolParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.CMS_PREUNIFIED); + } + public String getName() { return ChannelName.CMS_TENURED_POOL_PARSER_OUTBOX.toString(); } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/GenerationalHeapParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/GenerationalHeapParser.java index f4f32666..b47ab579 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/GenerationalHeapParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/GenerationalHeapParser.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.CPUSummary; import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; @@ -31,6 +33,7 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -74,7 +77,6 @@ public class GenerationalHeapParser extends PreUnifiedGCLogParser implements Sim private int numberOfBlocksForwardReference; private long averageBlockSizeForwardReference; private int treeHeightForwardReference; - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); //Expect Remark private boolean expectRemark = false; @@ -272,6 +274,11 @@ public class GenerationalHeapParser extends PreUnifiedGCLogParser implements Sim public GenerationalHeapParser() { } + @Override + public Set eventsProduced() { + return Set.of(EventSource.GENERATIONAL); + } + @Override public String getName() { return "GenerationalHeapParser"; @@ -2006,8 +2013,7 @@ private void log(String line) { if (line.contains("GC log file has reached the maximum size")) return; if (line.contains("Large block")) return; - if (debugging) - LOGGER.fine("GenerationalHeapParser missed: " + line); + GCToolKit.LOG_DEBUG_MESSAGE(() -> "GenerationalHeapParser missed: " + line); LOGGER.log(Level.WARNING, "Missed: {0}", line); } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/JVMEventParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/JVMEventParser.java index f1f7fb36..d08181de 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/JVMEventParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/JVMEventParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.ApplicationConcurrentTime; import com.microsoft.gctoolkit.event.jvm.ApplicationStoppedTime; import com.microsoft.gctoolkit.event.jvm.JVMEvent; @@ -13,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -27,8 +29,13 @@ public class JVMEventParser extends PreUnifiedGCLogParser implements JVMPatterns public JVMEventParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.JVM); + } + public String getName() { - return "JavaEventParser"; + return "JVMEventParser"; } /** diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/PreUnifiedG1GCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/PreUnifiedG1GCParser.java index b823298e..da3dbf57 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/PreUnifiedG1GCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/PreUnifiedG1GCParser.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.CPUSummary; import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; @@ -33,6 +35,7 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.AbstractMap; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.BiConsumer; import java.util.logging.Level; @@ -50,7 +53,6 @@ public class PreUnifiedG1GCParser extends PreUnifiedGCLogParser implements G1GCPatterns { private static final Logger LOGGER = Logger.getLogger(PreUnifiedG1GCParser.class.getName()); - private boolean debugging = Boolean.getBoolean("microsoft.debug"); //values show up at the end of GC log file from a normally terminated JVM @SuppressWarnings("unused") @@ -239,6 +241,11 @@ public PreUnifiedG1GCParser() { forwardReference = trap; } + @Override + public Set eventsProduced() { + return Set.of(EventSource.G1GC); + } + public String getName() { return "PreUnifiedG1GCParser"; } @@ -1201,9 +1208,7 @@ private void log(String line) { if (line.startsWith("Memory: ")) return; if (line.startsWith("CommandLine flags: ")) return; - if (debugging) - LOGGER.fine("Missed: " + line); - + GCToolKit.LOG_DEBUG_MESSAGE(() -> "Missed: " + line); LOGGER.log(Level.FINE, "Missed: {0}", line); } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/ShenandoahParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/ShenandoahParser.java index c7f505f4..fb957810 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ShenandoahParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ShenandoahParser.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.JVMEvent; import com.microsoft.gctoolkit.event.jvm.JVMTermination; import com.microsoft.gctoolkit.jvm.Diary; @@ -12,6 +14,7 @@ import java.util.AbstractMap; import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,8 +35,6 @@ public class ShenandoahParser extends UnifiedGCLogParser implements ShenandoahPa private static final Logger LOGGER = Logger.getLogger(ShenandoahParser.class.getName()); - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); - private final MRUQueue> parseRules; { @@ -43,6 +44,11 @@ public class ShenandoahParser extends UnifiedGCLogParser implements ShenandoahPa public ShenandoahParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.SHENANDOAH); + } + @Override public String getName() { return "Shenandoah Parser"; @@ -85,8 +91,7 @@ public void endOfFile(GCLogTrace trace, String line) { //Implement all capture methods private void log(String line) { - if (debugging) - LOGGER.log(Level.FINE,"ZGCHeapParser missed: {0}", line); + GCToolKit.LOG_DEBUG_MESSAGE(() -> "ZGCHeapParser missed: " + line); LOGGER.log(Level.WARNING, "Missed: {0}", line); } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/SurvivorMemoryPoolParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/SurvivorMemoryPoolParser.java index fa220f17..4fbbd9d6 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/SurvivorMemoryPoolParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/SurvivorMemoryPoolParser.java @@ -2,12 +2,15 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.JVMTermination; import com.microsoft.gctoolkit.event.jvm.SurvivorRecord; import com.microsoft.gctoolkit.jvm.Diary; import com.microsoft.gctoolkit.message.ChannelName; import com.microsoft.gctoolkit.message.JVMEventChannel; +import java.util.Set; + import static com.microsoft.gctoolkit.parser.unified.UnifiedPatterns.JVM_EXIT; public class SurvivorMemoryPoolParser extends PreUnifiedGCLogParser implements TenuredPatterns { @@ -16,6 +19,11 @@ public class SurvivorMemoryPoolParser extends PreUnifiedGCLogParser implements T public SurvivorMemoryPoolParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.SURVIVOR); + } + public String getName() { return "SurvivorMemoryPoolParser"; } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java index 417918b7..4d9423d8 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.CPUSummary; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.event.MalformedEvent; @@ -26,6 +28,7 @@ import java.util.Map; import java.util.Optional; import java.util.Queue; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.logging.Level; @@ -46,7 +49,6 @@ public class UnifiedG1GCParser extends UnifiedGCLogParser implements UnifiedG1GCPatterns { private static final Logger LOGGER = Logger.getLogger(UnifiedG1GCParser.class.getName()); - private boolean debugging = Boolean.getBoolean("microsoft.debug"); private final Map collectionsUnderway = new ConcurrentHashMap<>(); @@ -156,6 +158,11 @@ public class UnifiedG1GCParser extends UnifiedGCLogParser implements UnifiedG1GC public UnifiedG1GCParser() { } + @Override + public Set eventsProduced() { + return Set.of(EventSource.G1GC); + } + public String getName() { return "UnifiedG1GCParser"; } @@ -721,8 +728,7 @@ private void ignore(GCLogTrace trace, String line) { private void log(String line) { if ( ! ignoreFrequentlySeenButUnwantedLines(line)) { - if (debugging) - LOGGER.fine("Missed: " + line); + GCToolKit.LOG_DEBUG_MESSAGE(() -> "Missed: " + line); LOGGER.log(Level.FINE, "Missed: {0}", line); } } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedGenerationalParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedGenerationalParser.java index 41242d0a..09b82fe2 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedGenerationalParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedGenerationalParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.CPUSummary; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; import com.microsoft.gctoolkit.event.generational.AbortablePreClean; @@ -33,11 +34,24 @@ import java.util.ArrayList; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.logging.Logger; -import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.*; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Abortable_Preclean; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.ConcurrentModeFailure; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Concurrent_Mark; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Concurrent_Preclean; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Concurrent_Reset; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Concurrent_Sweep; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.DefNew; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.FullGC; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.InitialMark; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.PSFull; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.PSYoungGen; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.ParNew; +import static com.microsoft.gctoolkit.event.GarbageCollectionTypes.Remark; /** * TODO No reports or views generated from this data yet. @@ -51,7 +65,6 @@ public class UnifiedGenerationalParser extends UnifiedGCLogParser implements UnifiedGenerationalPatterns { private static final Logger LOGGER = Logger.getLogger(UnifiedGenerationalParser.class.getName()); - private boolean debugging = Boolean.getBoolean("microsoft.debug"); private final RuleSet> parseRules; @@ -100,8 +113,13 @@ public class UnifiedGenerationalParser extends UnifiedGCLogParser implements Uni public UnifiedGenerationalParser() { } + @Override + public Set eventsProduced() { + return Set.of(EventSource.GENERATIONAL); + } + public String getName() { - return "UnifiedG1GCParser"; + return "UnifiedGenerationalParser"; } @Override diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedJVMEventParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedJVMEventParser.java index 3b41f798..26f3e759 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedJVMEventParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedJVMEventParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.ApplicationConcurrentTime; import com.microsoft.gctoolkit.event.jvm.ApplicationStoppedTime; import com.microsoft.gctoolkit.event.jvm.JVMEvent; @@ -11,6 +12,7 @@ import com.microsoft.gctoolkit.message.JVMEventChannel; import com.microsoft.gctoolkit.time.DateTimeStamp; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -25,6 +27,11 @@ public class UnifiedJVMEventParser extends UnifiedGCLogParser implements JVMPatt public UnifiedJVMEventParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.JVM); + } + public String getName() { return "JavaEventParser"; } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedSurvivorMemoryPoolParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedSurvivorMemoryPoolParser.java index 0823b120..9f9f786f 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedSurvivorMemoryPoolParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedSurvivorMemoryPoolParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.JVMEvent; import com.microsoft.gctoolkit.event.jvm.JVMTermination; import com.microsoft.gctoolkit.event.jvm.SurvivorRecord; @@ -10,6 +11,8 @@ import com.microsoft.gctoolkit.message.JVMEventChannel; import com.microsoft.gctoolkit.parser.jvm.Decorators; +import java.util.Set; + import static com.microsoft.gctoolkit.parser.unified.UnifiedPatterns.CPU_BREAKOUT; import static com.microsoft.gctoolkit.parser.unified.UnifiedPatterns.JVM_EXIT; @@ -31,6 +34,11 @@ public class UnifiedSurvivorMemoryPoolParser extends UnifiedGCLogParser implemen public UnifiedSurvivorMemoryPoolParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.SURVIVOR); + } + public String getName() { return "SurvivorMemoryPoolParser"; } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java index f245baab..a488f442 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/ZGCParser.java @@ -2,6 +2,8 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.jvm.JVMEvent; import com.microsoft.gctoolkit.event.jvm.JVMTermination; @@ -19,6 +21,7 @@ import java.util.AbstractMap; import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,13 +37,11 @@ * CMS failures * System.gc() calls */ + public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { private static final Logger LOGGER = Logger.getLogger(ZGCParser.class.getName()); - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); - private final boolean develop = Boolean.getBoolean("microsoft.develop"); - private ZGCForwardReference forwardReference; private final long[] markStart = new long[3]; @@ -74,6 +75,11 @@ public class ZGCParser extends UnifiedGCLogParser implements ZGCPatterns { public ZGCParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.ZGC); + } + @Override public String getName() { return "ZGC Parser"; @@ -261,8 +267,7 @@ private void memorySummary(GCLogTrace trace, String s) { } private void log(String line) { - if (debugging) - LOGGER.log(Level.FINE, "ZGCHeapParser missed: {0}", line); + GCToolKit.LOG_DEBUG_MESSAGE(() -> "ZGCHeapParser missed: " + line); LOGGER.log(Level.WARNING, "Missed: {0}", line); } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/vmops/SafepointParser.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/vmops/SafepointParser.java index b022cec4..51170261 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/vmops/SafepointParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/vmops/SafepointParser.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser.vmops; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.jvm.JVMTermination; import com.microsoft.gctoolkit.event.jvm.Safepoint; import com.microsoft.gctoolkit.jvm.Diary; @@ -9,11 +10,17 @@ import com.microsoft.gctoolkit.message.JVMEventChannel; import com.microsoft.gctoolkit.parser.PreUnifiedGCLogParser; +import java.util.Set; public class SafepointParser extends PreUnifiedGCLogParser implements SafepointPatterns { public SafepointParser() {} + @Override + public Set eventsProduced() { + return Set.of(EventSource.SAFEPOINT); + } + public String getName() { return "SafepointParser"; } diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepParserRulesTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepParserRulesTest.java index fa35825b..1b336101 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepParserRulesTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepParserRulesTest.java @@ -2,9 +2,14 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import java.util.StringJoiner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ConcurrentMarkSweepParserRulesTest implements CMSPatterns { @@ -30,27 +35,27 @@ public void testCMSParseRules() { /* Code that is useful when testing individual records */ - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); - // @Test //@Ignore("Not a real test, only for debugging") public void testDebugCMSParseRule() { int index = rules.length-1; // awesome fix from David.. thanks :-) //index = 36; GCParseRule rule = rules[index]; - evaluate(rule, lines[index][0], debugging); + evaluate(rule, lines[index][0]); } - private void evaluate(GCParseRule rule, String string, boolean dump) { + private void evaluate(GCParseRule rule, String string) { //The IDE eats messages printed to the log file.. thus this information *is* printed to stout GCLogTrace trace = rule.parse(string); assertNotNull(trace); - if (dump) { - System.out.println("matches groups " + trace.groupCount()); + // Enable debugging by setting gctoolkit.debug to true + GCToolKit.LOG_DEBUG_MESSAGE(() -> { + StringBuilder sb = new StringBuilder("matches groups " + trace.groupCount()); for (int i = 0; i <= trace.groupCount(); i++) { - System.out.println(i + ": " + trace.getGroup(i)); + sb.append(String.format("%n%d : %s", i, trace.getGroup(i))) ; } - } + return sb.toString(); + }); } private GCParseRule[] rules = { diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepPhaseParserRulesTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepPhaseParserRulesTest.java index 969e08b3..403fb772 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepPhaseParserRulesTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/ConcurrentMarkSweepPhaseParserRulesTest.java @@ -2,11 +2,14 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.parser; +import com.microsoft.gctoolkit.GCToolKit; import org.junit.jupiter.api.Test; import java.util.logging.Logger; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ConcurrentMarkSweepPhaseParserRulesTest implements CMSPatterns { @@ -30,26 +33,26 @@ public void testCMSParseRules() { /* Code that is useful when testing individual records */ - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); - @Test public void testDebugCMSParseRules() { int index = 0; GCParseRule rule = rules[index]; - evaluate(rule, lines[index], debugging); + evaluate(rule, lines[index]); } - private void evaluate(GCParseRule rule, String string, boolean dump) { + private void evaluate(GCParseRule rule, String string) { GCLogTrace trace = rule.parse(string); assertNotNull(trace); - if (dump) { - LOGGER.fine("matches groups " + trace.groupCount()); + // Enable debugging by setting gctoolkit.debug to true + GCToolKit.LOG_DEBUG_MESSAGE(() -> { + StringBuilder sb = new StringBuilder("matches groups " + trace.groupCount()); for (int i = 0; i <= trace.groupCount(); i++) { - LOGGER.fine(i + ": " + trace.getGroup(i)); + sb.append(String.format("%n%d : %s", i, trace.getGroup(i))) ; } - } + return sb.toString(); + }); } //2015-08-04T19:50:56.691-0400: 168027.353: [GC[YG occupancy: 64589 K (720896 K)]2015-08-04T19:50:56.693-0400: 168027.355: [GC 168027.355: [ParNew diff --git a/parser/src/test/java/com/microsoft/gctoolkit/parser/ParallelParserRulesTest.java b/parser/src/test/java/com/microsoft/gctoolkit/parser/ParallelParserRulesTest.java index 283728be..43bef54e 100644 --- a/parser/src/test/java/com/microsoft/gctoolkit/parser/ParallelParserRulesTest.java +++ b/parser/src/test/java/com/microsoft/gctoolkit/parser/ParallelParserRulesTest.java @@ -29,8 +29,6 @@ public void testParallelParseRules() { /* Code that is useful when testing individual records */ - private final boolean debugging = Boolean.getBoolean("microsoft.debug"); - // @Test public void testDebugParallelParseRules() { int index = 4; diff --git a/vertx/src/test/java/com/microsoft/gctoolkit/vertx/io/GarbageCollectionEventSourceTest.java b/vertx/src/test/java/com/microsoft/gctoolkit/vertx/io/GarbageCollectionEventSourceTest.java index 44efee38..cb851bbc 100644 --- a/vertx/src/test/java/com/microsoft/gctoolkit/vertx/io/GarbageCollectionEventSourceTest.java +++ b/vertx/src/test/java/com/microsoft/gctoolkit/vertx/io/GarbageCollectionEventSourceTest.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.microsoft.gctoolkit.vertx.io; +import com.microsoft.gctoolkit.aggregator.EventSource; import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.GCEvent; import com.microsoft.gctoolkit.event.generational.DefNew; @@ -19,9 +20,12 @@ import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Set; import java.util.concurrent.CountDownLatch; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; public class GarbageCollectionEventSourceTest { @@ -149,6 +153,11 @@ public void diary(Diary diary) { public boolean accepts(Diary diary) { return false; } + + @Override + public Set eventsProduced() { + return Set.of(); + } } @Test