Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (revision 9795521f6f8ec6869287f1c55458505a2ec68844) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (date 1529395868000) @@ -22,6 +22,7 @@ import org.apache.jackrabbit.api.stats.TimeSeries; import org.apache.jackrabbit.oak.plugins.document.VersionGarbageCollector.VersionGCStats; +import org.apache.jackrabbit.oak.stats.CounterStats; import org.apache.jackrabbit.oak.stats.MeterStats; import org.apache.jackrabbit.oak.stats.StatisticsProvider; import org.apache.jackrabbit.oak.stats.TimerStats; @@ -35,7 +36,7 @@ * DocumentNodeStore revision garbage collection statistics. */ class RevisionGCStats implements RevisionGCStatsCollector, RevisionGCStatsMBean { - + static final String OP_STATS = "OperationStats"; static final String RGC = "RevisionGC"; static final String READ_DOC = "READ_DOC"; static final String DELETE_DOC = "DELETE_DOC"; @@ -44,7 +45,7 @@ static final String DELETE_INT_SPLIT_DOC = "DELETE_INT_SPLIT_DOC"; static final String RESET_DELETED_FLAG = "RESET_DELETED_FLAG"; - static final String ACTIVE_TIMER = "ACTIVE_TIMER"; + static final String ACTIVE_TIMER = "DURATION"; static final String READ_DOC_TIMER = "READ_DOC_TIMER"; static final String CHECK_DELETED_TIMER = "CHECK_DELETED_TIMER"; static final String SORT_IDS_TIMER = "SORT_IDS_TIMER"; @@ -52,6 +53,10 @@ static final String DELETE_DOC_TIMER = "DELETE_DOC_TIMER"; static final String DELETE_SPLIT_DOC_TIMER = "DELETE_SPLIT_DOC_TIMER"; + static final String START_COUNTER = "START"; + static final String FINISH_SUCCESS_COUNTER = "FINISH_SUCCESS"; + static final String FINISH_FAILURE_COUNTER = "FINISH_FAILURE"; + private final StatisticsProvider provider; private final MeterStats readDoc; @@ -69,6 +74,10 @@ private final TimerStats deletedDocTimer; private final TimerStats deletedSplitDocTimer; + private final CounterStats startCounter; + private final CounterStats finishSuccessCounter; + private final CounterStats finishFailureCounter; + RevisionGCStats(StatisticsProvider provider) { this.provider = provider; @@ -86,6 +95,10 @@ resetDeletedFlagTimer = timer(provider, RESET_DELETED_FLAG_TIMER); deletedDocTimer = timer(provider, DELETE_DOC_TIMER); deletedSplitDocTimer = timer(provider, DELETE_SPLIT_DOC_TIMER); + + startCounter = counter(provider, START_COUNTER); + finishSuccessCounter = counter(provider, FINISH_SUCCESS_COUNTER); + finishFailureCounter = counter(provider, FINISH_FAILURE_COUNTER); } //---------------------< RevisionGCStatsCollector >------------------------- @@ -124,6 +137,11 @@ resetDeletedFlag.mark(); } + @Override + public void start() { + startCounter.inc(); + } + @Override public void finished(VersionGCStats stats) { activeTimer.update(stats.active.elapsed(MICROSECONDS), MICROSECONDS); @@ -133,8 +151,13 @@ deletedSplitDocTimer.update(stats.collectAndDeleteSplitDocsElapsed, MICROSECONDS); sortIdsTimer.update(stats.sortDocIdsElapsed, MICROSECONDS); resetDeletedFlagTimer.update(stats.updateResurrectedDocumentsElapsed, MICROSECONDS); + finishSuccessCounter.inc(); } + @Override + public void finishedFailure() { + finishFailureCounter.inc(); + } //------------------------< RevisionGCStatsMBean >-------------------------- @@ -217,8 +240,13 @@ return provider.getTimer(qualifiedName(name), METRICS_ONLY); } + private static CounterStats counter(StatisticsProvider provider, + String name) { + return provider.getCounterStats(qualifiedName(name), METRICS_ONLY); + } + private static String qualifiedName(String metricName) { - return RGC + "." + metricName; + return OP_STATS + "." + RGC + "." + metricName; } private CompositeData getTimeSeriesData(String name, String desc) { Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (revision 9795521f6f8ec6869287f1c55458505a2ec68844) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (date 1529388219000) @@ -38,5 +38,9 @@ void deletedOnceFlagReset(); + void start(); + void finished(VersionGCStats stats); -} \ No newline at end of file + + void finishedFailure(); +} Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java (revision 9795521f6f8ec6869287f1c55458505a2ec68844) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java (date 1529388576000) @@ -135,6 +135,8 @@ if (collector.compareAndSet(null, job)) { VersionGCStats overall = new VersionGCStats(); overall.active.start(); + gcStats.start(); + boolean thrown = true; try { long averageDurationMs = 0; while (maxRunTime.contains(nodeStore.getClock().getTime() + averageDurationMs)) { @@ -152,10 +154,15 @@ averageDurationMs = ((averageDurationMs * (overall.iterationCount - 1)) + stats.active.elapsed(TimeUnit.MILLISECONDS)) / overall.iterationCount; } + + thrown = false; gcStats.finished(overall); return overall; } finally { overall.active.stop(); + if (thrown) { + gcStats.finishedFailure(); + } collector.set(null); if (overall.iterationCount > 1) { gcMonitor.info("Revision garbage collection finished after {} iterations - aggregate statistics: {}", Index: oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (revision 9795521f6f8ec6869287f1c55458505a2ec68844) +++ oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (date 1529390456000) @@ -20,6 +20,7 @@ import java.util.concurrent.ScheduledExecutorService; +import com.codahale.metrics.Counter; import com.codahale.metrics.Meter; import com.codahale.metrics.Timer; @@ -33,6 +34,7 @@ import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static org.apache.jackrabbit.oak.plugins.document.RevisionGCStats.OP_STATS; import static org.apache.jackrabbit.oak.plugins.document.RevisionGCStats.RGC; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -130,15 +132,38 @@ assertTimer(13, RevisionGCStats.RESET_DELETED_FLAG_TIMER); } + @Test + public void counters() { + Counter startCounter = getCounter(RevisionGCStats.START_COUNTER); + Counter finishSuccessCounter = getCounter(RevisionGCStats.FINISH_SUCCESS_COUNTER); + Counter finishFailureCounter = getCounter(RevisionGCStats.FINISH_FAILURE_COUNTER); + + stats.start(); + assertEquals(1, startCounter.getCount()); + + VersionGCStats vgcs = new VersionGCStats(); + stats.finished(vgcs); + assertEquals(1, finishSuccessCounter.getCount()); + assertEquals(0, finishFailureCounter.getCount()); + + stats.finishedFailure(); + assertEquals(1, finishFailureCounter.getCount()); + } + private void assertTimer(long expected, String name) { assertEquals(expected, NANOSECONDS.toMillis(getTimer(name).getSnapshot().getMax())); } private Timer getTimer(String name) { - return statsProvider.getRegistry().getTimers().get(RGC + "." + name); + return statsProvider.getRegistry().getTimers().get(OP_STATS + "." + RGC + "." + name); } private Meter getMeter(String name) { - return statsProvider.getRegistry().getMeters().get(RGC + "." + name); + return statsProvider.getRegistry().getMeters().get(OP_STATS + "." + RGC + "." + name); } + + private Counter getCounter(String name) { + return statsProvider.getRegistry().getCounters().get(OP_STATS + "." + RGC + "." + name); + } + }