Index: src/test/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorderTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorderTest.java	(revision 1357220)
+++ src/test/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorderTest.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.stats;
 
+import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.jackrabbit.api.stats.RepositoryStatistics;
@@ -24,9 +25,14 @@
 
 public class TimeSeriesRecorderTest extends TestCase {
 
-    public void testCounter() {
-        TimeSeriesRecorder recorder = new TimeSeriesRecorder(
-                RepositoryStatistics.Type.SESSION_READ_COUNTER);
+    public void testTimeSeries() {
+        checkCounterSingle(new TimeSeriesRecorder(
+                RepositoryStatistics.Type.SESSION_READ_COUNTER));
+        checkCounterIncremental(new TimeSeriesRecorder(
+                RepositoryStatistics.Type.SESSION_COUNT));
+    }
+
+    private void checkCounterSingle(TimeSeriesRecorder recorder) {
         AtomicLong counter = recorder.getCounter();
 
         // initial values
@@ -111,6 +117,102 @@
         assertValues(recorder.getValuePerWeek(), 13);
     }
 
+    private void checkCounterIncremental(TimeSeriesRecorder recorder) {
+        AtomicLong counter = recorder.getCounter();
+
+        // initial values
+        assertValues(recorder.getValuePerSecond());
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // no changes in first second
+        recorder.recordOneSecond();
+        assertValues(recorder.getValuePerSecond());
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // one increment in second
+        counter.incrementAndGet();
+        recorder.recordOneSecond();
+        assertValues(recorder.getValuePerSecond(), 1);
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // two increments in second
+        counter.incrementAndGet();
+        counter.incrementAndGet();
+        recorder.recordOneSecond();
+        assertValues(recorder.getValuePerSecond(), 3, 1);
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // no changes in a second
+        recorder.recordOneSecond();
+        assertValues(recorder.getValuePerSecond(), 3, 3, 1);
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // ten increments in a second
+        counter.addAndGet(10);
+        long value = counter.get();
+        recorder.recordOneSecond();
+        assertValues(recorder.getValuePerSecond(), value, 3, 3, 1);
+        assertValues(recorder.getValuePerMinute());
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // one minute
+        for (int i = 0; i < 60; i++) {
+            recorder.recordOneSecond();
+        }
+        long avgM = (1 + 3 + 3 + value * 57) / 60;
+        assertValues(recorder.getValuePerSecond(), newArray(value, 60));
+        assertValues(recorder.getValuePerMinute(), avgM);
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // second minute
+        for (int i = 0; i < 60; i++) {
+            recorder.recordOneSecond();
+        }
+        assertValues(recorder.getValuePerSecond(), newArray(value, 60));
+        assertValues(recorder.getValuePerMinute(), value, avgM);
+        assertValues(recorder.getValuePerHour());
+        assertValues(recorder.getValuePerWeek());
+
+        // one hour
+        for (int i = 0; i < 60 * 60; i++) {
+            recorder.recordOneSecond();
+        }
+        long avgH = (avgM + 59 * value) / 60;
+        assertValues(recorder.getValuePerSecond(), newArray(value, 60));
+        assertValues(recorder.getValuePerMinute(), newArray(value, 60));
+        assertValues(recorder.getValuePerHour(), avgH);
+        assertValues(recorder.getValuePerWeek());
+
+        // one week
+        for (int i = 0; i < 7 * 24 * 60 * 60; i++) {
+            recorder.recordOneSecond();
+        }
+        int hoursInAWeek = 24 * 7;
+        long avgW = (avgH + value * (hoursInAWeek - 1)) / hoursInAWeek;
+        assertValues(recorder.getValuePerSecond(), newArray(value, 60));
+        assertValues(recorder.getValuePerMinute(), newArray(value, 60));
+        assertValues(recorder.getValuePerHour(), newArray(value, hoursInAWeek));
+        assertValues(recorder.getValuePerWeek(), avgW);
+    }
+
+    private static long[] newArray(long v, int size) {
+        long[] arr = new long[size];
+        Arrays.fill(arr, v);
+        return arr;
+    }
+
     private void assertValues(long[] values, long... expected) {
         for (int i = 0; i < expected.length; i++) {
             assertEquals(expected[i], values[values.length - i - 1]);
Index: src/main/java/org/apache/jackrabbit/core/observation/ObservationDispatcher.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/observation/ObservationDispatcher.java	(revision 1357220)
+++ src/main/java/org/apache/jackrabbit/core/observation/ObservationDispatcher.java	(working copy)
@@ -16,19 +16,24 @@
  */
 package org.apache.jackrabbit.core.observation;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
 import org.apache.commons.collections.Buffer;
 import org.apache.commons.collections.BufferUtils;
 import org.apache.commons.collections.buffer.UnboundedFifoBuffer;
+import org.apache.jackrabbit.api.stats.TimeSeries;
 import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.stats.TimeSeriesRecorder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
 /**
  * Dispatcher for dispatching events to listeners within a single workspace.
  */
@@ -87,8 +92,6 @@
     private Buffer eventQueue
             = BufferUtils.blockingBuffer(new UnboundedFifoBuffer());
 
-    private AtomicInteger eventQueueSize = new AtomicInteger();
-
     /**
      * The background notification thread
      */
@@ -97,6 +100,17 @@
     private long lastError;
 
     /**
+     * The TimeSeries that handles the statistics reporting for this component. <br>
+     * It is important to pass <code>false</code> to the TimeSeriesRecorder
+     * otherwise we risk reseting the counter each second
+     */
+    private final TimeSeriesRecorder timeSeries = new TimeSeriesRecorder(false);
+
+    private final AtomicLong eventQueueSize = timeSeries.getCounter();
+
+    private ScheduledFuture<?> statFuture;
+
+    /**
      * Creates a new <code>ObservationDispatcher</code> instance
      * and starts the notification thread daemon.
      */
@@ -107,6 +121,21 @@
     }
 
     /**
+     * Creates a new <code>ObservationDispatcher</code> instance and starts the
+     * notification thread daemon. <br>
+     * This constructor also enables the component's statistics that will be
+     * tracked via the <code>executor</code>.
+     */
+    public ObservationDispatcher(ScheduledExecutorService executor) {
+        this();
+        statFuture = executor.scheduleAtFixedRate(new Runnable() {
+            public void run() {
+                recordOneSecond();
+            }
+        }, 1, 1, TimeUnit.SECONDS);
+    }
+
+    /**
      * Disposes this <code>ObservationManager</code>. This will
      * effectively stop the background notification thread.
      */
@@ -118,6 +147,7 @@
         } catch (InterruptedException e) {
             // FIXME log exception ?
         }
+        statFuture.cancel(true);
         log.info("Notification of EventListeners stopped.");
     }
 
@@ -153,7 +183,7 @@
         while ((action = (DispatchAction) eventQueue.remove()) != DISPOSE_MARKER) {
 
             eventQueueSize.getAndAdd(-action.getEventStates().size());
-            log.debug("got EventStateCollection");
+            log.debug("got EventStateCollection ({})", eventQueueSize.get());
             log.debug("event delivery to " + action.getEventConsumers().size() + " consumers started...");
             for (Iterator<EventConsumer> it = action.getEventConsumers().iterator(); it.hasNext();) {
                 EventConsumer c = it.next();
@@ -301,4 +331,14 @@
         }
     }
 
+    // ------------------------------------------Statistics
+
+    public TimeSeries getTimeSeries() {
+        return timeSeries;
+    }
+
+    private synchronized void recordOneSecond() {
+        timeSeries.recordOneSecond();
+    }
+
 }
Index: src/main/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorder.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorder.java	(revision 1357220)
+++ src/main/java/org/apache/jackrabbit/core/stats/TimeSeriesRecorder.java	(working copy)
@@ -27,7 +27,7 @@
  * exposes the collected time series through the {@link TimeSeries}
  * interface.
  */
-class TimeSeriesRecorder implements TimeSeries {
+public class TimeSeriesRecorder implements TimeSeries {
 
     /** Value */
     private final AtomicLong counter = new AtomicLong();
Index: src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(revision 1357220)
+++ src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(working copy)
@@ -2048,7 +2048,7 @@
                 throw new RepositoryException(msg, ise);
             }
 
-            dispatcher = new ObservationDispatcher();
+            dispatcher = new ObservationDispatcher(context.getExecutor());
 
             // register the observation factory of that workspace
             delegatingDispatcher.addDispatcher(dispatcher);
