From 6c352624d2dc2d50e457f54d8d98a5ede407a9e4 Mon Sep 17 00:00:00 2001 From: jkost Date: Thu, 30 Dec 2021 21:08:42 +0200 Subject: [PATCH 01/11] Update README.md (#195) To run the sample, `mvnw compile` is not enough; `mvn install` is needed so that the artifacts are created in the local maven repository and can be found by the next step. Then, one needs to first cd sample and then run `mvnw exec:exec` or `mvn exec:exec`. --- sample/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample/README.md b/sample/README.md index c00fb0c8..fd682fae 100644 --- a/sample/README.md +++ b/sample/README.md @@ -8,10 +8,10 @@ We use the Maven wrapper (`mvnw`) so you don't have to change your system wide M ### From Maven -Compile the sample with `mvnw compile`, then use `mvnw exec:exec` to run the sample. +Install the sample to your local maven repository with `mvnw install`, then use `mvnw exec:exec` to run the sample. ```shell -mvnw clean compile +mvnw clean install mvnw exec:exec ``` From 5405495005ebd273eb24805563c48959c979f5a7 Mon Sep 17 00:00:00 2001 From: Yifeng Jin Date: Sat, 29 Jan 2022 18:03:12 +0800 Subject: [PATCH 02/11] fix: add UnifiedJavaVirtualMachine to modulo-info (#202) * fix: add UnifiedJavaVirtualMachine to modulo-info * Update module-info.java Co-authored-by: Bruno Borges --- vertx/src/main/java/module-info.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vertx/src/main/java/module-info.java b/vertx/src/main/java/module-info.java index dfd19f51..e4e16bc6 100644 --- a/vertx/src/main/java/module-info.java +++ b/vertx/src/main/java/module-info.java @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import com.microsoft.gctoolkit.vertx.jvm.PreUnifiedJavaVirtualMachine; - /** * Contains a vertx based implementation of GCToolKit. The vertx implementation is an internal module. * @provides com.microsoft.gctoolkit.jvm.JavaVirtualMachine @@ -17,6 +15,7 @@ com.microsoft.gctoolkit.api; provides com.microsoft.gctoolkit.jvm.JavaVirtualMachine with - PreUnifiedJavaVirtualMachine; + com.microsoft.gctoolkit.vertx.jvm.PreUnifiedJavaVirtualMachine, + com.microsoft.gctoolkit.vertx.jvm.UnifiedJavaVirtualMachine; -} \ No newline at end of file +} From 5e1274bc8bd4a91625246d157bab9003f1947965 Mon Sep 17 00:00:00 2001 From: Kirk Pepperdine <74371364+kirk-microsoft@users.noreply.github.com> Date: Thu, 3 Feb 2022 03:32:45 -0800 Subject: [PATCH 03/11] Datetime (#204) * refactoring of JavaVirtualMachine * fix: DateTimeStamp is being reported incorrectly * refactor: reorganize IT module to better support tests * refactor: pick up modified files * fix: return correct time of log termination --- .gitignore | 1 + .../CollectionCycleCountsAggregation.java | 0 .../CollectionCycleCountsAggregator.java | 0 .../CollectionCycleCountsSummary.java | 0 .../HeapOccupancyAfterCollection.java | 0 ...apOccupancyAfterCollectionAggregation.java | 0 .../HeapOccupancyAfterCollectionSummary.java | 0 .../aggregation/PauseTimeAggregation.java | 0 .../aggregation/PauseTimeAggregator.java | 0 .../aggregation/PauseTimeSummary.java | 0 .../aggregation/RuntimeAggregation.java | 0 .../aggregation/RuntimeAggregator.java | 0 .../integration/collections/XYDataSet.java | 0 IT/src/{test => main}/java/module-info.java | 4 +- .../integration/EndToEndIntegrationTest.java | 10 +- .../RuntimeAggregationTest.java | 3 +- .../{collections => }/XYDataSetTest.java | 3 +- .../JavaVirtualMachineConfigurationTest.java | 47 +++++++ .../com/microsoft/gctoolkit/GCToolKit.java | 45 ++++++- .../gctoolkit/event/MalformedEvent.java | 7 + .../com/microsoft/gctoolkit/jvm/Diarizer.java | 1 + .../com/microsoft/gctoolkit/jvm/Diary.java | 10 ++ .../gctoolkit/jvm/JavaVirtualMachine.java | 19 +-- .../gctoolkit/jvm/JvmConfiguration.java | 98 -------------- .../gctoolkit/message/DataSourceBus.java | 9 ++ .../gctoolkit/message/DataSourceParser.java | 9 ++ .../message/DataSourcePublisher.java | 4 + .../gctoolkit/message/JVMEventBus.java | 16 +++ .../gctoolkit/message/JVMEventPublisher.java | 4 + api/src/main/java/module-info.java | 2 + .../parser/G1GCForwardReference.java | 12 +- .../gctoolkit/parser/UnifiedG1GCParser.java | 13 +- .../parser/jvm/PreUnifiedDiarizer.java | 5 + .../gctoolkit/parser/jvm/UnifiedDiarizer.java | 13 +- .../gctoolkit/vertx/GCToolkitVertx.java | 24 ++-- .../vertx/aggregator/AggregatorVerticle.java | 21 +-- .../vertx/jvm/AbstractJavaVirtualMachine.java | 94 +++++++------ ...olkitVertxParametersForPreUnifiedLogs.java | 5 +- .../vertx/jvm/JvmConfigurationImpl.java | 103 --------------- .../jvm/PreUnifiedJavaVirtualMachine.java | 124 +----------------- .../vertx/jvm/UnifiedJavaVirtualMachine.java | 113 +--------------- 41 files changed, 284 insertions(+), 535 deletions(-) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregation.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsSummary.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollection.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregation.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionSummary.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregation.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregator.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeSummary.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregation.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregator.java (100%) rename IT/src/{test => main}/java/com/microsoft/gctoolkit/integration/collections/XYDataSet.java (100%) rename IT/src/{test => main}/java/module-info.java (86%) rename IT/src/test/java/com/microsoft/gctoolkit/integration/{aggregation => }/RuntimeAggregationTest.java (97%) rename IT/src/test/java/com/microsoft/gctoolkit/integration/{collections => }/XYDataSetTest.java (93%) create mode 100644 IT/src/test/java/com/microsoft/gctoolkit/integration/core/JavaVirtualMachineConfigurationTest.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/event/MalformedEvent.java delete mode 100644 api/src/main/java/com/microsoft/gctoolkit/jvm/JvmConfiguration.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/message/DataSourceBus.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/message/DataSourcePublisher.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/message/JVMEventBus.java create mode 100644 api/src/main/java/com/microsoft/gctoolkit/message/JVMEventPublisher.java delete mode 100644 vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/JvmConfigurationImpl.java diff --git a/.gitignore b/.gitignore index aab6d4eb..3d77079f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ gclogs/streaming gclogs/unified gclogs/zgc +unifiedrules.txt gctoolkit-testdata-*.zip # Maven diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregation.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregation.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregation.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregation.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsAggregator.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsSummary.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsSummary.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsSummary.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/CollectionCycleCountsSummary.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollection.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollection.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollection.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollection.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregation.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregation.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregation.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionAggregation.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionSummary.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionSummary.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionSummary.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/HeapOccupancyAfterCollectionSummary.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregation.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregation.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregation.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregation.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregator.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregator.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregator.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeAggregator.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeSummary.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeSummary.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeSummary.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/PauseTimeSummary.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregation.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregation.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregation.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregation.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregator.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregator.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregator.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregator.java diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/collections/XYDataSet.java b/IT/src/main/java/com/microsoft/gctoolkit/integration/collections/XYDataSet.java similarity index 100% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/collections/XYDataSet.java rename to IT/src/main/java/com/microsoft/gctoolkit/integration/collections/XYDataSet.java diff --git a/IT/src/test/java/module-info.java b/IT/src/main/java/module-info.java similarity index 86% rename from IT/src/test/java/module-info.java rename to IT/src/main/java/module-info.java index 98f68efe..9557429d 100644 --- a/IT/src/test/java/module-info.java +++ b/IT/src/main/java/module-info.java @@ -10,9 +10,9 @@ requires com.microsoft.gctoolkit.parser; requires com.microsoft.gctoolkit.vertx; requires java.logging; - requires org.junit.jupiter.api; - exports com.microsoft.gctoolkit.integration; +// exports com.microsoft.gctoolkit.integration.aggregation; +// exports com.microsoft.gctoolkit.integration.collections; exports com.microsoft.gctoolkit.integration.aggregation to com.microsoft.gctoolkit.vertx; diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/EndToEndIntegrationTest.java b/IT/src/test/java/com/microsoft/gctoolkit/integration/EndToEndIntegrationTest.java index 7a1f518e..db7b5f59 100644 --- a/IT/src/test/java/com/microsoft/gctoolkit/integration/EndToEndIntegrationTest.java +++ b/IT/src/test/java/com/microsoft/gctoolkit/integration/EndToEndIntegrationTest.java @@ -10,9 +10,12 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.io.IOException; import java.nio.file.Path; import java.util.Optional; +import static org.junit.jupiter.api.Assertions.fail; + public class EndToEndIntegrationTest { @Test @@ -43,7 +46,12 @@ public void analyze(String gcLogFile) { * The JavaVirtualMachine contains the aggregations as filled out by the Aggregators. * It also contains configuration information about how the JVM was configured for the runtime. */ - JavaVirtualMachine machine = gcToolKit.analyze(logFile); + JavaVirtualMachine machine = null; + try { + machine = gcToolKit.analyze(logFile); + } catch (IOException e) { + fail(e.getMessage()); + } // Retrieves the Aggregation for HeapOccupancyAfterCollectionSummary. This is a time-series aggregation. String message = "The XYDataSet for %s contains %s items.\n"; diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregationTest.java b/IT/src/test/java/com/microsoft/gctoolkit/integration/RuntimeAggregationTest.java similarity index 97% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregationTest.java rename to IT/src/test/java/com/microsoft/gctoolkit/integration/RuntimeAggregationTest.java index 2c4689d8..494e07c4 100644 --- a/IT/src/test/java/com/microsoft/gctoolkit/integration/aggregation/RuntimeAggregationTest.java +++ b/IT/src/test/java/com/microsoft/gctoolkit/integration/RuntimeAggregationTest.java @@ -1,5 +1,6 @@ -package com.microsoft.gctoolkit.integration.aggregation; +package com.microsoft.gctoolkit.integration; +import com.microsoft.gctoolkit.integration.aggregation.RuntimeAggregation; import com.microsoft.gctoolkit.time.DateTimeStamp; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/collections/XYDataSetTest.java b/IT/src/test/java/com/microsoft/gctoolkit/integration/XYDataSetTest.java similarity index 93% rename from IT/src/test/java/com/microsoft/gctoolkit/integration/collections/XYDataSetTest.java rename to IT/src/test/java/com/microsoft/gctoolkit/integration/XYDataSetTest.java index c2afa9f8..c30f12a3 100644 --- a/IT/src/test/java/com/microsoft/gctoolkit/integration/collections/XYDataSetTest.java +++ b/IT/src/test/java/com/microsoft/gctoolkit/integration/XYDataSetTest.java @@ -1,7 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -package com.microsoft.gctoolkit.integration.collections; +package com.microsoft.gctoolkit.integration; +import com.microsoft.gctoolkit.integration.collections.XYDataSet; import com.microsoft.gctoolkit.integration.collections.XYDataSet.Point; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/IT/src/test/java/com/microsoft/gctoolkit/integration/core/JavaVirtualMachineConfigurationTest.java b/IT/src/test/java/com/microsoft/gctoolkit/integration/core/JavaVirtualMachineConfigurationTest.java new file mode 100644 index 00000000..9f05f1a5 --- /dev/null +++ b/IT/src/test/java/com/microsoft/gctoolkit/integration/core/JavaVirtualMachineConfigurationTest.java @@ -0,0 +1,47 @@ +package com.microsoft.gctoolkit.integration.core; + +import com.microsoft.gctoolkit.GCToolKit; +import com.microsoft.gctoolkit.integration.io.TestLogFile; +import com.microsoft.gctoolkit.io.GCLogFile; +import com.microsoft.gctoolkit.io.RotatingGCLogFile; +import com.microsoft.gctoolkit.io.SingleGCLogFile; +import com.microsoft.gctoolkit.jvm.JavaVirtualMachine; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.fail; + +public class JavaVirtualMachineConfigurationTest { + + private String logFile = "rolling/jdk14/rollinglogs/long_restart.log"; + private int[][] times = { { 0, 13, 262172, 262172}, { 259077, 259077, 262172, 3095}}; + + @Test + public void testRotating() { + TestLogFile log = new TestLogFile(logFile); + test(new RotatingGCLogFile(log.getFile().toPath()), times[0]); + } + + @Test + public void testSingle() { + TestLogFile log = new TestLogFile(logFile); + test(new SingleGCLogFile(log.getFile().toPath()), times[1]); + } + + private void test(GCLogFile log, int[] endStartTimes ) { + GCToolKit gcToolKit = new GCToolKit(); + gcToolKit.loadAggregationsFromServiceLoader(); + JavaVirtualMachine machine = null; + try { + machine = gcToolKit.analyze(log); + } catch (IOException e) { + fail(e.getMessage()); + } + Assertions.assertEquals( endStartTimes[0], (int)(machine.getEstimatedJVMStartTime().getTimeStamp() * 1000.0d)); + Assertions.assertEquals( endStartTimes[1], (int)(machine.getTimeOfFirstEvent().getTimeStamp() * 1000.0d)); + Assertions.assertEquals( endStartTimes[2], (int)(machine.getJVMTerminationTime().getTimeStamp() * 1000.0d)); + Assertions.assertEquals( endStartTimes[3], (int)(machine.getRuntimeDuration() * 1000.0d)); + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java index 4a5325f5..2def0c08 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java +++ b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java @@ -7,8 +7,13 @@ import com.microsoft.gctoolkit.io.GCLogFile; import com.microsoft.gctoolkit.io.RotatingGCLogFile; import com.microsoft.gctoolkit.io.SingleGCLogFile; +import com.microsoft.gctoolkit.jvm.Diary; import com.microsoft.gctoolkit.jvm.JavaVirtualMachine; +import com.microsoft.gctoolkit.message.DataSourceBus; +import com.microsoft.gctoolkit.message.JVMEventBus; +import com.microsoft.gctoolkit.message.DataSourceParser; +import java.io.IOException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.ServiceConfigurationError; @@ -30,13 +35,40 @@ public class GCToolKit { * @param logFile GCLogFile DataSource * @return JavaVirtualMachine implementation. */ - private static JavaVirtualMachine loadJavaVirtualMachine(GCLogFile logFile) { + private JavaVirtualMachine loadJavaVirtualMachine(GCLogFile logFile) { return ServiceLoader.load(JavaVirtualMachine.class) .stream() .map(ServiceLoader.Provider::get) .filter(jvm -> jvm.accepts(logFile)) .findFirst() - .orElseThrow(() -> new ServiceConfigurationError("No suitable service provider found")); + .orElseThrow(() -> new ServiceConfigurationError("No suitable JavaVirtualMachine implementation found")); + } + + private DataSourceBus setupDataSourceBus() { + return ServiceLoader.load(DataSourceBus.class) + .stream() + .map(ServiceLoader.Provider::get) + .findFirst() + .orElseThrow(() -> new ServiceConfigurationError("No suitable DataSourceBus implementation found")); + + } + + private JVMEventBus setupJVMEventBus() { + return ServiceLoader.load(JVMEventBus.class) + .stream() + .map(ServiceLoader.Provider::get) + .findFirst() + .orElseThrow(() -> new ServiceConfigurationError("No suitable JVMEventBus implementation found")); + + } + + private void registerParsers(DataSourceBus bus, Diary diary) { + ServiceLoader.load(DataSourceParser.class) + .stream() + .map(ServiceLoader.Provider::get) + .filter(p->p.accepts(diary)) + .forEach(parser->bus.register(parser)); + } private final Set> registeredAggregations; @@ -107,14 +139,17 @@ public void registerAggregation(Class aggregationClass) { * @return a representation of the state of the Java Virtual Machine resulting * from the analysis of the GC log file. */ - public JavaVirtualMachine analyze(GCLogFile logFile) { + public JavaVirtualMachine analyze(GCLogFile logFile) throws IOException { //todo: revert this to DataSource to account for non-GC log data sources once we have a use case (maybe JFR but JFR timers drift badly ATM) // Potential NPE, but would have logged if there was trouble creating the instance. + //setup message bus + //DataSourceBus dataSourceBus = setupDataSourceBus(); + //JVMEventBus eventBus = setupJVMEventBus(); + //registerParsers(dataSourceBus,logFile.diary()); JavaVirtualMachine javaVirtualMachine = loadJavaVirtualMachine(logFile); //todo: do we need reflection???? try { - Method analyze = javaVirtualMachine.getClass() - .getMethod("analyze", Set.class, DataSource.class); + Method analyze = javaVirtualMachine.getClass().getMethod("analyze", Set.class, DataSource.class); analyze.invoke(javaVirtualMachine, this.registeredAggregations, logFile); } catch (ReflectiveOperationException e) { LOGGER.log(Level.SEVERE, "Cannot invoke analyze method", e); diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/MalformedEvent.java b/api/src/main/java/com/microsoft/gctoolkit/event/MalformedEvent.java new file mode 100644 index 00000000..574ffbe1 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/event/MalformedEvent.java @@ -0,0 +1,7 @@ +package com.microsoft.gctoolkit.event; + +public class MalformedEvent extends Exception { + public MalformedEvent(String message) { + super(message); + } +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java index 4ddb8adf..3304ee4c 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java @@ -11,6 +11,7 @@ public interface Diarizer { String getCommandLine(); DateTimeStamp getTimeOfFirstEvent(); + DateTimeStamp getTimeOfLastEvent(); int getMaxTenuringThreshold(); diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java index af923ef1..6e79e5b8 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diary.java @@ -3,6 +3,7 @@ package com.microsoft.gctoolkit.jvm; import com.microsoft.gctoolkit.parser.datatype.TripleState; +import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.Arrays; @@ -45,6 +46,7 @@ public class Diary { private final TripleState[] states; + private DateTimeStamp timeOfFirstEvent; public Diary() { states = new TripleState[SupportedFlags.values().length]; @@ -366,4 +368,12 @@ public boolean isMaxTenuringThresholdViolationKnown() { public boolean isJVMEventsKnown() { return isApplicationStoppedTimeKnown() && isApplicationRunningTime(); } + + public void setTimeOfFirstEvent(DateTimeStamp startTime) { + if ( this.timeOfFirstEvent == null) + this.timeOfFirstEvent = startTime; + } + public DateTimeStamp getTimeOfFirstEvent() { + return this.timeOfFirstEvent; + } } 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 28b853f8..b72b55e4 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java @@ -10,6 +10,7 @@ import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.Optional; +import java.util.Set; /** * JavaVirtualMachine is a representation of the JVM state obtained by analyzing a GC log file. @@ -69,15 +70,21 @@ public interface JavaVirtualMachine { /** * Return the time of the first event in the GC log file. - * @return The time of the first event. + * @return The time of the last event. */ DateTimeStamp getTimeOfFirstEvent(); + /** + * Return the time of the first event in the GC log file. + * @return The time of the first event. + */ + DateTimeStamp getEstimatedJVMStartTime(); + /** * Return the time of the last event in the GC log file. * @return The time of the last event. */ - DateTimeStamp getTimeOfLastEvent(); + DateTimeStamp getJVMTerminationTime(); /** * Return the runtime duration. This is not necessarily the difference @@ -87,13 +94,6 @@ public interface JavaVirtualMachine { */ double getRuntimeDuration(); - /** - * Get the configuration metadata. This configuration data is either - * known from JVM flags, or inferred from parsing the GC log file. - * @return The {@code JvmConfiguration} - */ - JvmConfiguration getJvmConfiguration(); - /** * Return the {@code Aggregation} that was used in the analysis of the GC log file * that is the same class as {@code aggregationClass}. In other words, {@code aggregationClass} @@ -106,4 +106,5 @@ public interface JavaVirtualMachine { * if given aggregationClass is not available. */ Optional getAggregation(Class aggregationClass); + } \ No newline at end of file diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/JvmConfiguration.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/JvmConfiguration.java deleted file mode 100644 index 623c5dd3..00000000 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/JvmConfiguration.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -package com.microsoft.gctoolkit.jvm; - -import com.microsoft.gctoolkit.time.DateTimeStamp; - -/** - * The configuration of the Java Virtual Machine, calculated from the GC log analysis. - */ -public interface JvmConfiguration { - /** - * Was the JVM configured with {@code -XX:+PrintGCDetails}, or with {@code -Xlog:gc*}? - * @return {@code true} if the JVM was configured to print GC details. - */ - boolean isPrintGCDetails(); - - /** - * Was the JVM configured with {@code -XX:+PrintTenuringDistribution}, or with {@code -Xlog:gc+age*=trace} - * @return {@code true} if the JVM was configured to print tenuring distribution details. - */ - boolean isPrintTenuringDistribution(); - - /** - * Was the JVM configured with {@code -XX:+PrintGCApplicationConcurrentTime}, - * {@code -XX:+PrintGCApplicationConcurrentTime}, or with {@code -Xlog:safepoint}? - * @return {@code true} if the JVM was configured to log time spent in safepoints. - */ - boolean hasSafepointEvents(); - - /** - * Was the {@code MaxTenuringThreshold} garbage collection option set to a value greater than 15? Prior to - * Java version 1.5.0_06, the maximum value was 31. From version 1.5.0_06 on, a value greater than 15 means - * that objects never tenure, which is likely to cause heap fragmentation once survivor space is filled. - * The method {@link #getMaxTenuringThreshold()}} can be used to retrieve the value. - * @return {@code true} if {@code MaxTenuringThreshold} is set with a value greater than 15. - */ - boolean hasMaxTenuringThresholdViolation(); - - /** - * Get the value of the {@code MaxTenuringThreshold} garbage collection option. - * @return The value of the {@code MaxTenuringThreshold} garbage collection option. - */ - int getMaxTenuringThreshold(); - - /** - * Return {@code true} if the JDK version has been determined from parsing the log file. This method - * should be used in conjunction with {@link #isJDK70()}, {@link #isJDK80()}}, and {@link #isPreJDK17040()} - * to determine whether these methods return {@code false} because the parser could not determine the JDK version. - * @return {@code} true if the JDK version is known. - */ - boolean isJDKVersionKnown(); - - /** - * Is the version of Java 1.7 prior to 7u40? Up until 170_40, the only GC Cause printed was System.gc(), - * and only with +PrintGCDetails. - * @return {@code true} if the Java version is 1.7 prior to 7u40. - */ - boolean isPreJDK17040(); - - /** - * Is the version of Java 1.7 after, and including, 7u40? The {@code PrintGCCause} flag was added in 7u40, and - * was necessary to include {@code System.gc()}. - * @return {@code true} if the Java version is 1.7 after, and including, 7u40. - */ - boolean isJDK70(); - - /** - * Is the version of Java 1.8? In version 1.8, {@code PrintGCDetails} includes {@code System.gc()}. - * @return {@code true} if the version of Java is 1.8. - */ - boolean isJDK80(); - - /** - * Do the JVM arguments include {@code -XX:+PrintGCCause}? If {@link #isJDK70()} returns {@code true} and - * {@code containsGCCause()} returns {@code false}, then {@code System.gc()} calls are not being logged. - * @return {@code true} if the JVM is configured to print GC cause. - */ - boolean containsGCCause(); - - int MAXIMUM_LINES_TO_EXAMINE = 10_000; - - String getCommandLine(); - - DateTimeStamp getTimeOfFirstEvent(); - - boolean isUnified(); - - Diary getDiary(); - - boolean hasJVMEvents(); - - boolean completed(); - - void fillInKnowns(); - - boolean diarize(String line); - -} diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceBus.java b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceBus.java new file mode 100644 index 00000000..42e80f88 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceBus.java @@ -0,0 +1,9 @@ +package com.microsoft.gctoolkit.message; + +public interface DataSourceBus { + + void register(DataSourceParser parser); + void start(); + void stop(); + void publish(S data); +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java new file mode 100644 index 00000000..eb1511d2 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourceParser.java @@ -0,0 +1,9 @@ +package com.microsoft.gctoolkit.message; + +import com.microsoft.gctoolkit.jvm.Diary; + +public interface DataSourceParser { + + boolean accepts(Diary diary); + +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/DataSourcePublisher.java b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourcePublisher.java new file mode 100644 index 00000000..8ec9e32e --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/message/DataSourcePublisher.java @@ -0,0 +1,4 @@ +package com.microsoft.gctoolkit.message; + +public interface DataSourcePublisher { +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventBus.java b/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventBus.java new file mode 100644 index 00000000..099b628e --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventBus.java @@ -0,0 +1,16 @@ +package com.microsoft.gctoolkit.message; + +import com.microsoft.gctoolkit.aggregator.Aggregator; +import com.microsoft.gctoolkit.event.jvm.JVMEvent; + +import java.util.List; + +public interface JVMEventBus { + + void registerAggregators(List aggregators); + void registerAggregator(Aggregator aggregator); + void start(); + void stop(); + void publish(JVMEvent event); + +} diff --git a/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventPublisher.java b/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventPublisher.java new file mode 100644 index 00000000..ffb977b2 --- /dev/null +++ b/api/src/main/java/com/microsoft/gctoolkit/message/JVMEventPublisher.java @@ -0,0 +1,4 @@ +package com.microsoft.gctoolkit.message; + +public interface JVMEventPublisher { +} diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java index fb9d03dd..bdde98e0 100644 --- a/api/src/main/java/module-info.java +++ b/api/src/main/java/module-info.java @@ -43,4 +43,6 @@ uses com.microsoft.gctoolkit.aggregator.Aggregation; uses com.microsoft.gctoolkit.jvm.JavaVirtualMachine; uses com.microsoft.gctoolkit.jvm.Diarizer; + uses com.microsoft.gctoolkit.message.DataSourceBus; + uses com.microsoft.gctoolkit.message.JVMEventBus; } diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/G1GCForwardReference.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/G1GCForwardReference.java index ad2f0211..9c7486ce 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/G1GCForwardReference.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/G1GCForwardReference.java @@ -4,6 +4,7 @@ import com.microsoft.gctoolkit.event.GCCause; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; +import com.microsoft.gctoolkit.event.MalformedEvent; import com.microsoft.gctoolkit.event.MemoryPoolSummary; import com.microsoft.gctoolkit.event.ReferenceGCSummary; import com.microsoft.gctoolkit.event.SurvivorMemoryPoolSummary; @@ -660,10 +661,9 @@ G1GCConcurrentEvent buildConcurrentUndoCycleEvent() { * gcType == null -> likely an incomplete record. * @return */ - G1GCPauseEvent buildEvent() { + G1GCPauseEvent buildEvent() throws MalformedEvent { if (gcType == null ) { - LOGGER.warning("GC Event is undefined (null)"); - throw new IllegalStateException("G1GC Event type is undefined (null): " + this.toString()); + throw new MalformedEvent("G1GC Event type is undefined (null): " + this.toString()); } switch (this.gcType) { case Young: @@ -681,9 +681,8 @@ G1GCPauseEvent buildEvent() { case G1GCCleanup: return buildCleanup(); default: - LOGGER.warning("Unrecognized (mostly) Concurrent Cycle Pause Event " + getConcurrentPhase()); + throw new MalformedEvent("Unrecognized (mostly) Concurrent Cycle Pause Event " + getConcurrentPhase()); } - return null; case G1GCConcurrentUndoCycle: // gctype is likely incorrectly set in the forward reference. The plan is to specialize the forward // references thus allowing this event to be built here rather than in a specialized method. @@ -691,8 +690,7 @@ G1GCPauseEvent buildEvent() { // filled in a future PR. return null; default: - LOGGER.warning("Unrecognized Event " + gcType); - return null; + throw new MalformedEvent("Unrecognized Event " + gcType); } } 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 6efe47b3..02d55351 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/UnifiedG1GCParser.java @@ -4,6 +4,7 @@ import com.microsoft.gctoolkit.event.CPUSummary; import com.microsoft.gctoolkit.event.GarbageCollectionTypes; +import com.microsoft.gctoolkit.event.MalformedEvent; import com.microsoft.gctoolkit.event.MemoryPoolSummary; import com.microsoft.gctoolkit.event.RegionSummary; import com.microsoft.gctoolkit.event.g1gc.G1ConcurrentUndoCycle; @@ -208,10 +209,14 @@ private void noop(GCLogTrace trace, String line) {} private void cpuBreakout(GCLogTrace trace, String line) { CPUSummary cpuSummary = new CPUSummary(trace.getDoubleGroup(1), trace.getDoubleGroup(2), trace.getDoubleGroup(3)); forwardReference.setCPUSummary(cpuSummary); - if (! forwardReference.isConcurrentCycle()) - record(forwardReference.buildEvent()); - else - recordPausePhaseInConcurrentCycle(forwardReference.buildEvent()); + try { + if (!forwardReference.isConcurrentCycle()) + record(forwardReference.buildEvent()); + else + recordPausePhaseInConcurrentCycle(forwardReference.buildEvent()); + } catch (MalformedEvent malformedEvent) { + LOGGER.warning(malformedEvent.getMessage()); + } } // todo: need to drain the queues before terminating... diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java index 96ef5f61..090655f1 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java @@ -233,6 +233,11 @@ public DateTimeStamp getTimeOfFirstEvent() { return timeOfFirstEvent; } + @Override + public DateTimeStamp getTimeOfLastEvent() { + return null; + } + private void timeOfFirstEvent(String line) { if (timeOfFirstEvent == null) { Matcher matcher = excludeG1Ergonomics.matcher(line); diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java index 3a13ae76..6c391bcc 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java @@ -29,7 +29,6 @@ public class UnifiedDiarizer implements Diarizer { private final Diary diary; private final TreeSet tagsAndLevels = new TreeSet<>(); - private DateTimeStamp startTime = null; private int stopTheWorldEvents = 0; { @@ -149,10 +148,7 @@ else if (decorators.tagsContain("gc") && line.contains("Trigger")) } private void timeOfFirstEvent(Decorators decorator) { - if (startTime == null) { - startTime = decorator.getDateTimeStamp(); - } - + diary.setTimeOfFirstEvent(decorator.getDateTimeStamp()); } private void extractTagsAndLevels(Decorators decorators) { @@ -240,6 +236,11 @@ private void discoverJVMEvents(String line) { @Override public DateTimeStamp getTimeOfFirstEvent() { - return startTime; + return getDiary().getTimeOfFirstEvent(); + } + + @Override + public DateTimeStamp getTimeOfLastEvent() { + return null; } } \ No newline at end of file diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/GCToolkitVertx.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/GCToolkitVertx.java index d6a806c1..8eb8ae14 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/GCToolkitVertx.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/GCToolkitVertx.java @@ -64,11 +64,7 @@ private GCToolkitVertx(String mailBox) { * @return The runtime duration * @throws IOException If an IOException is thrown while reading the DataSource */ - public static DateTimeStamp aggregateDataSource( - DataSource dataSource, - Set logFileParsers, - Set aggregatorVerticles, - String mailBox) throws IOException { + public static DateTimeStamp aggregateDataSource(DataSource dataSource, Set logFileParsers, Set aggregatorVerticles, String mailBox) throws IOException { //remove AggregatorVerticle which can not match by the LogFileParser to prevent dead loop aggregatorVerticles.removeIf(aggregatorVerticle->{ boolean isMatch = logFileParsers.stream().map(LogFileParser::getOutbox) @@ -78,25 +74,25 @@ public static DateTimeStamp aggregateDataSource( return !isMatch; }); - GCToolkitVertx GCToolkitVertx = new GCToolkitVertx(mailBox); + GCToolkitVertx gcToolkitVertx = new GCToolkitVertx(mailBox); JVMEventSource jvmEventSource = new JVMEventSource(PARSER_INBOX); - GCToolkitVertx.deployVerticle(jvmEventSource); + gcToolkitVertx.deployVerticle(jvmEventSource); jvmEventSource.awaitDeployment(); - GCToolkitVertx.deployVerticle(GCToolkitVertx); + gcToolkitVertx.deployVerticle(gcToolkitVertx); - logFileParsers.forEach(logFileParser -> GCToolkitVertx.deployVerticle(logFileParser, new DeploymentOptions().setWorker(true))); + logFileParsers.forEach(logFileParser -> gcToolkitVertx.deployVerticle(logFileParser, new DeploymentOptions().setWorker(true))); logFileParsers.forEach(LogFileParser::awaitDeployment); - aggregatorVerticles.forEach(GCToolkitVertx::deployVerticle); + aggregatorVerticles.forEach(gcToolkitVertx::deployVerticle); aggregatorVerticles.forEach(AggregatorVerticle::awaitDeployment); jvmEventSource.publishGCDataSource(dataSource); aggregatorVerticles.forEach(AggregatorVerticle::awaitCompletion); - GCToolkitVertx.shutdown(); + gcToolkitVertx.shutdown(); - return GCToolkitVertx.timeOfLastEvent; + return gcToolkitVertx.timeOfLastEvent; } private Future deployVerticle(Verticle verticle) { @@ -114,12 +110,12 @@ public void start() { consumer(mailBox, message -> { try { JVMEvent event = (JVMEvent) message.body(); - if (event instanceof JVMTermination) - return; DateTimeStamp now = event.getDateTimeStamp().add(event.getDuration()); if (now.after(timeOfLastEvent)) { timeOfLastEvent = now; } + if (event instanceof JVMTermination) + return; } catch (Throwable t) { LOGGER.throwing(this.getClass().getName(), "start", t); } diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/aggregator/AggregatorVerticle.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/aggregator/AggregatorVerticle.java index 57de3eaa..2b11b564 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/aggregator/AggregatorVerticle.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/aggregator/AggregatorVerticle.java @@ -5,12 +5,14 @@ import com.microsoft.gctoolkit.aggregator.Aggregation; import com.microsoft.gctoolkit.aggregator.Aggregator; import com.microsoft.gctoolkit.event.jvm.JVMEvent; +import com.microsoft.gctoolkit.event.jvm.JVMTermination; import com.microsoft.gctoolkit.time.DateTimeStamp; import com.microsoft.gctoolkit.vertx.internal.util.concurrent.StartingGun; import io.vertx.core.AbstractVerticle; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; @@ -60,7 +62,7 @@ public void onCompletion(Runnable runnable) { private final StartingGun deployed = new StartingGun(); private final StartingGun completion = new StartingGun(); - private DateTimeStamp timeOfTerminationEvent; + private volatile DateTimeStamp timeOfTerminationEvent; private final String inbox; @@ -112,18 +114,16 @@ public void awaitDeployment() { deployed.awaitUninterruptibly(); } + /* + we need some check on the state of the consumer... + */ public DateTimeStamp awaitCompletion() { completion.awaitUninterruptibly(); return timeOfTerminationEvent; } private void monitorForTermination() { - AtomicInteger counter = new AtomicInteger(aggregators.size()); - aggregators.forEach(aggregator -> ((AggregatorWrapper)aggregator).onCompletion(() -> { - if ( counter.decrementAndGet() == 0) { - completion.ready(); - } - })); + Executors.newSingleThreadExecutor().execute(() -> completion.awaitUninterruptibly()); } @Override @@ -134,8 +134,11 @@ public void start() { consumer(inbox, message -> { try { JVMEvent event = message.body(); - timeOfTerminationEvent = event.getDateTimeStamp(); this.record(event); + if ( event instanceof JVMTermination) { + timeOfTerminationEvent = event.getDateTimeStamp(); + completion.ready(); + } } catch (Throwable t) { LOGGER.throwing(this.getClass().getName(), "start", t); } @@ -145,4 +148,6 @@ public void start() { LOGGER.throwing(this.getClass().getName(), "start", t); } } + + } diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java index 05edc5b9..3f01e399 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java @@ -5,16 +5,13 @@ import com.microsoft.gctoolkit.aggregator.Aggregation; import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.io.GCLogFile; -import com.microsoft.gctoolkit.jvm.Diarizer; +import com.microsoft.gctoolkit.jvm.Diary; import com.microsoft.gctoolkit.jvm.JavaVirtualMachine; -import com.microsoft.gctoolkit.jvm.JvmConfiguration; -import com.microsoft.gctoolkit.parser.jvm.UnifiedDiarizer; import com.microsoft.gctoolkit.time.DateTimeStamp; import com.microsoft.gctoolkit.vertx.GCToolkitVertx; import java.io.IOException; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -32,67 +29,95 @@ public abstract class AbstractJavaVirtualMachine implements JavaVirtualMachine { private static final Logger LOGGER = Logger.getLogger(AbstractJavaVirtualMachine.class.getName()); - private static final double LOG_FRAGMENT_THRESHOLD = 18000; + private static final double LOG_FRAGMENT_THRESHOLD = 60.0d; - private Diarizer jvmConfigurationFromParser; - private JvmConfiguration jvmConfigurationForCoreApi; + private Diary diary; private DateTimeStamp timeOfLastEvent; private final Map, Aggregation> aggregatedData = new ConcurrentHashMap<>(); @Override public boolean isG1GC() { - return jvmConfigurationFromParser.getDiary().isG1GC(); + return diary.isG1GC(); } @Override public boolean isZGC() { - return jvmConfigurationFromParser.getDiary().isZGC(); + return diary.isZGC(); } @Override public boolean isShenandoah() { - return jvmConfigurationFromParser.getDiary().isShenandoah(); + return diary.isShenandoah(); } @Override public boolean isParallel() { - return jvmConfigurationFromParser.getDiary().isParNew(); + return diary.isParNew(); } @Override public boolean isSerial() { - return jvmConfigurationFromParser.getDiary().isSerialFull(); + return diary.isSerialFull(); } @Override public boolean isCMS() { - return jvmConfigurationFromParser.getDiary().isCMS(); + return diary.isCMS(); } @Override public String getCommandLine() { - return jvmConfigurationFromParser.getCommandLine(); + return ""; //todo: extract from diary... jvmConfigurationFromParser.getCommandLine(); } + /** + * of the first event is significantly away from zero in relation to the time intervals between the + * of the next N events, where N maybe 1. + * + * try to estimate the time at which the JVM started. For log fragments, this will be the time + * of the first event in the log. Otherwise it will be 0.000 seconds. + * @return DateTimeStamp + */ + @Override + public DateTimeStamp getEstimatedJVMStartTime() { + DateTimeStamp startTime = getTimeOfFirstEvent(); + // Initial entries in GC log happen within seconds. Lets allow for 60 before considering the log + // to be a fragment. + if (startTime.getTimeStamp() < LOG_FRAGMENT_THRESHOLD) { + return startTime.minus(startTime.getTimeStamp()); + } else { + return startTime; + } + } + + /** + * todo: fix this to be a globally available value. Also, the JVM start time is not zero if the time + * of the first event is significantly away from zero in relation to the time intervals between the + * of the next N events, where N maybe 1. + * + * try to estimate the time at which the JVM started. For log fragments, this will be the time + * of the first event in the log. Otherwise it will be 0.000 seconds. + * @return DateTimeStamp + */ @Override public DateTimeStamp getTimeOfFirstEvent() { - return jvmConfigurationFromParser.getTimeOfFirstEvent(); + return diary.getTimeOfFirstEvent(); } + /** + * JVM termination time will be one of either, the time stamp in the termination event if present or, the + * time of the last event + that events duration. + * @return DateTimeStamp + */ @Override - public DateTimeStamp getTimeOfLastEvent() { - if (getTimeOfFirstEvent().before(timeOfLastEvent)) - return timeOfLastEvent; - else - return getTimeOfFirstEvent(); + public DateTimeStamp getJVMTerminationTime() { + return timeOfLastEvent; } @Override public double getRuntimeDuration() { - boolean isLogFragment = getTimeOfFirstEvent().getTimeStamp() > LOG_FRAGMENT_THRESHOLD; - if (isLogFragment) - return getTimeOfLastEvent().minus(getTimeOfFirstEvent()); - return getTimeOfLastEvent().getTimeStamp(); } + return getJVMTerminationTime().minus(getEstimatedJVMStartTime()); + } @Override @SuppressWarnings("unchecked") @@ -100,27 +125,16 @@ public Optional getAggregation(Class aggregationCl return Optional.ofNullable((T) aggregatedData.get(aggregationClass)); } - @Override - public JvmConfiguration getJvmConfiguration() { //todo: why???? - return jvmConfigurationForCoreApi; - } + abstract GCToolkitVertxParameters getParameters(Set> registeredAggregations, Diary diary); // Invoked reflectively from GCToolKit public void analyze(Set> registeredAggregations, DataSource dataSource) { try { final GCLogFile gcLogFile = (GCLogFile) dataSource; + this.diary = gcLogFile.diary(); - this.jvmConfigurationFromParser = new UnifiedDiarizer(); - - gcLogFile.stream() - .map(this.jvmConfigurationFromParser::diarize) - .filter(Boolean::booleanValue) - .findFirst(); - - this.jvmConfigurationFromParser.fillInKnowns(); - - GCToolkitVertxParameters GCToolkitVertxParameters = new GCToolkitVertxParametersForUnifiedLogs(registeredAggregations, gcLogFile.diary()); + GCToolkitVertxParameters GCToolkitVertxParameters = getParameters(registeredAggregations, gcLogFile.diary()); this.timeOfLastEvent = GCToolkitVertx.aggregateDataSource( dataSource, @@ -136,10 +150,6 @@ public void analyze(Set> registeredAggregations, Da this.aggregatedData.put(aggregation.getClass(), aggregation); }); - - this.jvmConfigurationForCoreApi = new JvmConfigurationImpl(gcLogFile.diary()); - - } catch (IOException | ClassCastException e ) { LOGGER.log(Level.WARNING, e.getMessage(), e); } diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/GCToolkitVertxParametersForPreUnifiedLogs.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/GCToolkitVertxParametersForPreUnifiedLogs.java index 3c9bf55c..eabc2eb9 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/GCToolkitVertxParametersForPreUnifiedLogs.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/GCToolkitVertxParametersForPreUnifiedLogs.java @@ -25,10 +25,7 @@ private final Set aggregatorVerticles; private final String mailBox; - /* package */ GCToolkitVertxParametersForPreUnifiedLogs( - Set> registeredAggregations, - Diary diary) - { + /* package */ GCToolkitVertxParametersForPreUnifiedLogs( Set> registeredAggregations, Diary diary) { logFileParsers = initLogFileParsers(diary); aggregatorVerticles = initAggregatorVerticles(registeredAggregations, diary); mailBox = initMailBox(diary); diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/JvmConfigurationImpl.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/JvmConfigurationImpl.java deleted file mode 100644 index e2e05126..00000000 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/JvmConfigurationImpl.java +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -package com.microsoft.gctoolkit.vertx.jvm; - -import com.microsoft.gctoolkit.jvm.Diary; -import com.microsoft.gctoolkit.time.DateTimeStamp; - -/* package scope */ class JvmConfigurationImpl implements com.microsoft.gctoolkit.jvm.JvmConfiguration { - - private final Diary diary; - /* package scope */ - JvmConfigurationImpl(Diary diary) { - this.diary = diary; - } - - @Override - public boolean isPrintGCDetails() { - return diary.isPrintGCDetails(); - } - - @Override - public boolean isPrintTenuringDistribution() { - return diary.isTenuringDistribution(); - } - - @Override - public boolean hasSafepointEvents() { - return diary.isApplicationStoppedTime() || diary.isApplicationRunningTime(); - } - - @Override - public boolean hasMaxTenuringThresholdViolation() { - return diary.isMaxTenuringThresholdViolation(); - } - - @Override - public int getMaxTenuringThreshold() { - return 0; //diary.getMaxTenuringThreshold(); todo: add in command line values. - } - - @Override - public boolean isPreJDK17040() { - return diary.isPre70_40(); - } - - @Override - public boolean isJDK70() { - return diary.isJDK70(); - } - - @Override - public boolean isJDK80() { - return diary.isJDK80(); - } - - @Override - public boolean containsGCCause() { - return diary.isGCCause(); - } - - @Override - public String getCommandLine() { - return null; - } - - @Override - public DateTimeStamp getTimeOfFirstEvent() { - return null; - } - - @Override - public boolean isUnified() { - return false; - } - - @Override - public Diary getDiary() { - return null; - } - - @Override - public boolean hasJVMEvents() { - return false; - } - - @Override - public boolean completed() { - return false; - } - - @Override - public void fillInKnowns() { - - } - - @Override - public boolean diarize(String line) { - return false; - } - - @Override - public boolean isJDKVersionKnown() { return diary.isVersionKnown(); } -} diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/PreUnifiedJavaVirtualMachine.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/PreUnifiedJavaVirtualMachine.java index 77cb9369..a515c643 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/PreUnifiedJavaVirtualMachine.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/PreUnifiedJavaVirtualMachine.java @@ -3,23 +3,11 @@ package com.microsoft.gctoolkit.vertx.jvm; import com.microsoft.gctoolkit.aggregator.Aggregation; -import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.io.GCLogFile; -import com.microsoft.gctoolkit.jvm.Diarizer; -import com.microsoft.gctoolkit.jvm.JavaVirtualMachine; -import com.microsoft.gctoolkit.jvm.JvmConfiguration; -import com.microsoft.gctoolkit.parser.jvm.PreUnifiedDiarizer; -import com.microsoft.gctoolkit.parser.jvm.UnifiedDiarizer; +import com.microsoft.gctoolkit.jvm.Diary; import com.microsoft.gctoolkit.time.DateTimeStamp; -import com.microsoft.gctoolkit.vertx.GCToolkitVertx; -import java.io.IOException; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -33,126 +21,24 @@ public class PreUnifiedJavaVirtualMachine extends AbstractJavaVirtualMachine { private static final Logger LOGGER = Logger.getLogger(PreUnifiedJavaVirtualMachine.class.getName()); - private static final double LOG_FRAGMENT_THRESHOLD = 18000; - - private Diarizer jvmConfigurationFromParser; - private JvmConfiguration jvmConfigurationForCoreApi; - private DateTimeStamp timeOfLastEvent; - private final Map, Aggregation> aggregatedData = - new ConcurrentHashMap<>(); - @Override public boolean accepts(GCLogFile logFile) { return ! logFile.isUnified(); } @Override - public boolean isG1GC() { - return jvmConfigurationFromParser.getDiary().isG1GC(); + GCToolkitVertxParameters getParameters(Set> registeredAggregations, Diary diary) { + return new GCToolkitVertxParametersForPreUnifiedLogs(registeredAggregations, diary); } @Override public boolean isZGC() { - return jvmConfigurationFromParser.getDiary().isZGC(); + return false; } @Override public boolean isShenandoah() { - return jvmConfigurationFromParser.getDiary().isShenandoah(); - } - - @Override - public boolean isParallel() { - return jvmConfigurationFromParser.getDiary().isParNew(); - } - - @Override - public boolean isSerial() { - return jvmConfigurationFromParser.getDiary().isSerialFull(); - } - - @Override - public boolean isCMS() { - return jvmConfigurationFromParser.getDiary().isCMS(); - } - - @Override - public String getCommandLine() { - return jvmConfigurationFromParser.getCommandLine(); - } - - @Override - public DateTimeStamp getTimeOfFirstEvent() { - return jvmConfigurationFromParser.getTimeOfFirstEvent(); - } - - @Override - public DateTimeStamp getTimeOfLastEvent() { - if (getTimeOfFirstEvent().before(timeOfLastEvent)) - return timeOfLastEvent; - else - return getTimeOfFirstEvent(); + return false; } - @Override - public double getRuntimeDuration() { - boolean isLogFragment = getTimeOfFirstEvent().getTimeStamp() > LOG_FRAGMENT_THRESHOLD; - if (isLogFragment) - return getTimeOfLastEvent().minus(getTimeOfFirstEvent()); - return getTimeOfLastEvent().getTimeStamp(); } - - @Override - @SuppressWarnings("unchecked") - public Optional getAggregation(Class aggregationClass) { - return Optional.ofNullable((T) aggregatedData.get(aggregationClass)); - } - - @Override - public JvmConfiguration getJvmConfiguration() { - return jvmConfigurationForCoreApi; - } - - // Invoked reflectively from GCToolKit - public void analyze(Set> registeredAggregations, DataSource dataSource) { - - try { - final GCLogFile gcLogFile = (GCLogFile) dataSource; - - this.jvmConfigurationFromParser = gcLogFile.isUnified() - ? new UnifiedDiarizer() - : new PreUnifiedDiarizer(); - - gcLogFile.stream(). - map(this.jvmConfigurationFromParser::diarize) - .filter(Boolean::booleanValue) - .findFirst(); - - this.jvmConfigurationFromParser.fillInKnowns(); - - GCToolkitVertxParameters GCToolkitVertxParameters = gcLogFile.isUnified() - ? new GCToolkitVertxParametersForUnifiedLogs(registeredAggregations, gcLogFile.diary()) - : new GCToolkitVertxParametersForPreUnifiedLogs(registeredAggregations, gcLogFile.diary()); - - this.timeOfLastEvent = GCToolkitVertx.aggregateDataSource( - dataSource, - GCToolkitVertxParameters.logFileParsers(), - GCToolkitVertxParameters.aggregatorVerticles(), - GCToolkitVertxParameters.mailBox() - ); - - GCToolkitVertxParameters.aggregatorVerticles().stream() - .flatMap(aggregatorVerticle -> aggregatorVerticle.aggregators().stream()) - .forEach(aggregator -> { - Aggregation aggregation = aggregator.aggregation(); - this.aggregatedData.put(aggregation.getClass(), aggregation); - }); - - - this.jvmConfigurationForCoreApi = new JvmConfigurationImpl(gcLogFile.diary()); - - - } catch (IOException | ClassCastException e ) { - LOGGER.log(Level.WARNING, e.getMessage(), e); - } - } } diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/UnifiedJavaVirtualMachine.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/UnifiedJavaVirtualMachine.java index 5e71ae2e..9d1936ab 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/UnifiedJavaVirtualMachine.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/UnifiedJavaVirtualMachine.java @@ -3,20 +3,10 @@ package com.microsoft.gctoolkit.vertx.jvm; import com.microsoft.gctoolkit.aggregator.Aggregation; -import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.io.GCLogFile; import com.microsoft.gctoolkit.jvm.Diary; -import com.microsoft.gctoolkit.jvm.JavaVirtualMachine; -import com.microsoft.gctoolkit.jvm.JvmConfiguration; -import com.microsoft.gctoolkit.time.DateTimeStamp; -import com.microsoft.gctoolkit.vertx.GCToolkitVertx; -import java.io.IOException; -import java.util.Map; -import java.util.Optional; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -30,113 +20,14 @@ public class UnifiedJavaVirtualMachine extends AbstractJavaVirtualMachine { private static final Logger LOGGER = Logger.getLogger(UnifiedJavaVirtualMachine.class.getName()); - private static final double LOG_FRAGMENT_THRESHOLD = 18000; - private Diary diary; - private JvmConfiguration jvmConfigurationForCoreApi; - private DateTimeStamp timeOfLastEvent; - private final Map, Aggregation> aggregatedData = - new ConcurrentHashMap<>(); - @Override public boolean accepts(GCLogFile logFile) { return logFile.isUnified(); } @Override - public boolean isG1GC() { - return diary.isG1GC(); - } - - @Override - public boolean isZGC() { - return diary.isZGC(); - } - - @Override - public boolean isShenandoah() { - return diary.isShenandoah(); - } - - @Override - public boolean isParallel() { - return diary.isParNew(); - } - - @Override - public boolean isSerial() { - return diary.isSerialFull(); - } - - @Override - public boolean isCMS() { - return diary.isCMS(); - } - - @Override - public String getCommandLine() { - return null; //diary.getCommandLine(); - } - - @Override - public DateTimeStamp getTimeOfFirstEvent() { - return new DateTimeStamp(0.0d); //diary.getTimeOfFirstEvent(); - } - - @Override - public DateTimeStamp getTimeOfLastEvent() { - if (getTimeOfFirstEvent().before(timeOfLastEvent)) - return timeOfLastEvent; - else - return getTimeOfFirstEvent(); + GCToolkitVertxParameters getParameters(Set> registeredAggregations, Diary diary) { + return new GCToolkitVertxParametersForUnifiedLogs(registeredAggregations, diary); } - @Override - public double getRuntimeDuration() { - boolean isLogFragment = getTimeOfFirstEvent().getTimeStamp() > LOG_FRAGMENT_THRESHOLD; - if (isLogFragment) - return getTimeOfLastEvent().minus(getTimeOfFirstEvent()); - return getTimeOfLastEvent().getTimeStamp(); } - - @Override - @SuppressWarnings("unchecked") - public Optional getAggregation(Class aggregationClass) { - return Optional.ofNullable((T) aggregatedData.get(aggregationClass)); - } - - @Override - public JvmConfiguration getJvmConfiguration() { - return jvmConfigurationForCoreApi; - } - - // Invoked reflectively from GCToolKit - public void analyze(Set> registeredAggregations, DataSource dataSource) { - - try { - final GCLogFile gcLogFile = (GCLogFile) dataSource; - this.diary = gcLogFile.diary(); - - GCToolkitVertxParameters GCToolkitVertxParameters = new GCToolkitVertxParametersForUnifiedLogs(registeredAggregations, this.diary); - - this.timeOfLastEvent = GCToolkitVertx.aggregateDataSource( - dataSource, - GCToolkitVertxParameters.logFileParsers(), - GCToolkitVertxParameters.aggregatorVerticles(), - GCToolkitVertxParameters.mailBox() - ); - - GCToolkitVertxParameters.aggregatorVerticles().stream() - .flatMap(aggregatorVerticle -> aggregatorVerticle.aggregators().stream()) - .forEach(aggregator -> { - Aggregation aggregation = aggregator.aggregation(); - this.aggregatedData.put(aggregation.getClass(), aggregation); - }); - - - this.jvmConfigurationForCoreApi = new JvmConfigurationImpl(diary); - - - } catch (IOException | ClassCastException e ) { - LOGGER.log(Level.WARNING, e.getMessage(), e); - } - } } From 6ca506d948ef3cfbeb5841ab855d7e02eb08fab6 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Thu, 3 Feb 2022 15:46:44 -0800 Subject: [PATCH 04/11] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..2f446d32 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '32 17 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 0dbbac2e4806be82b5e56060025809339a9db54a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 4 Feb 2022 20:04:18 +0000 Subject: [PATCH 05/11] [maven-release-plugin] prepare release gctoolkit-2.0.6 --- IT/pom.xml | 4 ++-- api/pom.xml | 2 +- gclogs/pom.xml | 2 +- parser/pom.xml | 2 +- pom.xml | 4 ++-- sample/pom.xml | 2 +- vertx/pom.xml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/IT/pom.xml b/IT/pom.xml index 4f3c03da..bf0bb75a 100644 --- a/IT/pom.xml +++ b/IT/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml @@ -44,7 +44,7 @@ com.microsoft.gctoolkit gctoolkit-sample - 2.0.6-SNAPSHOT + 2.0.6 test diff --git a/api/pom.xml b/api/pom.xml index 1161809d..9700c427 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml diff --git a/gclogs/pom.xml b/gclogs/pom.xml index 3edc9d27..9280d795 100644 --- a/gclogs/pom.xml +++ b/gclogs/pom.xml @@ -6,7 +6,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml diff --git a/parser/pom.xml b/parser/pom.xml index 76a8f263..3f50da1f 100644 --- a/parser/pom.xml +++ b/parser/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml diff --git a/pom.xml b/pom.xml index fa018554..56195b11 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit pom - 2.0.6-SNAPSHOT + 2.0.6 GCToolKit GC log parsing utilities @@ -28,7 +28,7 @@ scm:git:${repository.url} scm:git:${repository.url} ${repository.url} - gctoolkit-2.0.5 + gctoolkit-2.0.6 diff --git a/sample/pom.xml b/sample/pom.xml index 6b7c9e4e..6c5221b5 100644 --- a/sample/pom.xml +++ b/sample/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml diff --git a/vertx/pom.xml b/vertx/pom.xml index 6fcd454b..9d5742b2 100644 --- a/vertx/pom.xml +++ b/vertx/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6-SNAPSHOT + 2.0.6 ../pom.xml From 4c4d0c41e72e68a504f76db856c8aa37d8850828 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 4 Feb 2022 20:04:19 +0000 Subject: [PATCH 06/11] [maven-release-plugin] prepare for next development iteration --- IT/pom.xml | 4 ++-- api/pom.xml | 2 +- gclogs/pom.xml | 2 +- parser/pom.xml | 2 +- pom.xml | 4 ++-- sample/pom.xml | 2 +- vertx/pom.xml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/IT/pom.xml b/IT/pom.xml index bf0bb75a..992354a5 100644 --- a/IT/pom.xml +++ b/IT/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml @@ -44,7 +44,7 @@ com.microsoft.gctoolkit gctoolkit-sample - 2.0.6 + 2.0.7-SNAPSHOT test diff --git a/api/pom.xml b/api/pom.xml index 9700c427..61eb09c0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml diff --git a/gclogs/pom.xml b/gclogs/pom.xml index 9280d795..b0dd7fc0 100644 --- a/gclogs/pom.xml +++ b/gclogs/pom.xml @@ -6,7 +6,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml diff --git a/parser/pom.xml b/parser/pom.xml index 3f50da1f..9a074187 100644 --- a/parser/pom.xml +++ b/parser/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 56195b11..40e3a21b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit pom - 2.0.6 + 2.0.7-SNAPSHOT GCToolKit GC log parsing utilities @@ -28,7 +28,7 @@ scm:git:${repository.url} scm:git:${repository.url} ${repository.url} - gctoolkit-2.0.6 + gctoolkit-2.0.5 diff --git a/sample/pom.xml b/sample/pom.xml index 6c5221b5..db298f51 100644 --- a/sample/pom.xml +++ b/sample/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml diff --git a/vertx/pom.xml b/vertx/pom.xml index 9d5742b2..67c82c20 100644 --- a/vertx/pom.xml +++ b/vertx/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.6 + 2.0.7-SNAPSHOT ../pom.xml From c0516533aa3c9fd83db3cffca7d0c7701201edc6 Mon Sep 17 00:00:00 2001 From: Kirk Pepperdine <74371364+kirk-microsoft@users.noreply.github.com> Date: Mon, 7 Feb 2022 16:28:00 -0800 Subject: [PATCH 07/11] Datetime (#206) * refactoring of JavaVirtualMachine * fix: DateTimeStamp is being reported incorrectly * refactor: reorganize IT module to better support tests * refactor: pick up modified files * fix: return correct time of log termination * refactor: more pre-release cleanup --- IT/src/main/java/module-info.java | 3 --- .../main/java/com/microsoft/gctoolkit/GCToolKit.java | 1 - .../java/com/microsoft/gctoolkit/jvm/Diarizer.java | 1 - .../microsoft/gctoolkit/jvm/JavaVirtualMachine.java | 5 ++--- .../gctoolkit/parser/jvm/PreUnifiedDiarizer.java | 5 ----- .../gctoolkit/parser/jvm/UnifiedDiarizer.java | 4 ---- .../vertx/jvm/AbstractJavaVirtualMachine.java | 10 +++++++--- 7 files changed, 9 insertions(+), 20 deletions(-) diff --git a/IT/src/main/java/module-info.java b/IT/src/main/java/module-info.java index 9557429d..23967659 100644 --- a/IT/src/main/java/module-info.java +++ b/IT/src/main/java/module-info.java @@ -11,9 +11,6 @@ requires com.microsoft.gctoolkit.vertx; requires java.logging; -// exports com.microsoft.gctoolkit.integration.aggregation; -// exports com.microsoft.gctoolkit.integration.collections; - exports com.microsoft.gctoolkit.integration.aggregation to com.microsoft.gctoolkit.vertx; diff --git a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java index 2def0c08..9aea4d32 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java +++ b/api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java @@ -141,7 +141,6 @@ public void registerAggregation(Class aggregationClass) { */ public JavaVirtualMachine analyze(GCLogFile logFile) throws IOException { //todo: revert this to DataSource to account for non-GC log data sources once we have a use case (maybe JFR but JFR timers drift badly ATM) - // Potential NPE, but would have logged if there was trouble creating the instance. //setup message bus //DataSourceBus dataSourceBus = setupDataSourceBus(); //JVMEventBus eventBus = setupJVMEventBus(); diff --git a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java index 3304ee4c..4ddb8adf 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/Diarizer.java @@ -11,7 +11,6 @@ public interface Diarizer { String getCommandLine(); DateTimeStamp getTimeOfFirstEvent(); - DateTimeStamp getTimeOfLastEvent(); int getMaxTenuringThreshold(); 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 b72b55e4..8da0d410 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java +++ b/api/src/main/java/com/microsoft/gctoolkit/jvm/JavaVirtualMachine.java @@ -5,12 +5,10 @@ import com.microsoft.gctoolkit.GCToolKit; import com.microsoft.gctoolkit.aggregator.Aggregation; -import com.microsoft.gctoolkit.io.DataSource; import com.microsoft.gctoolkit.io.GCLogFile; import com.microsoft.gctoolkit.time.DateTimeStamp; import java.util.Optional; -import java.util.Set; /** * JavaVirtualMachine is a representation of the JVM state obtained by analyzing a GC log file. @@ -75,7 +73,8 @@ public interface JavaVirtualMachine { DateTimeStamp getTimeOfFirstEvent(); /** - * Return the time of the first event in the GC log file. + * Estimates the initial start time of the log in the case that the log + * is determined to be a fragment. Otherwise, return a start time of 0.000 seconds * @return The time of the first event. */ DateTimeStamp getEstimatedJVMStartTime(); diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java index 090655f1..96ef5f61 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/PreUnifiedDiarizer.java @@ -233,11 +233,6 @@ public DateTimeStamp getTimeOfFirstEvent() { return timeOfFirstEvent; } - @Override - public DateTimeStamp getTimeOfLastEvent() { - return null; - } - private void timeOfFirstEvent(String line) { if (timeOfFirstEvent == null) { Matcher matcher = excludeG1Ergonomics.matcher(line); diff --git a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java index 6c391bcc..c64c5cad 100644 --- a/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java +++ b/parser/src/main/java/com/microsoft/gctoolkit/parser/jvm/UnifiedDiarizer.java @@ -239,8 +239,4 @@ public DateTimeStamp getTimeOfFirstEvent() { return getDiary().getTimeOfFirstEvent(); } - @Override - public DateTimeStamp getTimeOfLastEvent() { - return null; - } } \ No newline at end of file diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java index 3f01e399..1eb6237f 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java @@ -28,8 +28,7 @@ public abstract class AbstractJavaVirtualMachine implements JavaVirtualMachine { private static final Logger LOGGER = Logger.getLogger(AbstractJavaVirtualMachine.class.getName()); - - private static final double LOG_FRAGMENT_THRESHOLD = 60.0d; + private static final double LOG_FRAGMENT_THRESHOLD_SECONDS = 60.0d; //todo: replace magic threshold with a heuristic private Diary diary; private DateTimeStamp timeOfLastEvent; @@ -71,8 +70,13 @@ public String getCommandLine() { } /** +<<<<<<< HEAD + * If the first event is significantly distant from zero in relation to the time intervals between the + * of the next N events, where N maybe 1, then this is likely a log fragment and not the start of the run. +======= * of the first event is significantly away from zero in relation to the time intervals between the * of the next N events, where N maybe 1. +>>>>>>> 4c4d0c41e72e68a504f76db856c8aa37d8850828 * * try to estimate the time at which the JVM started. For log fragments, this will be the time * of the first event in the log. Otherwise it will be 0.000 seconds. @@ -83,7 +87,7 @@ public DateTimeStamp getEstimatedJVMStartTime() { DateTimeStamp startTime = getTimeOfFirstEvent(); // Initial entries in GC log happen within seconds. Lets allow for 60 before considering the log // to be a fragment. - if (startTime.getTimeStamp() < LOG_FRAGMENT_THRESHOLD) { + if (startTime.getTimeStamp() < LOG_FRAGMENT_THRESHOLD_SECONDS) { return startTime.minus(startTime.getTimeStamp()); } else { return startTime; From deb747116e0e54b7c31dd823c591a8583cc73000 Mon Sep 17 00:00:00 2001 From: Kirk Pepperdine <74371364+kirk-microsoft@users.noreply.github.com> Date: Mon, 7 Feb 2022 17:14:21 -0800 Subject: [PATCH 08/11] Datetime (#207) * refactoring of JavaVirtualMachine * fix: DateTimeStamp is being reported incorrectly * refactor: reorganize IT module to better support tests * refactor: pick up modified files * fix: return correct time of log termination * refactor: more pre-release cleanup * tidy: fix issue with javadoc --- .../gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java index 1eb6237f..10853d47 100644 --- a/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java +++ b/vertx/src/main/java/com/microsoft/gctoolkit/vertx/jvm/AbstractJavaVirtualMachine.java @@ -70,15 +70,10 @@ public String getCommandLine() { } /** -<<<<<<< HEAD * If the first event is significantly distant from zero in relation to the time intervals between the * of the next N events, where N maybe 1, then this is likely a log fragment and not the start of the run. -======= - * of the first event is significantly away from zero in relation to the time intervals between the - * of the next N events, where N maybe 1. ->>>>>>> 4c4d0c41e72e68a504f76db856c8aa37d8850828 * - * try to estimate the time at which the JVM started. For log fragments, this will be the time + * Try to estimate the time at which the JVM started. For log fragments, this will be the time * of the first event in the log. Otherwise it will be 0.000 seconds. * @return DateTimeStamp */ From 524bc0216a4f3c02e6894c29f3d9ed817c9a61de Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 8 Feb 2022 01:20:03 +0000 Subject: [PATCH 09/11] [maven-release-plugin] prepare release gctoolkit-2.0.7 --- IT/pom.xml | 4 ++-- api/pom.xml | 2 +- gclogs/pom.xml | 2 +- parser/pom.xml | 2 +- pom.xml | 4 ++-- sample/pom.xml | 2 +- vertx/pom.xml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/IT/pom.xml b/IT/pom.xml index 992354a5..ec96af52 100644 --- a/IT/pom.xml +++ b/IT/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml @@ -44,7 +44,7 @@ com.microsoft.gctoolkit gctoolkit-sample - 2.0.7-SNAPSHOT + 2.0.7 test diff --git a/api/pom.xml b/api/pom.xml index 61eb09c0..07653241 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml diff --git a/gclogs/pom.xml b/gclogs/pom.xml index b0dd7fc0..01308536 100644 --- a/gclogs/pom.xml +++ b/gclogs/pom.xml @@ -6,7 +6,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml diff --git a/parser/pom.xml b/parser/pom.xml index 9a074187..90ea5bdc 100644 --- a/parser/pom.xml +++ b/parser/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml diff --git a/pom.xml b/pom.xml index 40e3a21b..c028c688 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit pom - 2.0.7-SNAPSHOT + 2.0.7 GCToolKit GC log parsing utilities @@ -28,7 +28,7 @@ scm:git:${repository.url} scm:git:${repository.url} ${repository.url} - gctoolkit-2.0.5 + gctoolkit-2.0.7 diff --git a/sample/pom.xml b/sample/pom.xml index db298f51..c3083296 100644 --- a/sample/pom.xml +++ b/sample/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml diff --git a/vertx/pom.xml b/vertx/pom.xml index 67c82c20..2665a66f 100644 --- a/vertx/pom.xml +++ b/vertx/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7-SNAPSHOT + 2.0.7 ../pom.xml From 2b966e78841a0aeb0a64a3beec22b2032c0d2932 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 8 Feb 2022 01:20:05 +0000 Subject: [PATCH 10/11] [maven-release-plugin] prepare for next development iteration --- IT/pom.xml | 4 ++-- api/pom.xml | 2 +- gclogs/pom.xml | 2 +- parser/pom.xml | 2 +- pom.xml | 4 ++-- sample/pom.xml | 2 +- vertx/pom.xml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/IT/pom.xml b/IT/pom.xml index ec96af52..dd9288ed 100644 --- a/IT/pom.xml +++ b/IT/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml @@ -44,7 +44,7 @@ com.microsoft.gctoolkit gctoolkit-sample - 2.0.7 + 2.0.8-SNAPSHOT test diff --git a/api/pom.xml b/api/pom.xml index 07653241..f39a29dc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml diff --git a/gclogs/pom.xml b/gclogs/pom.xml index 01308536..0faf78d3 100644 --- a/gclogs/pom.xml +++ b/gclogs/pom.xml @@ -6,7 +6,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml diff --git a/parser/pom.xml b/parser/pom.xml index 90ea5bdc..9b9035f9 100644 --- a/parser/pom.xml +++ b/parser/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index c028c688..af21371e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit pom - 2.0.7 + 2.0.8-SNAPSHOT GCToolKit GC log parsing utilities @@ -28,7 +28,7 @@ scm:git:${repository.url} scm:git:${repository.url} ${repository.url} - gctoolkit-2.0.7 + gctoolkit-2.0.5 diff --git a/sample/pom.xml b/sample/pom.xml index c3083296..7a2cb8b0 100644 --- a/sample/pom.xml +++ b/sample/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml diff --git a/vertx/pom.xml b/vertx/pom.xml index 2665a66f..0f80305b 100644 --- a/vertx/pom.xml +++ b/vertx/pom.xml @@ -5,7 +5,7 @@ com.microsoft.gctoolkit gctoolkit - 2.0.7 + 2.0.8-SNAPSHOT ../pom.xml From e0eabd2f2ea8dd6611e6609c3008083e9961b3c1 Mon Sep 17 00:00:00 2001 From: DreamLettuce <843608347@qq.com> Date: Mon, 21 Feb 2022 00:46:16 +0800 Subject: [PATCH 11/11] fix G1GC JVM tenured summary calculate (#144) (#210) Co-authored-by: xuanfei --- .../microsoft/gctoolkit/event/g1gc/G1GCPauseEvent.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/microsoft/gctoolkit/event/g1gc/G1GCPauseEvent.java b/api/src/main/java/com/microsoft/gctoolkit/event/g1gc/G1GCPauseEvent.java index e7d4b05d..0fac4116 100644 --- a/api/src/main/java/com/microsoft/gctoolkit/event/g1gc/G1GCPauseEvent.java +++ b/api/src/main/java/com/microsoft/gctoolkit/event/g1gc/G1GCPauseEvent.java @@ -64,15 +64,12 @@ public MemoryPoolSummary getTenured() { if ((getEden() == null) || (getHeap() == null)) { return NULL_POOL; } else if (getSurvivor() == null) { - return new MemoryPoolSummary(getHeap().getOccupancyBeforeCollection() - this.getEden().getOccupancyBeforeCollection(), - getHeap().getSizeBeforeCollection() - getEden().getSizeBeforeCollection(), - getHeap().getOccupancyAfterCollection() - getEden().getOccupancyAfterCollection(), - getHeap().getSizeAfterCollection() - getEden().getSizeAfterCollection()); + return getHeap().minus(getEden()); } else { - return new MemoryPoolSummary(getHeap().getOccupancyBeforeCollection() - this.getEden().getOccupancyBeforeCollection(), + return new MemoryPoolSummary(getHeap().getOccupancyBeforeCollection() - this.getEden().getOccupancyBeforeCollection() - getSurvivor().getOccupancyBeforeCollection(), getHeap().getSizeBeforeCollection() - getEden().getSizeBeforeCollection() - getSurvivor().getOccupancyBeforeCollection(), getHeap().getOccupancyAfterCollection() - getEden().getOccupancyAfterCollection() - getSurvivor().getOccupancyAfterCollection(), - getHeap().getSizeAfterCollection() - getEden().getSizeAfterCollection()); + getHeap().getSizeAfterCollection() - getEden().getSizeAfterCollection() - getSurvivor().getOccupancyAfterCollection()); } }