diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
index 5be7caf..42bdb6e 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
@@ -405,7 +405,7 @@ public class AsyncIndexUpdate implements Runnable {
                 postAsyncRunStatsStatus(indexStats);
             }
             if (indexUpdate.isReindexingPerformed()) {
-                log.info("Reindexing completed for indexes: {} in {}", indexUpdate.getAllReIndexedIndexes(), watch);
+                log.info("Reindexing completed for indexes: {} in {}", indexUpdate.getReindexStats(), watch);
             }
         } finally {
             callback.close();
diff --git oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
index 757a19b..d900164 100644
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
@@ -33,6 +33,8 @@ import static org.apache.jackrabbit.oak.spi.commit.CompositeEditor.compose;
 import static org.apache.jackrabbit.oak.spi.commit.EditorDiff.process;
 import static org.apache.jackrabbit.oak.spi.commit.VisibleEditor.wrap;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -41,10 +43,13 @@ import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.spi.commit.Editor;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -56,7 +61,7 @@ import com.google.common.base.Objects;
 
 public class IndexUpdate implements Editor {
 
-    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final Logger log = LoggerFactory.getLogger(IndexUpdate.class);
 
     private final IndexUpdateRootState rootState;
 
@@ -125,11 +130,11 @@ public class IndexUpdate implements Editor {
     }
 
     public boolean isReindexingPerformed(){
-        return !getAllReIndexedIndexes().isEmpty();
+        return !getReindexStats().isEmpty();
     }
 
-    public Set<String> getAllReIndexedIndexes(){
-        return rootState.reindexedIndexes;
+    public List<String> getReindexStats(){
+        return rootState.getReindexStats();
     }
 
     private boolean shouldReindex(NodeBuilder definition, NodeState before,
@@ -160,7 +165,8 @@ public class IndexUpdate implements Editor {
                 }
                 boolean shouldReindex = shouldReindex(definition,
                         before, name);
-                Editor editor = rootState.provider.getIndexEditor(type, definition, rootState.root, rootState.updateCallback);
+                Editor editor = rootState.provider.getIndexEditor(type, definition, rootState.root,
+                        rootState.newCallback(getIndexPath(getPath(), name), shouldReindex));
                 if (editor == null) {
                     missingProvider.onMissingIndex(type, definition);
                 } else if (shouldReindex) {
@@ -212,6 +218,14 @@ public class IndexUpdate implements Editor {
         for (Editor editor : editors) {
             editor.leave(before, after);
         }
+
+        if (parent == null){
+            if (rootState.isReindexingPerformed()){
+                log.info(rootState.getReport());
+            } else if (log.isDebugEnabled()){
+                log.debug(rootState.getReport());
+            }
+        }
     }
 
     @Override
@@ -284,6 +298,13 @@ public class IndexUpdate implements Editor {
         return reindex.keySet();
     }
 
+    private static String getIndexPath(String path, String indexName) {
+        if (PathUtils.denotesRoot(path)) {
+            return "/" + INDEX_DEFINITIONS_NAME + "/" + indexName;
+        }
+        return path + "/" + INDEX_DEFINITIONS_NAME + "/" + indexName;
+    }
+
     public static class MissingIndexProviderStrategy {
         public void onMissingIndex(String type, NodeBuilder definition)
                 throws CommitFailedException {
@@ -312,6 +333,7 @@ public class IndexUpdate implements Editor {
          */
         final IndexUpdateCallback updateCallback;
         final Set<String> reindexedIndexes = Sets.newHashSet();
+        final Map<String, CountingCallback> callbacks = Maps.newHashMap();
 
         private IndexUpdateRootState(IndexEditorProvider provider, String async, NodeState root,
                                      IndexUpdateCallback updateCallback) {
@@ -320,6 +342,65 @@ public class IndexUpdate implements Editor {
             this.root = checkNotNull(root);
             this.updateCallback = checkNotNull(updateCallback);
         }
+
+        public IndexUpdateCallback newCallback(String indexPath, boolean reindex) {
+            CountingCallback cb = new CountingCallback(indexPath, reindex);
+            callbacks.put(cb.indexName, cb);
+            return cb;
+        }
+
+        public String getReport() {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            pw.println("Indexing report");
+            for (CountingCallback cb : callbacks.values()) {
+                if (!log.isDebugEnabled() && !cb.reindex) {
+                    continue;
+                }
+                pw.printf("    - %s%n", cb);
+            }
+            return sw.toString();
+        }
+
+        public List<String> getReindexStats(){
+            List<String> stats = Lists.newArrayList();
+            for (CountingCallback cb : callbacks.values()){
+                if (cb.reindex) {
+                    stats.add(cb.toString());
+                }
+            }
+            return stats;
+        }
+
+        public boolean isReindexingPerformed(){
+            return !reindexedIndexes.isEmpty();
+        }
+
+        private class CountingCallback implements IndexUpdateCallback {
+            final String indexName;
+            final boolean reindex;
+            int count;
+
+            private CountingCallback(String indexName, boolean reindex) {
+                this.indexName = indexName;
+                this.reindex = reindex;
+            }
+
+            @Override
+            public void indexUpdate() throws CommitFailedException {
+                count++;
+                if (count % 1000 == 0){
+                    log.info("{} => Indexed {} nodes...", indexName, count);
+                }
+                updateCallback.indexUpdate();
+            }
+
+            @Override
+            public String toString() {
+                String reindexMarker = reindex ? "*" : "";
+                return indexName + reindexMarker + "(" + count + ")";
+            }
+        }
     }
 
 }
