Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (revision 1833913) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (working copy) @@ -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,6 @@ * DocumentNodeStore revision garbage collection statistics. */ class RevisionGCStats implements RevisionGCStatsCollector, RevisionGCStatsMBean { - static final String RGC = "RevisionGC"; static final String READ_DOC = "READ_DOC"; static final String DELETE_DOC = "DELETE_DOC"; @@ -52,6 +52,9 @@ static final String DELETE_DOC_TIMER = "DELETE_DOC_TIMER"; static final String DELETE_SPLIT_DOC_TIMER = "DELETE_SPLIT_DOC_TIMER"; + static final String COUNTER = "COUNTER"; + static final String FAILURE_COUNTER = "FAILURE"; + private final StatisticsProvider provider; private final MeterStats readDoc; @@ -69,6 +72,9 @@ private final TimerStats deletedDocTimer; private final TimerStats deletedSplitDocTimer; + private final CounterStats counter; + private final CounterStats failureCounter; + RevisionGCStats(StatisticsProvider provider) { this.provider = provider; @@ -86,6 +92,9 @@ resetDeletedFlagTimer = timer(provider, RESET_DELETED_FLAG_TIMER); deletedDocTimer = timer(provider, DELETE_DOC_TIMER); deletedSplitDocTimer = timer(provider, DELETE_SPLIT_DOC_TIMER); + + counter = counter(provider, COUNTER); + failureCounter = counter(provider, FAILURE_COUNTER); } //---------------------< RevisionGCStatsCollector >------------------------- @@ -125,6 +134,11 @@ } @Override + public void started() { + counter.inc(); + } + + @Override public void finished(VersionGCStats stats) { activeTimer.update(stats.active.elapsed(MICROSECONDS), MICROSECONDS); readDocTimer.update(stats.collectDeletedDocsElapsed, MICROSECONDS); @@ -133,6 +147,9 @@ deletedSplitDocTimer.update(stats.collectAndDeleteSplitDocsElapsed, MICROSECONDS); sortIdsTimer.update(stats.sortDocIdsElapsed, MICROSECONDS); resetDeletedFlagTimer.update(stats.updateResurrectedDocumentsElapsed, MICROSECONDS); + if (!stats.success) { + failureCounter.inc(); + } } @@ -217,6 +234,11 @@ 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; } Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (revision 1833913) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (working copy) @@ -38,5 +38,7 @@ void deletedOnceFlagReset(); + void started(); + void finished(VersionGCStats stats); } \ No newline at end of file Index: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java =================================================================== --- oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java (revision 1833913) +++ oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java (working copy) @@ -135,6 +135,8 @@ if (collector.compareAndSet(null, job)) { VersionGCStats overall = new VersionGCStats(); overall.active.start(); + gcStats.started(); + boolean success = false; try { long averageDurationMs = 0; while (maxRunTime.contains(nodeStore.getClock().getTime() + averageDurationMs)) { @@ -152,11 +154,13 @@ averageDurationMs = ((averageDurationMs * (overall.iterationCount - 1)) + stats.active.elapsed(TimeUnit.MILLISECONDS)) / overall.iterationCount; } - gcStats.finished(overall); + success = true; return overall; } finally { overall.active.stop(); collector.set(null); + overall.success = success; + gcStats.finished(overall); if (overall.iterationCount > 1) { gcMonitor.info("Revision garbage collection finished after {} iterations - aggregate statistics: {}", overall.iterationCount, overall); @@ -243,6 +247,7 @@ public static class VersionGCStats { boolean ignoredGCDueToCheckPoint; boolean canceled; + boolean success = true; boolean limitExceeded; boolean needRepeat; int iterationCount; @@ -312,6 +317,7 @@ ++iterationCount; this.ignoredGCDueToCheckPoint = run.ignoredGCDueToCheckPoint; this.canceled = run.canceled; + this.success = run.success; this.limitExceeded = run.limitExceeded; this.needRepeat = run.needRepeat; this.deletedDocGCCount += run.deletedDocGCCount; Index: oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java =================================================================== --- oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (revision 1833913) +++ oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (working copy) @@ -20,6 +20,7 @@ import java.util.concurrent.ScheduledExecutorService; +import com.codahale.metrics.Counter; import com.codahale.metrics.Meter; import com.codahale.metrics.Timer; @@ -130,6 +131,24 @@ assertTimer(13, RevisionGCStats.RESET_DELETED_FLAG_TIMER); } + @Test + public void counters() { + Counter counter = getCounter(RevisionGCStats.COUNTER); + Counter failureCounter = getCounter(RevisionGCStats.FAILURE_COUNTER); + + VersionGCStats vgcs = new VersionGCStats(); + stats.started(); + stats.finished(vgcs); + assertEquals(1, counter.getCount()); + assertEquals(0, failureCounter.getCount()); + + vgcs.success = false; + stats.started(); + stats.finished(vgcs); + assertEquals(2, counter.getCount()); + assertEquals(1, failureCounter.getCount()); + } + private void assertTimer(long expected, String name) { assertEquals(expected, NANOSECONDS.toMillis(getTimer(name).getSnapshot().getMax())); } @@ -141,4 +160,9 @@ private Meter getMeter(String name) { return statsProvider.getRegistry().getMeters().get(RGC + "." + name); } + + private Counter getCounter(String name) { + return statsProvider.getRegistry().getCounters().get(RGC + "." + name); + } + }