You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2017/03/20 17:04:31 UTC

[1/2] lucene-solr:jira/solr-9959: SOLR-9959 Notes + javadoc.

Repository: lucene-solr
Updated Branches:
  refs/heads/jira/solr-9959 56095a35f -> b94db28ca


SOLR-9959 Notes + javadoc.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2985bca4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2985bca4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2985bca4

Branch: refs/heads/jira/solr-9959
Commit: 2985bca4485a48b65cd30f12dba0b83bbcd4f8de
Parents: 56095a3
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Thu Mar 16 18:46:27 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Thu Mar 16 18:46:27 2017 +0100

----------------------------------------------------------------------
 solr/core/src/java/org/apache/solr/core/SolrInfoBean.java         | 2 +-
 solr/core/src/java/org/apache/solr/metrics/MetricsMap.java        | 3 +++
 .../java/org/apache/solr/metrics/reporters/SolrJmxReporter.java   | 2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2985bca4/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
index c73492e..83cefe1 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
@@ -19,7 +19,7 @@ package org.apache.solr.core;
 import org.apache.solr.common.util.NamedList;
 
 /**
- * Interface for getting various ui friendly strings and URLs
+ * Interface for getting various ui friendly strings
  * for use by objects which are 'pluggable' to make server administration
  * easier.
  */

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2985bca4/solr/core/src/java/org/apache/solr/metrics/MetricsMap.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/MetricsMap.java b/solr/core/src/java/org/apache/solr/metrics/MetricsMap.java
index 9127636..0a9fae5 100644
--- a/solr/core/src/java/org/apache/solr/metrics/MetricsMap.java
+++ b/solr/core/src/java/org/apache/solr/metrics/MetricsMap.java
@@ -10,6 +10,9 @@ import com.codahale.metrics.Metric;
  * where each metric had to be known in advance and registered separately in {@link com.codahale.metrics.MetricRegistry}.
  * <p>Note: this awkwardly extends {@link Gauge} and not {@link Metric} because awkwardly {@link Metric} instances
  * are not supported by {@link com.codahale.metrics.MetricRegistryListener} :(</p>
+ * <p>Note 2: values added to this metric map have to belong to the list of types supported by JMX:
+ * {@link javax.management.openmbean.OpenType#ALLOWED_CLASSNAMES_LIST}, otherwise they will show up as
+ * "Unavailable" in JConsole.</p>
  */
 public interface MetricsMap extends Gauge<Map<String, Object>> {
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2985bca4/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
index 0e78eee..bdc4edf 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
@@ -34,6 +34,8 @@ import org.slf4j.LoggerFactory;
 /**
  * A {@link SolrMetricReporter} that finds (or creates) a MBeanServer from
  * the given configuration and registers metrics to it with JMX.
+ * <p>NOTE: {@link JmxReporter} that this class uses exports only newly added metrics (it doesn't
+ * process already existing metrics in a registry)</p>
  */
 public class SolrJmxReporter extends SolrMetricReporter {
 


[2/2] lucene-solr:jira/solr-9959: SOLR-9959 Replace SolrInfoBean.getStatistics with the metrics API, part 1.

Posted by ab...@apache.org.
SOLR-9959 Replace SolrInfoBean.getStatistics with the metrics API, part 1.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b94db28c
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b94db28c
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b94db28c

Branch: refs/heads/jira/solr-9959
Commit: b94db28cad645fe0b01bb430a164131cc7f463bd
Parents: 2985bca
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Mon Mar 20 18:02:34 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Mon Mar 20 18:02:34 2017 +0100

----------------------------------------------------------------------
 .../.idea/libraries/Solr_DIH_core_library.xml   |  10 ++
 .../dataimporthandler/dataimporthandler.iml     |   1 +
 .../plugin/AnalyticsStatisticsCollector.java    |  25 ++--
 .../handler/component/AnalyticsComponent.java   |  12 +-
 solr/contrib/dataimporthandler/ivy.xml          |   1 +
 .../handler/dataimport/DataImportHandler.java   |  59 +++++----
 .../src/java/org/apache/solr/core/SolrCore.java |  58 ++++-----
 .../java/org/apache/solr/core/SolrInfoBean.java |  11 --
 .../apache/solr/handler/ReplicationHandler.java | 112 ++++++++++-------
 .../apache/solr/handler/RequestHandlerBase.java |  17 +--
 .../solr/handler/admin/PluginInfoHandler.java   |   4 -
 .../handler/admin/SolrInfoMBeanHandler.java     |   3 -
 .../solr/handler/component/SearchComponent.java |   5 -
 .../handler/component/SuggestComponent.java     |  28 +++--
 .../apache/solr/highlight/GapFragmenter.java    |   2 +-
 .../solr/highlight/HighlightingPluginBase.java  |  13 +-
 .../apache/solr/highlight/HtmlFormatter.java    |   2 +-
 .../apache/solr/highlight/RegexFragmenter.java  |   2 +-
 .../solr/highlight/SimpleFragListBuilder.java   |   2 +-
 .../solr/highlight/SingleFragListBuilder.java   |   2 +-
 .../solr/highlight/SolrBoundaryScanner.java     |   2 +-
 .../solr/highlight/SolrFragmentsBuilder.java    |   2 +-
 .../solr/highlight/WeightedFragListBuilder.java |   2 +-
 .../org/apache/solr/search/FastLRUCache.java    | 107 +++++++++--------
 .../java/org/apache/solr/search/LFUCache.java   | 111 +++++++++--------
 .../java/org/apache/solr/search/LRUCache.java   |  66 +++++-----
 .../org/apache/solr/search/QParserPlugin.java   |   4 -
 .../java/org/apache/solr/search/SolrCache.java  |   3 +-
 .../org/apache/solr/search/SolrCacheBase.java   |   4 -
 .../apache/solr/search/SolrFieldCacheBean.java  |   4 -
 .../apache/solr/search/SolrIndexSearcher.java   |  48 ++++----
 .../solr/store/hdfs/HdfsLocalityReporter.java   | 119 +++++++++----------
 .../solr/update/DirectUpdateHandler2.java       |  60 +++-------
 .../apache/solr/update/UpdateShardHandler.java  |   5 -
 .../org/apache/solr/util/stats/MetricUtils.java |  14 +--
 .../src/test-files/solr/solr-jmxreporter.xml    |  43 +++++++
 .../cloud/CollectionsAPIDistributedZkTest.java  |   2 +-
 37 files changed, 485 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/dev-tools/idea/.idea/libraries/Solr_DIH_core_library.xml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/.idea/libraries/Solr_DIH_core_library.xml b/dev-tools/idea/.idea/libraries/Solr_DIH_core_library.xml
new file mode 100644
index 0000000..d363b92
--- /dev/null
+++ b/dev-tools/idea/.idea/libraries/Solr_DIH_core_library.xml
@@ -0,0 +1,10 @@
+<component name="libraryTable">
+  <library name="Solr DIH core library">
+    <CLASSES>
+      <root url="file://$PROJECT_DIR$/solr/contrib/dataimporthandler/lib" />
+    </CLASSES>
+    <JAVADOC />
+    <SOURCES />
+    <jarDirectory url="file://$PROJECT_DIR$/solr/contrib/dataimporthandler/lib" recursive="false" />
+  </library>
+</component>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/dev-tools/idea/solr/contrib/dataimporthandler/dataimporthandler.iml
----------------------------------------------------------------------
diff --git a/dev-tools/idea/solr/contrib/dataimporthandler/dataimporthandler.iml b/dev-tools/idea/solr/contrib/dataimporthandler/dataimporthandler.iml
index 6268247..bf3a12e 100644
--- a/dev-tools/idea/solr/contrib/dataimporthandler/dataimporthandler.iml
+++ b/dev-tools/idea/solr/contrib/dataimporthandler/dataimporthandler.iml
@@ -19,6 +19,7 @@
     <orderEntry type="library" scope="TEST" name="Solr example library" level="project" />
     <orderEntry type="library" name="Solr core library" level="project" />
     <orderEntry type="library" name="Solrj library" level="project" />
+    <orderEntry type="library" name="Solr DIH core library" level="project" />
     <orderEntry type="module" scope="TEST" module-name="lucene-test-framework" />
     <orderEntry type="module" scope="TEST" module-name="solr-test-framework" />
     <orderEntry type="module" module-name="solr-core" />

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
index b22dcb5..05e332c 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.analytics.plugin;
 
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 import com.codahale.metrics.Timer;
@@ -85,17 +87,16 @@ public class AnalyticsStatisticsCollector {
     currentTimer.stop();
   }
 
-  public NamedList<Object> getStatistics() {
-    NamedList<Object> lst = new SimpleOrderedMap<>();
-    lst.add("requests", numRequests.longValue());
-    lst.add("analyticsRequests", numAnalyticsRequests.longValue());
-    lst.add("statsRequests", numStatsRequests.longValue());
-    lst.add("statsCollected", numCollectedStats.longValue());
-    lst.add("fieldFacets", numFieldFacets.longValue());
-    lst.add("rangeFacets", numRangeFacets.longValue());
-    lst.add("queryFacets", numQueryFacets.longValue());
-    lst.add("queriesInQueryFacets", numQueries.longValue());
-    MetricUtils.addMetrics(lst, requestTimes);
-    return lst;
+  public Map<String, Object> getStatistics() {
+    Map<String, Object> map = MetricUtils.convertTimer(requestTimes, false);
+    map.put("requests", numRequests.longValue());
+    map.put("analyticsRequests", numAnalyticsRequests.longValue());
+    map.put("statsRequests", numStatsRequests.longValue());
+    map.put("statsCollected", numCollectedStats.longValue());
+    map.put("fieldFacets", numFieldFacets.longValue());
+    map.put("rangeFacets", numRangeFacets.longValue());
+    map.put("queryFacets", numQueryFacets.longValue());
+    map.put("queriesInQueryFacets", numQueries.longValue());
+    return map;
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/contrib/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java b/solr/contrib/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
index a83f7b5..fa354c4 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/handler/component/AnalyticsComponent.java
@@ -23,8 +23,11 @@ import org.apache.solr.analytics.request.AnalyticsStats;
 import org.apache.solr.analytics.util.AnalyticsParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
 
-public class AnalyticsComponent extends SearchComponent {
+public class AnalyticsComponent extends SearchComponent implements SolrMetricProducer {
   public static final String COMPONENT_NAME = "analytics";
   private final AnalyticsStatisticsCollector analyticsCollector = new AnalyticsStatisticsCollector();;
 
@@ -80,7 +83,10 @@ public class AnalyticsComponent extends SearchComponent {
   }
 
   @Override
-  public NamedList getStatistics() {
-    return analyticsCollector.getStatistics();
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    MetricsMap metrics = detailed -> {
+      return analyticsCollector.getStatistics();
+    };
+    manager.registerGauge(registry, metrics, true, getClass().getSimpleName(), getCategory().toString(), scope);
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/contrib/dataimporthandler/ivy.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/dataimporthandler/ivy.xml b/solr/contrib/dataimporthandler/ivy.xml
index ea138dd..5ec92ae 100644
--- a/solr/contrib/dataimporthandler/ivy.xml
+++ b/solr/contrib/dataimporthandler/ivy.xml
@@ -29,6 +29,7 @@
     <dependency org="org.mockito" name="mockito-core" rev="${/org.mockito/mockito-core}" conf="test"/>
     <dependency org="net.bytebuddy" name="byte-buddy" rev="${/net.bytebuddy/byte-buddy}" conf="test"/>
     <dependency org="org.objenesis" name="objenesis" rev="${/org.objenesis/objenesis}" conf="test"/>
+    <dependency org="io.dropwizard.metrics" name="metrics-core" rev="${/io.dropwizard.metrics/metrics-core}" conf="compile" />
     <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
   </dependencies>
 </ivy-module>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
----------------------------------------------------------------------
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
index 0766c7f..02f0dc7 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
@@ -32,6 +32,8 @@ import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.response.RawResponseWriter;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
@@ -42,6 +44,7 @@ import org.apache.solr.util.plugin.SolrCoreAware;
 import java.util.*;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Constructor;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -74,6 +77,8 @@ public class DataImportHandler extends RequestHandlerBase implements
 
   private String myName = "dataimport";
 
+  private MetricsMap metrics;
+
   private static final String PARAM_WRITER_IMPL = "writerImpl";
   private static final String DEFAULT_WRITER_NAME = "SolrWriter";
 
@@ -260,41 +265,35 @@ public class DataImportHandler extends RequestHandlerBase implements
       };
     }
   }
-  
-  @Override
-  @SuppressWarnings("unchecked")
-  public NamedList getStatistics() {
-    if (importer == null)
-      return super.getStatistics();
 
-    DocBuilder.Statistics cumulative = importer.cumulativeStatistics;
-    SimpleOrderedMap result = new SimpleOrderedMap();
-
-    result.add("Status", importer.getStatus().toString());
+  @Override
+  public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) {
+    super.initializeMetrics(manager, registryName, scope);
+    metrics = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
+      if (importer != null) {
+        DocBuilder.Statistics cumulative = importer.cumulativeStatistics;
 
-    if (importer.docBuilder != null) {
-      DocBuilder.Statistics running = importer.docBuilder.importStatistics;
-      result.add("Documents Processed", running.docCount);
-      result.add("Requests made to DataSource", running.queryCount);
-      result.add("Rows Fetched", running.rowsCount);
-      result.add("Documents Deleted", running.deletedDocCount);
-      result.add("Documents Skipped", running.skipDocCount);
-    }
+        map.put("Status", importer.getStatus().toString());
 
-    result.add(DataImporter.MSG.TOTAL_DOC_PROCESSED, cumulative.docCount);
-    result.add(DataImporter.MSG.TOTAL_QUERIES_EXECUTED, cumulative.queryCount);
-    result.add(DataImporter.MSG.TOTAL_ROWS_EXECUTED, cumulative.rowsCount);
-    result.add(DataImporter.MSG.TOTAL_DOCS_DELETED, cumulative.deletedDocCount);
-    result.add(DataImporter.MSG.TOTAL_DOCS_SKIPPED, cumulative.skipDocCount);
+        if (importer.docBuilder != null) {
+          DocBuilder.Statistics running = importer.docBuilder.importStatistics;
+          map.put("Documents Processed", running.docCount);
+          map.put("Requests made to DataSource", running.queryCount);
+          map.put("Rows Fetched", running.rowsCount);
+          map.put("Documents Deleted", running.deletedDocCount);
+          map.put("Documents Skipped", running.skipDocCount);
+        }
 
-    NamedList requestStatistics = super.getStatistics();
-    if (requestStatistics != null) {
-      for (int i = 0; i < requestStatistics.size(); i++) {
-        result.add(requestStatistics.getName(i), requestStatistics.getVal(i));
+        map.put(DataImporter.MSG.TOTAL_DOC_PROCESSED, cumulative.docCount);
+        map.put(DataImporter.MSG.TOTAL_QUERIES_EXECUTED, cumulative.queryCount);
+        map.put(DataImporter.MSG.TOTAL_ROWS_EXECUTED, cumulative.rowsCount);
+        map.put(DataImporter.MSG.TOTAL_DOCS_DELETED, cumulative.deletedDocCount);
+        map.put(DataImporter.MSG.TOTAL_DOCS_SKIPPED, cumulative.skipDocCount);
       }
-    }
-
-    return result;
+      return map;
+    };
+    manager.registerGauge(registryName, metrics, true, "importer", getCategory().toString(), scope);
   }
 
   // //////////////////////SolrInfoMBeans methods //////////////////////

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/core/SolrCore.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index 7333dcc..7f8f98a 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -1139,7 +1139,28 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
     manager.registerGauge(registry, () -> getIndexDir(), true, "indexDir", Category.CORE.toString());
     manager.registerGauge(registry, () -> getIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
     manager.registerGauge(registry, () -> NumberUtils.readableSize(getIndexSize()), true, "size", Category.INDEX.toString());
-    manager.registerGauge(registry, () -> coreDescriptor.getCoreContainer().getCoreNames(this), true, "aliases", Category.CORE.toString());
+    if (coreDescriptor != null && coreDescriptor.getCoreContainer() != null) {
+      manager.registerGauge(registry, () -> coreDescriptor.getCoreContainer().getCoreNames(this), true, "aliases", Category.CORE.toString());
+      final CloudDescriptor cd = coreDescriptor.getCloudDescriptor();
+      if (cd != null) {
+        manager.registerGauge(registry, () -> {
+          if (cd.getCollectionName() != null) {
+            return cd.getCollectionName();
+          } else {
+            return "_notset_";
+          }
+        }, true, "collection", Category.CORE.toString());
+
+        manager.registerGauge(registry, () -> {
+          if (cd.getShardId() != null) {
+            return cd.getShardId();
+          } else {
+            return "_auto_";
+          }
+        }, true, "shard", Category.CORE.toString());
+      }
+    }
+
     // initialize disk total / free metrics
     Path dataDirPath = Paths.get(dataDir);
     File dataDirFile = dataDirPath.toFile();
@@ -2779,41 +2800,6 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
     return Category.CORE;
   }
 
-  @Override
-  public NamedList getStatistics() {
-    NamedList<Object> lst = new SimpleOrderedMap<>(8);
-    lst.add("coreName", name==null ? "(null)" : name);
-    lst.add("startTime", startTime);
-    lst.add("refCount", getOpenCount());
-    lst.add("instanceDir", resourceLoader.getInstancePath());
-    lst.add("indexDir", getIndexDir());
-    long size = getIndexSize();
-    lst.add("sizeInBytes", size);
-    lst.add("size", NumberUtils.readableSize(size));
-
-    CoreDescriptor cd = getCoreDescriptor();
-    if (cd != null) {
-      if (null != cd && cd.getCoreContainer() != null) {
-        lst.add("aliases", getCoreDescriptor().getCoreContainer().getCoreNames(this));
-      }
-      CloudDescriptor cloudDesc = cd.getCloudDescriptor();
-      if (cloudDesc != null) {
-        String collection = cloudDesc.getCollectionName();
-        if (collection == null) {
-          collection = "_notset_";
-        }
-        lst.add("collection", collection);
-        String shard = cloudDesc.getShardId();
-        if (shard == null) {
-          shard = "_auto_";
-        }
-        lst.add("shard", shard);
-      }
-    }
-
-    return lst;
-  }
-
   public Codec getCodec() {
     return codec;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
index 83cefe1..cd18d62 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
@@ -45,15 +45,4 @@ public interface SolrInfoBean {
   String getDescription();
   /** Category of this component */
   Category getCategory();
-  /**
-   * Any statistics this instance would like to be publicly available via
-   * the Solr Administration interface.
-   *
-   * <p>
-   * Any Object type may be stored in the list, but only the
-   * <code>toString()</code> representation will be used.
-   * </p>
-   */
-  NamedList getStatistics();
-
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index e40b2c3..85cbc75 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -42,6 +42,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -90,6 +91,8 @@ import org.apache.solr.core.SolrEventListener;
 import org.apache.solr.core.backup.repository.BackupRepository;
 import org.apache.solr.core.backup.repository.LocalFileSystemRepository;
 import org.apache.solr.core.snapshots.SolrSnapshotMetaDataManager;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.search.SolrIndexSearcher;
@@ -161,6 +164,10 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
       }
       return new CommitVersionInfo(generation, version);
     }
+
+    public String toString() {
+      return "generation=" + generation + ",version=" + version;
+    }
   }
 
   private IndexFetcher pollingIndexFetcher;
@@ -851,52 +858,58 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
   }
 
   @Override
-  @SuppressWarnings("unchecked")
-  public NamedList getStatistics() {
-    NamedList list = super.getStatistics();
-    if (core != null) {
-      list.add("indexSize", NumberUtils.readableSize(core.getIndexSize()));
-      CommitVersionInfo vInfo = (core != null && !core.isClosed()) ? getIndexVersion(): null;
-      list.add("indexVersion", null == vInfo ? 0 : vInfo.version);
-      list.add(GENERATION, null == vInfo ? 0 : vInfo.generation);
-
-      list.add("indexPath", core.getIndexDir());
-      list.add("isMaster", String.valueOf(isMaster));
-      list.add("isSlave", String.valueOf(isSlave));
-
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    super.initializeMetrics(manager, registry, scope);
+
+    manager.registerGauge(registry, () -> core != null ? NumberUtils.readableSize(core.getIndexSize()) : "", true,
+        "indexSize", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> (core != null && !core.isClosed() ? getIndexVersion().toString() : ""), true,
+        "indexVersion", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> (core != null && !core.isClosed() ? getIndexVersion().generation : 0), true,
+        GENERATION, getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> core != null ? core.getIndexDir() : "", true,
+        "indexPath", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> isMaster, true,
+        "isMaster", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> isSlave, true,
+        "isSlave", getCategory().toString(), scope);
+    final MetricsMap fetcherMap = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
       IndexFetcher fetcher = currentIndexFetcher;
       if (fetcher != null) {
-        list.add(MASTER_URL, fetcher.getMasterUrl());
+        map.put(MASTER_URL, fetcher.getMasterUrl());
         if (getPollInterval() != null) {
-          list.add(POLL_INTERVAL, getPollInterval());
+          map.put(POLL_INTERVAL, getPollInterval());
         }
-        list.add("isPollingDisabled", String.valueOf(isPollingDisabled()));
-        list.add("isReplicating", String.valueOf(isReplicating()));
+        map.put("isPollingDisabled", isPollingDisabled());
+        map.put("isReplicating", isReplicating());
         long elapsed = fetcher.getReplicationTimeElapsed();
         long val = fetcher.getTotalBytesDownloaded();
         if (elapsed > 0) {
-          list.add("timeElapsed", elapsed);
-          list.add("bytesDownloaded", val);
-          list.add("downloadSpeed", val / elapsed);
+          map.put("timeElapsed", elapsed);
+          map.put("bytesDownloaded", val);
+          map.put("downloadSpeed", val / elapsed);
         }
         Properties props = loadReplicationProperties();
-        addVal(list, IndexFetcher.PREVIOUS_CYCLE_TIME_TAKEN, props, Long.class);
-        addVal(list, IndexFetcher.INDEX_REPLICATED_AT, props, Date.class);
-        addVal(list, IndexFetcher.CONF_FILES_REPLICATED_AT, props, Date.class);
-        addVal(list, IndexFetcher.REPLICATION_FAILED_AT, props, Date.class);
-        addVal(list, IndexFetcher.TIMES_FAILED, props, Integer.class);
-        addVal(list, IndexFetcher.TIMES_INDEX_REPLICATED, props, Integer.class);
-        addVal(list, IndexFetcher.LAST_CYCLE_BYTES_DOWNLOADED, props, Long.class);
-        addVal(list, IndexFetcher.TIMES_CONFIG_REPLICATED, props, Integer.class);
-        addVal(list, IndexFetcher.CONF_FILES_REPLICATED, props, String.class);
-      }
-      if (isMaster) {
-        if (includeConfFiles != null) list.add("confFilesToReplicate", includeConfFiles);
-        list.add(REPLICATE_AFTER, getReplicateAfterStrings());
-        list.add("replicationEnabled", String.valueOf(replicationEnabled.get()));
+        addVal(map, IndexFetcher.PREVIOUS_CYCLE_TIME_TAKEN, props, Long.class);
+        addVal(map, IndexFetcher.INDEX_REPLICATED_AT, props, Date.class);
+        addVal(map, IndexFetcher.CONF_FILES_REPLICATED_AT, props, Date.class);
+        addVal(map, IndexFetcher.REPLICATION_FAILED_AT, props, Date.class);
+        addVal(map, IndexFetcher.TIMES_FAILED, props, Integer.class);
+        addVal(map, IndexFetcher.TIMES_INDEX_REPLICATED, props, Integer.class);
+        addVal(map, IndexFetcher.LAST_CYCLE_BYTES_DOWNLOADED, props, Long.class);
+        addVal(map, IndexFetcher.TIMES_CONFIG_REPLICATED, props, Integer.class);
+        addVal(map, IndexFetcher.CONF_FILES_REPLICATED, props, String.class);
       }
-    }
-    return list;
+      return map;
+    };
+    manager.registerGauge(registry, fetcherMap, true, "fetcher", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> isMaster && includeConfFiles != null ? includeConfFiles : "", true,
+        "confFilesToReplicate", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> isMaster ? getReplicateAfterStrings() : Collections.<String>emptyList(), true,
+        REPLICATE_AFTER, getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> isMaster && replicationEnabled.get(), true,
+        "replicationEnabled", getCategory().toString(), scope);
   }
 
   /**
@@ -1064,24 +1077,39 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
   }
 
   private void addVal(NamedList<Object> nl, String key, Properties props, Class clzz) {
+    Object val = formatVal(key, props, clzz);
+    if (val != null) {
+      nl.add(key, val);
+    }
+  }
+
+  private void addVal(Map<String, Object> map, String key, Properties props, Class clzz) {
+    Object val = formatVal(key, props, clzz);
+    if (val != null) {
+      map.put(key, val);
+    }
+  }
+
+  private Object formatVal(String key, Properties props, Class clzz) {
     String s = props.getProperty(key);
-    if (s == null || s.trim().length() == 0) return;
+    if (s == null || s.trim().length() == 0) return null;
     if (clzz == Date.class) {
       try {
         Long l = Long.parseLong(s);
-        nl.add(key, new Date(l).toString());
-      } catch (NumberFormatException e) {/*no op*/ }
+        return new Date(l).toString();
+      } catch (NumberFormatException e) {
+        return null;
+      }
     } else if (clzz == List.class) {
       String ss[] = s.split(",");
       List<String> l = new ArrayList<>();
       for (String s1 : ss) {
         l.add(new Date(Long.valueOf(s1)).toString());
       }
-      nl.add(key, l);
+      return l;
     } else {
-      nl.add(key, s);
+      return s;
     }
-
   }
 
   private List<String> getReplicateAfterStrings() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
index 18ab7c7..6baa000 100644
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@ -144,6 +144,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
     requests = manager.counter(registryName, "requests", getCategory().toString(), scope);
     requestTimes = manager.timer(registryName, "requestTimes", getCategory().toString(), scope);
     totalTime = manager.counter(registryName, "totalTime", getCategory().toString(), scope);
+    manager.registerGauge(registryName, () -> handlerStart, true, "handlerStart", getCategory().toString(), scope);
   }
 
   public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {
@@ -271,22 +272,6 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
     return  pluginInfo;
   }
 
-
-  @Override
-  public NamedList<Object> getStatistics() {
-    NamedList<Object> lst = new SimpleOrderedMap<>();
-    lst.add("handlerStart",handlerStart);
-    lst.add("requests", requests.getCount());
-    lst.add("errors", numErrors.getCount());
-    lst.add("serverErrors", numServerErrors.getCount());
-    lst.add("clientErrors", numClientErrors.getCount());
-    lst.add("timeouts", numTimeouts.getCount());
-    // convert totalTime to ms
-    lst.add("totalTime", MetricUtils.nsToMs(totalTime.getCount()));
-    MetricUtils.addMetrics(lst, requestTimes);
-    return lst;
-  }
-
   @Override
   public Collection<Api> getApis() {
     return ImmutableList.of(new ApiBag.ReqHandlerToApi(this, ApiBag.constructSpec(pluginInfo)));

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
index e9af3d0..3bf3d3e 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
@@ -61,10 +61,6 @@ public class PluginInfoHandler extends RequestHandlerBase
 
         info.add( NAME,          (m.getName()       !=null ? m.getName()        : na) );
         info.add( "description", (m.getDescription()!=null ? m.getDescription() : na) );
-
-        if( stats ) {
-          info.add( "stats", m.getStatistics() );
-        }
       }
     }
     return list;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
index 4f8ba6a..d9cd21d 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
@@ -144,9 +144,6 @@ public class SolrInfoMBeanHandler extends RequestHandlerBase {
     mBeanInfo.add("class", m.getName());
     mBeanInfo.add("description", m.getDescription());
 
-    if (req.getParams().getFieldBool(key, "stats", false))
-      mBeanInfo.add("stats", m.getStatistics());
-
     catInfo.add(key, mBeanInfo);
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
index c566298..ad8ace9 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java
@@ -108,11 +108,6 @@ public abstract class SearchComponent implements SolrInfoBean, NamedListInitiali
     return Category.OTHER;
   }
 
-  @Override
-  public NamedList getStatistics() {
-    return null;
-  }
-
   public static final Map<String, Class<? extends SearchComponent>> standard_components;
   ;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
index bb87440..b591571 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
@@ -47,6 +47,9 @@ import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrEventListener;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
 import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.spelling.suggest.SolrSuggester;
 import org.apache.solr.spelling.suggest.SuggesterOptions;
@@ -61,7 +64,7 @@ import org.slf4j.LoggerFactory;
  * Responsible for routing commands and queries to the appropriate {@link SolrSuggester}
  * and for initializing them as specified by SolrConfig
  */
-public class SuggestComponent extends SearchComponent implements SolrCoreAware, SuggesterParams, Accountable {
+public class SuggestComponent extends SearchComponent implements SolrCoreAware, SuggesterParams, Accountable, SolrMetricProducer {
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   
   /** Name used to identify whether the user query concerns this component */
@@ -89,7 +92,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
    * Key is the dictionary name used in SolrConfig, value is the corresponding {@link SolrSuggester}
    */
   protected Map<String, SolrSuggester> suggesters = new ConcurrentHashMap<>();
-  
+
   /** Container for various labels used in the responses generated by this component */
   private static class SuggesterResultLabels {
     static final String SUGGEST = "suggest";
@@ -345,16 +348,19 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList<String> stats = new SimpleOrderedMap<>();
-    stats.add("totalSizeInBytes", String.valueOf(ramBytesUsed()));
-    for (Map.Entry<String, SolrSuggester> entry : suggesters.entrySet()) {
-      SolrSuggester suggester = entry.getValue();
-      stats.add(entry.getKey(), suggester.toString());
-    }
-    return stats;
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    manager.registerGauge(registry, () -> ramBytesUsed(), true, "totalSizeInBytes", getCategory().toString(), scope);
+    MetricsMap suggestersMap = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
+      for (Map.Entry<String, SolrSuggester> entry : suggesters.entrySet()) {
+        SolrSuggester suggester = entry.getValue();
+        map.put(entry.getKey(), suggester.toString());
+      }
+      return map;
+    };
+    manager.registerGauge(registry, suggestersMap, true, "suggesters", getCategory().toString(), scope);
   }
-  
+
   @Override
   public long ramBytesUsed() {
     long sizeInBytes = 0;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/GapFragmenter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/GapFragmenter.java b/solr/core/src/java/org/apache/solr/highlight/GapFragmenter.java
index 64cb280..6a11bb9 100644
--- a/solr/core/src/java/org/apache/solr/highlight/GapFragmenter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/GapFragmenter.java
@@ -30,7 +30,7 @@ public class GapFragmenter extends HighlightingPluginBase implements SolrFragmen
   @Override
   public Fragmenter getFragmenter(String fieldName, SolrParams params )
   {
-    numRequests++;
+    numRequests.inc();
     params = SolrParams.wrapDefaults(params, defaults);
     
     int fragsize = params.getFieldInt( fieldName, HighlightParams.FRAGSIZE, 100 );

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
index 94a5688..9f90b6d 100644
--- a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
+++ b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java
@@ -16,18 +16,21 @@
  */
 package org.apache.solr.highlight;
 
+import com.codahale.metrics.Counter;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrInfoBean;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
 
 /**
  * 
  * @since solr 1.3
  */
-public abstract class HighlightingPluginBase implements SolrInfoBean
+public abstract class HighlightingPluginBase implements SolrInfoBean, SolrMetricProducer
 {
-  protected long numRequests;
+  protected Counter numRequests;
   protected SolrParams defaults;
 
   public void init(NamedList args) {
@@ -56,10 +59,8 @@ public abstract class HighlightingPluginBase implements SolrInfoBean
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList<Long> lst = new SimpleOrderedMap<>();
-    lst.add("requests", numRequests);
-    return lst;
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    manager.counter(registry, "requests", getCategory().toString(), scope);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/HtmlFormatter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/HtmlFormatter.java b/solr/core/src/java/org/apache/solr/highlight/HtmlFormatter.java
index 842d5cd..0950c53 100644
--- a/solr/core/src/java/org/apache/solr/highlight/HtmlFormatter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/HtmlFormatter.java
@@ -29,7 +29,7 @@ public class HtmlFormatter extends HighlightingPluginBase implements SolrFormatt
   @Override
   public Formatter getFormatter(String fieldName, SolrParams params ) 
   {
-    numRequests++;
+    numRequests.inc();
     params = SolrParams.wrapDefaults(params, defaults);
 
     return new SimpleHTMLFormatter(

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/RegexFragmenter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/RegexFragmenter.java b/solr/core/src/java/org/apache/solr/highlight/RegexFragmenter.java
index b755b2d..ffefbad 100644
--- a/solr/core/src/java/org/apache/solr/highlight/RegexFragmenter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/RegexFragmenter.java
@@ -60,7 +60,7 @@ public class RegexFragmenter extends HighlightingPluginBase implements SolrFragm
   @Override
   public Fragmenter getFragmenter(String fieldName, SolrParams params )
   { 
-    numRequests++;
+    numRequests.inc();
     params = SolrParams.wrapDefaults(params, defaults);
 
     int fragsize  = params.getFieldInt(   fieldName, HighlightParams.FRAGSIZE,  LuceneRegexFragmenter.DEFAULT_FRAGMENT_SIZE );

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/SimpleFragListBuilder.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/SimpleFragListBuilder.java b/solr/core/src/java/org/apache/solr/highlight/SimpleFragListBuilder.java
index ed5430c..7e30a92 100644
--- a/solr/core/src/java/org/apache/solr/highlight/SimpleFragListBuilder.java
+++ b/solr/core/src/java/org/apache/solr/highlight/SimpleFragListBuilder.java
@@ -28,7 +28,7 @@ public class SimpleFragListBuilder extends HighlightingPluginBase implements
     // If that ever changes, it should wrap them with defaults...
     // params = SolrParams.wrapDefaults(params, defaults)
 
-    numRequests++;
+    numRequests.inc();
 
     return new org.apache.lucene.search.vectorhighlight.SimpleFragListBuilder();
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/SingleFragListBuilder.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/SingleFragListBuilder.java b/solr/core/src/java/org/apache/solr/highlight/SingleFragListBuilder.java
index 0b79929..0dfa16e 100644
--- a/solr/core/src/java/org/apache/solr/highlight/SingleFragListBuilder.java
+++ b/solr/core/src/java/org/apache/solr/highlight/SingleFragListBuilder.java
@@ -28,7 +28,7 @@ public class SingleFragListBuilder extends HighlightingPluginBase implements
     // If that ever changes, it should wrap them with defaults...
     // params = SolrParams.wrapDefaults(params, defaults)
 
-    numRequests++;
+    numRequests.inc();
 
     return new org.apache.lucene.search.vectorhighlight.SingleFragListBuilder();
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/SolrBoundaryScanner.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/SolrBoundaryScanner.java b/solr/core/src/java/org/apache/solr/highlight/SolrBoundaryScanner.java
index 2c768ce..ddbbfde 100644
--- a/solr/core/src/java/org/apache/solr/highlight/SolrBoundaryScanner.java
+++ b/solr/core/src/java/org/apache/solr/highlight/SolrBoundaryScanner.java
@@ -25,7 +25,7 @@ public abstract class SolrBoundaryScanner extends HighlightingPluginBase impleme
     SolrInfoBean, NamedListInitializedPlugin {
 
   public BoundaryScanner getBoundaryScanner(String fieldName, SolrParams params){
-    numRequests++;
+    numRequests.inc();
     params = SolrParams.wrapDefaults(params, defaults);
 
     return get(fieldName, params);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/SolrFragmentsBuilder.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/SolrFragmentsBuilder.java b/solr/core/src/java/org/apache/solr/highlight/SolrFragmentsBuilder.java
index b21b669..023d55a 100644
--- a/solr/core/src/java/org/apache/solr/highlight/SolrFragmentsBuilder.java
+++ b/solr/core/src/java/org/apache/solr/highlight/SolrFragmentsBuilder.java
@@ -37,7 +37,7 @@ public abstract class SolrFragmentsBuilder extends HighlightingPluginBase
    * @return An appropriate {@link org.apache.lucene.search.vectorhighlight.FragmentsBuilder}.
    */
   public FragmentsBuilder getFragmentsBuilder(SolrParams params, BoundaryScanner bs) {
-    numRequests++;
+    numRequests.inc();
     params = SolrParams.wrapDefaults(params, defaults);
 
     return getFragmentsBuilder( params, getPreTags( params, null ), getPostTags( params, null ), bs );

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/highlight/WeightedFragListBuilder.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/highlight/WeightedFragListBuilder.java b/solr/core/src/java/org/apache/solr/highlight/WeightedFragListBuilder.java
index f44c0f0..b97cc31 100644
--- a/solr/core/src/java/org/apache/solr/highlight/WeightedFragListBuilder.java
+++ b/solr/core/src/java/org/apache/solr/highlight/WeightedFragListBuilder.java
@@ -28,7 +28,7 @@ public class WeightedFragListBuilder extends HighlightingPluginBase implements
     // If that ever changes, it should wrap them with defaults...
     // params = SolrParams.wrapDefaults(params, defaults)
     
-    numRequests++;
+    numRequests.inc();
     
     return new org.apache.lucene.search.vectorhighlight.WeightedFragListBuilder();
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 39082ad..35c5860 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.search;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLRUCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,6 +29,7 @@ import java.lang.invoke.MethodHandles;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 
@@ -57,6 +60,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>
 
   private long maxRamBytes;
 
+  private MetricsMap cacheMap;
+
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
     super.init(args, regenerator);
@@ -215,62 +220,66 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList<Serializable> lst = new SimpleOrderedMap<>();
-    if (cache == null)  return lst;
-    ConcurrentLRUCache.Stats stats = cache.getStats();
-    long lookups = stats.getCumulativeLookups();
-    long hits = stats.getCumulativeHits();
-    long inserts = stats.getCumulativePuts();
-    long evictions = stats.getCumulativeEvictions();
-    long size = stats.getCurrentSize();
-    long clookups = 0;
-    long chits = 0;
-    long cinserts = 0;
-    long cevictions = 0;
-
-    // NOTE: It is safe to iterate on a CopyOnWriteArrayList
-    for (ConcurrentLRUCache.Stats statistiscs : statsList) {
-      clookups += statistiscs.getCumulativeLookups();
-      chits += statistiscs.getCumulativeHits();
-      cinserts += statistiscs.getCumulativePuts();
-      cevictions += statistiscs.getCumulativeEvictions();
-    }
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    cacheMap = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
+      if (cache != null) {
+        ConcurrentLRUCache.Stats stats = cache.getStats();
+        long lookups = stats.getCumulativeLookups();
+        long hits = stats.getCumulativeHits();
+        long inserts = stats.getCumulativePuts();
+        long evictions = stats.getCumulativeEvictions();
+        long size = stats.getCurrentSize();
+        long clookups = 0;
+        long chits = 0;
+        long cinserts = 0;
+        long cevictions = 0;
+
+        // NOTE: It is safe to iterate on a CopyOnWriteArrayList
+        for (ConcurrentLRUCache.Stats statistiscs : statsList) {
+          clookups += statistiscs.getCumulativeLookups();
+          chits += statistiscs.getCumulativeHits();
+          cinserts += statistiscs.getCumulativePuts();
+          cevictions += statistiscs.getCumulativeEvictions();
+        }
 
-    lst.add("lookups", lookups);
-    lst.add("hits", hits);
-    lst.add("hitratio", calcHitRatio(lookups, hits));
-    lst.add("inserts", inserts);
-    lst.add("evictions", evictions);
-    lst.add("size", size);
-
-    lst.add("warmupTime", warmupTime);
-    lst.add("cumulative_lookups", clookups);
-    lst.add("cumulative_hits", chits);
-    lst.add("cumulative_hitratio", calcHitRatio(clookups, chits));
-    lst.add("cumulative_inserts", cinserts);
-    lst.add("cumulative_evictions", cevictions);
-
-    if (showItems != 0) {
-      Map items = cache.getLatestAccessedItems( showItems == -1 ? Integer.MAX_VALUE : showItems );
-      for (Map.Entry e : (Set <Map.Entry>)items.entrySet()) {
-        Object k = e.getKey();
-        Object v = e.getValue();
-
-        String ks = "item_" + k;
-        String vs = v.toString();
-        lst.add(ks,vs);
-      }
-      
-    }
+        map.put("lookups", lookups);
+        map.put("hits", hits);
+        map.put("hitratio", calcHitRatio(lookups, hits));
+        map.put("inserts", inserts);
+        map.put("evictions", evictions);
+        map.put("size", size);
+
+        map.put("warmupTime", warmupTime);
+        map.put("cumulative_lookups", clookups);
+        map.put("cumulative_hits", chits);
+        map.put("cumulative_hitratio", calcHitRatio(clookups, chits));
+        map.put("cumulative_inserts", cinserts);
+        map.put("cumulative_evictions", cevictions);
+
+        if (detailed && showItems != 0) {
+          Map items = cache.getLatestAccessedItems( showItems == -1 ? Integer.MAX_VALUE : showItems );
+          for (Map.Entry e : (Set <Map.Entry>)items.entrySet()) {
+            Object k = e.getKey();
+            Object v = e.getValue();
+
+            String ks = "item_" + k;
+            String vs = v.toString();
+            map.put(ks,vs);
+          }
 
-    return lst;
+        }
+      }
+      return map;
+    };
+    manager.registerGauge(registry, cacheMap, true, getClass().getSimpleName(), getCategory().toString(), scope);
   }
 
   @Override
   public String toString() {
-    return name() + getStatistics().toString();
+    return name() + cacheMap != null ? cacheMap.getValue().toString() : "";
   }
+
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/LFUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 193134a..3841d0d 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -21,6 +21,7 @@ import java.net.URL;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 
@@ -28,6 +29,8 @@ import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.util.ConcurrentLFUCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,6 +67,7 @@ public class LFUCache<K, V> implements SolrCache<K, V> {
   private ConcurrentLFUCache<K, V> cache;
   private int showItems = 0;
   private Boolean timeDecay = true;
+  private MetricsMap cacheMap;
 
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -231,62 +235,67 @@ public class LFUCache<K, V> implements SolrCache<K, V> {
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList<Serializable> lst = new SimpleOrderedMap<>();
-    if (cache == null) return lst;
-    ConcurrentLFUCache.Stats stats = cache.getStats();
-    long lookups = stats.getCumulativeLookups();
-    long hits = stats.getCumulativeHits();
-    long inserts = stats.getCumulativePuts();
-    long evictions = stats.getCumulativeEvictions();
-    long size = stats.getCurrentSize();
-
-    lst.add("lookups", lookups);
-    lst.add("hits", hits);
-    lst.add("hitratio", calcHitRatio(lookups, hits));
-    lst.add("inserts", inserts);
-    lst.add("evictions", evictions);
-    lst.add("size", size);
-
-    lst.add("warmupTime", warmupTime);
-    lst.add("timeDecay", timeDecay);
-
-    long clookups = 0;
-    long chits = 0;
-    long cinserts = 0;
-    long cevictions = 0;
-
-    // NOTE: It is safe to iterate on a CopyOnWriteArrayList
-    for (ConcurrentLFUCache.Stats statistics : statsList) {
-      clookups += statistics.getCumulativeLookups();
-      chits += statistics.getCumulativeHits();
-      cinserts += statistics.getCumulativePuts();
-      cevictions += statistics.getCumulativeEvictions();
-    }
-    lst.add("cumulative_lookups", clookups);
-    lst.add("cumulative_hits", chits);
-    lst.add("cumulative_hitratio", calcHitRatio(clookups, chits));
-    lst.add("cumulative_inserts", cinserts);
-    lst.add("cumulative_evictions", cevictions);
-
-    if (showItems != 0) {
-      Map items = cache.getMostUsedItems(showItems == -1 ? Integer.MAX_VALUE : showItems);
-      for (Map.Entry e : (Set<Map.Entry>) items.entrySet()) {
-        Object k = e.getKey();
-        Object v = e.getValue();
-
-        String ks = "item_" + k;
-        String vs = v.toString();
-        lst.add(ks, vs);
-      }
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    cacheMap = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
+      if (cache != null) {
+        ConcurrentLFUCache.Stats stats = cache.getStats();
+        long lookups = stats.getCumulativeLookups();
+        long hits = stats.getCumulativeHits();
+        long inserts = stats.getCumulativePuts();
+        long evictions = stats.getCumulativeEvictions();
+        long size = stats.getCurrentSize();
+
+        map.put("lookups", lookups);
+        map.put("hits", hits);
+        map.put("hitratio", calcHitRatio(lookups, hits));
+        map.put("inserts", inserts);
+        map.put("evictions", evictions);
+        map.put("size", size);
+
+        map.put("warmupTime", warmupTime);
+        map.put("timeDecay", timeDecay);
+
+        long clookups = 0;
+        long chits = 0;
+        long cinserts = 0;
+        long cevictions = 0;
+
+        // NOTE: It is safe to iterate on a CopyOnWriteArrayList
+        for (ConcurrentLFUCache.Stats statistics : statsList) {
+          clookups += statistics.getCumulativeLookups();
+          chits += statistics.getCumulativeHits();
+          cinserts += statistics.getCumulativePuts();
+          cevictions += statistics.getCumulativeEvictions();
+        }
+        map.put("cumulative_lookups", clookups);
+        map.put("cumulative_hits", chits);
+        map.put("cumulative_hitratio", calcHitRatio(clookups, chits));
+        map.put("cumulative_inserts", cinserts);
+        map.put("cumulative_evictions", cevictions);
+
+        if (detailed && showItems != 0) {
+          Map items = cache.getMostUsedItems(showItems == -1 ? Integer.MAX_VALUE : showItems);
+          for (Map.Entry e : (Set<Map.Entry>) items.entrySet()) {
+            Object k = e.getKey();
+            Object v = e.getValue();
+
+            String ks = "item_" + k;
+            String vs = v.toString();
+            map.put(ks, vs);
+          }
 
-    }
+        }
 
-    return lst;
+      }
+      return map;
+    };
+    manager.registerGauge(registry, cacheMap, true, getClass().getSimpleName(), getCategory().toString(), scope);
   }
 
   @Override
   public String toString() {
-    return name + getStatistics().toString();
+    return name + cacheMap != null ? cacheMap.getValue().toString() : "";
   }
+
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/LRUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index db07659..f6762b6 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.LongAdder;
 
@@ -31,6 +32,8 @@ import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,6 +58,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   static final long LINKED_HASHTABLE_RAM_BYTES_PER_ENTRY =
       HASHTABLE_RAM_BYTES_PER_ENTRY
           + 2 * RamUsageEstimator.NUM_BYTES_OBJECT_REF; // previous & next references
+
   /// End copied code
 
   /* An instance of this class will be shared across multiple instances
@@ -82,6 +86,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
 
   private Map<K,V> map;
   private String description="LRU Cache";
+  private MetricsMap cacheMap;
 
   private long maxRamBytes = Long.MAX_VALUE;
   // The synchronization used for the map will be used to update this,
@@ -319,40 +324,43 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList lst = new SimpleOrderedMap();
-    synchronized (map) {
-      lst.add("lookups", lookups);
-      lst.add("hits", hits);
-      lst.add("hitratio", calcHitRatio(lookups,hits));
-      lst.add("inserts", inserts);
-      lst.add("evictions", evictions);
-      lst.add("size", map.size());
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    cacheMap = detailed -> {
+      Map<String, Object> res = new ConcurrentHashMap<>();
+      synchronized (map) {
+        res.put("lookups", lookups);
+        res.put("hits", hits);
+        res.put("hitratio", calcHitRatio(lookups,hits));
+        res.put("inserts", inserts);
+        res.put("evictions", evictions);
+        res.put("size", map.size());
+        if (maxRamBytes != Long.MAX_VALUE)  {
+          res.put("maxRamMB", maxRamBytes / 1024L / 1024L);
+          res.put("ramBytesUsed", ramBytesUsed());
+          res.put("evictionsRamUsage", evictionsRamUsage);
+        }
+      }
+      res.put("warmupTime", warmupTime);
+
+      long clookups = stats.lookups.longValue();
+      long chits = stats.hits.longValue();
+      res.put("cumulative_lookups", clookups);
+      res.put("cumulative_hits", chits);
+      res.put("cumulative_hitratio", calcHitRatio(clookups, chits));
+      res.put("cumulative_inserts", stats.inserts.longValue());
+      res.put("cumulative_evictions", stats.evictions.longValue());
       if (maxRamBytes != Long.MAX_VALUE)  {
-        lst.add("maxRamMB", maxRamBytes / 1024L / 1024L);
-        lst.add("ramBytesUsed", ramBytesUsed());
-        lst.add("evictionsRamUsage", evictionsRamUsage);
+        res.put("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue());
       }
-    }
-    lst.add("warmupTime", warmupTime);
-    
-    long clookups = stats.lookups.longValue();
-    long chits = stats.hits.longValue();
-    lst.add("cumulative_lookups", clookups);
-    lst.add("cumulative_hits", chits);
-    lst.add("cumulative_hitratio", calcHitRatio(clookups, chits));
-    lst.add("cumulative_inserts", stats.inserts.longValue());
-    lst.add("cumulative_evictions", stats.evictions.longValue());
-    if (maxRamBytes != Long.MAX_VALUE)  {
-      lst.add("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue());
-    }
-    
-    return lst;
-  }
 
+      return res;
+    };
+    manager.registerGauge(registry, cacheMap, true, getClass().getSimpleName(), getCategory().toString(), scope);
+  }
+  
   @Override
   public String toString() {
-    return name() + getStatistics().toString();
+    return name() + cacheMap != null ? cacheMap.getValue().toString() : "";
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
index 04d5d51..c82e2fc 100644
--- a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java
@@ -107,10 +107,6 @@ public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrI
     return Category.QUERYPARSER;
   }
 
-  @Override
-  public NamedList getStatistics() {
-    return null;
-  }
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/SolrCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 8f448e91..caa5c2c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -17,6 +17,7 @@
 package org.apache.solr.search;
 
 import org.apache.solr.core.SolrInfoBean;
+import org.apache.solr.metrics.SolrMetricProducer;
 
 import java.util.Map;
 
@@ -24,7 +25,7 @@ import java.util.Map;
 /**
  * Primary API for dealing with Solr's internal caches.
  */
-public interface SolrCache<K,V> extends SolrInfoBean {
+public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer {
 
   /**
    * The initialization routine. Instance specific arguments are passed in

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/SolrCacheBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheBase.java b/solr/core/src/java/org/apache/solr/search/SolrCacheBase.java
index 3f6fb15..3e969dd 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheBase.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheBase.java
@@ -106,10 +106,6 @@ public abstract class SolrCacheBase {
     return Category.CACHE;
   }
 
-  public URL[] getDocs() {
-    return null;
-  }
-  
   public void init(Map<String, String> args, CacheRegenerator regenerator) {
     this.regenerator = regenerator;
     state = State.CREATED;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
index 4677445..e307031 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
@@ -47,10 +47,6 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer {
   }
   @Override
   public Category getCategory() { return Category.CACHE; } 
-  @Override
-  public NamedList getStatistics() {
-    return new NamedList(metricsMap.getValue(!disableEntryList));
-  }
 
   @Override
   public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 75a858d..e13769f 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -103,15 +103,15 @@ import org.apache.solr.common.SolrDocumentBase;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.ModifiableSolrParams;
-import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.ObjectReleaseTracker;
-import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.DirectoryFactory;
 import org.apache.solr.core.DirectoryFactory.DirContext;
 import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.index.SlowCompositeReaderWrapper;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestInfo;
@@ -140,7 +140,7 @@ import com.google.common.collect.Iterables;
  *
  * @since solr 0.9
  */
-public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrInfoBean {
+public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrInfoBean, SolrMetricProducer {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -201,8 +201,6 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
   private final String path;
   private boolean releaseDirectory;
 
-  private final NamedList<Object> readerStats;
-
   private static DirectoryReader getReader(SolrCore core, SolrIndexConfig config, DirectoryFactory directoryFactory,
       String path) throws IOException {
     final Directory dir = directoryFactory.get(path, DirContext.DEFAULT, config.lockType);
@@ -388,7 +386,6 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
     // We already have our own filter cache
     setQueryCache(null);
 
-    readerStats = snapStatistics(reader);
     // do this at the end since an exception in the constructor means we won't close
     numOpens.incrementAndGet();
     assert ObjectReleaseTracker.track(this);
@@ -2605,28 +2602,23 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
   }
 
   @Override
-  public NamedList<Object> getStatistics() {
-    final NamedList<Object> lst = new SimpleOrderedMap<>();
-    lst.add("searcherName", name);
-    lst.add("caching", cachingEnabled);
-
-    lst.addAll(readerStats);
-
-    lst.add("openedAt", openTime);
-    if (registerTime != null) lst.add("registeredAt", registerTime);
-    lst.add("warmupTime", warmupTime);
-    return lst;
-  }
-
-  static private NamedList<Object> snapStatistics(DirectoryReader reader) {
-    final NamedList<Object> lst = new SimpleOrderedMap<>();
-    lst.add("numDocs", reader.numDocs());
-    lst.add("maxDoc", reader.maxDoc());
-    lst.add("deletedDocs", reader.maxDoc() - reader.numDocs());
-    lst.add("reader", reader.toString());
-    lst.add("readerDir", reader.directory());
-    lst.add("indexVersion", reader.getVersion());
-    return lst;
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+
+    manager.registerGauge(registry, () -> name, true, "searcherName", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> cachingEnabled, true, "caching", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> openTime, true, "openedAt", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> warmupTime, true, "warmupTime", Category.SEARCHER.toString(), scope);
+    if (registerTime != null) {
+      manager.registerGauge(registry, () -> registerTime, true, "registeredAt", Category.SEARCHER.toString(), scope);
+    }
+    // reader stats
+    manager.registerGauge(registry, () -> reader.numDocs(), true, "numDocs", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> reader.maxDoc(), true, "maxDoc", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> reader.maxDoc() - reader.numDocs(), true, "deletedDocs", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> reader.toString(), true, "reader", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> reader.directory().toString(), true, "readerDir", Category.SEARCHER.toString(), scope);
+    manager.registerGauge(registry, () -> reader.getVersion(), true, "indexVersion", Category.SEARCHER.toString(), scope);
+
   }
 
   private static class FilterImpl extends Filter {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
index fc331ea..6fd7c4b 100644
--- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
+++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
@@ -32,10 +32,13 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.SolrInfoBean;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class HdfsLocalityReporter implements SolrInfoBean {
+public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer {
   public static final String LOCALITY_BYTES_TOTAL = "locality.bytes.total";
   public static final String LOCALITY_BYTES_LOCAL = "locality.bytes.local";
   public static final String LOCALITY_BYTES_RATIO = "locality.bytes.ratio";
@@ -79,76 +82,59 @@ public class HdfsLocalityReporter implements SolrInfoBean {
    * Provide statistics on HDFS block locality, both in terms of bytes and block counts.
    */
   @Override
-  public NamedList getStatistics() {
-    long totalBytes = 0;
-    long localBytes = 0;
-    int totalCount = 0;
-    int localCount = 0;
-
-    for (Iterator<HdfsDirectory> iterator = cache.keySet().iterator(); iterator.hasNext();) {
-      HdfsDirectory hdfsDirectory = iterator.next();
-
-      if (hdfsDirectory.isClosed()) {
-        iterator.remove();
-      } else {
-        try {
-          refreshDirectory(hdfsDirectory);
-          Map<FileStatus,BlockLocation[]> blockMap = cache.get(hdfsDirectory);
-
-          // For every block in every file in this directory, count it
-          for (BlockLocation[] locations : blockMap.values()) {
-            for (BlockLocation bl : locations) {
-              totalBytes += bl.getLength();
-              totalCount++;
-
-              if (Arrays.asList(bl.getHosts()).contains(hostname)) {
-                localBytes += bl.getLength();
-                localCount++;
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    MetricsMap metricsMap = detailed -> {
+      Map<String, Object> map = new ConcurrentHashMap<>();
+      long totalBytes = 0;
+      long localBytes = 0;
+      int totalCount = 0;
+      int localCount = 0;
+
+      for (Iterator<HdfsDirectory> iterator = cache.keySet().iterator(); iterator.hasNext();) {
+        HdfsDirectory hdfsDirectory = iterator.next();
+
+        if (hdfsDirectory.isClosed()) {
+          iterator.remove();
+        } else {
+          try {
+            refreshDirectory(hdfsDirectory);
+            Map<FileStatus,BlockLocation[]> blockMap = cache.get(hdfsDirectory);
+
+            // For every block in every file in this directory, count it
+            for (BlockLocation[] locations : blockMap.values()) {
+              for (BlockLocation bl : locations) {
+                totalBytes += bl.getLength();
+                totalCount++;
+
+                if (Arrays.asList(bl.getHosts()).contains(hostname)) {
+                  localBytes += bl.getLength();
+                  localCount++;
+                }
               }
             }
+          } catch (IOException e) {
+            logger.warn("Could not retrieve locality information for {} due to exception: {}",
+                hdfsDirectory.getHdfsDirPath(), e);
           }
-        } catch (IOException e) {
-          logger.warn("Could not retrieve locality information for {} due to exception: {}",
-              hdfsDirectory.getHdfsDirPath(), e);
         }
       }
-    }
-
-    return createStatistics(totalBytes, localBytes, totalCount, localCount);
-  }
-
-  /**
-   * Generate a statistics object based on the given measurements for all files monitored by this reporter.
-   * 
-   * @param totalBytes
-   *          The total bytes used
-   * @param localBytes
-   *          The amount of bytes found on local nodes
-   * @param totalCount
-   *          The total block count
-   * @param localCount
-   *          The amount of blocks found on local nodes
-   * @return HDFS block locality statistics
-   */
-  private NamedList<Number> createStatistics(long totalBytes, long localBytes, int totalCount, int localCount) {
-    NamedList<Number> statistics = new SimpleOrderedMap<Number>();
-
-    statistics.add(LOCALITY_BYTES_TOTAL, totalBytes);
-    statistics.add(LOCALITY_BYTES_LOCAL, localBytes);
-    if (localBytes == 0) {
-      statistics.add(LOCALITY_BYTES_RATIO, 0);
-    } else {
-      statistics.add(LOCALITY_BYTES_RATIO, localBytes / (double) totalBytes);
-    }
-    statistics.add(LOCALITY_BLOCKS_TOTAL, totalCount);
-    statistics.add(LOCALITY_BLOCKS_LOCAL, localCount);
-    if (localCount == 0) {
-      statistics.add(LOCALITY_BLOCKS_RATIO, 0);
-    } else {
-      statistics.add(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount);
-    }
-
-    return statistics;
+      map.put(LOCALITY_BYTES_TOTAL, totalBytes);
+      map.put(LOCALITY_BYTES_LOCAL, localBytes);
+      if (localBytes == 0) {
+        map.put(LOCALITY_BYTES_RATIO, 0);
+      } else {
+        map.put(LOCALITY_BYTES_RATIO, localBytes / (double) totalBytes);
+      }
+      map.put(LOCALITY_BLOCKS_TOTAL, totalCount);
+      map.put(LOCALITY_BLOCKS_LOCAL, localCount);
+      if (localCount == 0) {
+        map.put(LOCALITY_BLOCKS_RATIO, 0);
+      } else {
+        map.put(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount);
+      }
+      return map;
+    };
+    manager.registerGauge(registry, metricsMap, true, "hdfsLocality", getCategory().toString(), scope);
   }
 
   /**
@@ -193,4 +179,5 @@ public class HdfsLocalityReporter implements SolrInfoBean {
       }
     }
   }
+
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
index 445d1ce..6d5bce2 100644
--- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
+++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
@@ -165,6 +165,22 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
     commitCommands = manager.meter(registry, "commits", getCategory().toString(), scope);
     manager.registerGauge(registry, () -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString(), scope);
     manager.registerGauge(registry, () -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString(), scope);
+    if (commitTracker.getDocsUpperBound() > 0) {
+      manager.registerGauge(registry, () -> commitTracker.getDocsUpperBound(), true, "autoCommitMaxDocs",
+          getCategory().toString(), scope);
+    }
+    if (commitTracker.getTimeUpperBound() > 0) {
+      manager.registerGauge(registry, () -> "" + commitTracker.getTimeUpperBound() + "ms", true, "autoCommitMaxTime",
+          getCategory().toString(), scope);
+    }
+    if (softCommitTracker.getDocsUpperBound() > 0) {
+      manager.registerGauge(registry, () -> softCommitTracker.getDocsUpperBound(), true, "softAutoCommitMaxDocs",
+          getCategory().toString(), scope);
+    }
+    if (softCommitTracker.getTimeUpperBound() > 0) {
+      manager.registerGauge(registry, () -> "" + softCommitTracker.getTimeUpperBound() + "ms", true, "softAutoCommitMaxTime",
+          getCategory().toString(), scope);
+    }
     optimizeCommands = manager.meter(registry, "optimizes", getCategory().toString(), scope);
     rollbackCommands = manager.meter(registry, "rollbacks", getCategory().toString(), scope);
     splitCommands = manager.meter(registry, "splits", getCategory().toString(), scope);
@@ -965,50 +981,6 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
   }
 
   @Override
-  public NamedList getStatistics() {
-    NamedList lst = new SimpleOrderedMap();
-    lst.add("commits", commitCommands.getCount());
-    if (commitTracker.getDocsUpperBound() > 0) {
-      lst.add("autocommit maxDocs", commitTracker.getDocsUpperBound());
-    }
-    if (commitTracker.getTimeUpperBound() > 0) {
-      lst.add("autocommit maxTime", "" + commitTracker.getTimeUpperBound() + "ms");
-    }
-    lst.add("autocommits", commitTracker.getCommitCount());
-    if (softCommitTracker.getDocsUpperBound() > 0) {
-      lst.add("soft autocommit maxDocs", softCommitTracker.getDocsUpperBound());
-    }
-    if (softCommitTracker.getTimeUpperBound() > 0) {
-      lst.add("soft autocommit maxTime", "" + softCommitTracker.getTimeUpperBound() + "ms");
-    }
-    lst.add("soft autocommits", softCommitTracker.getCommitCount());
-    lst.add("optimizes", optimizeCommands.getCount());
-    lst.add("rollbacks", rollbackCommands.getCount());
-    lst.add("expungeDeletes", expungeDeleteCommands.getCount());
-    lst.add("docsPending", numDocsPending.longValue());
-    // pset.size() not synchronized, but it should be fine to access.
-    // lst.add("deletesPending", pset.size());
-    lst.add("adds", addCommands.longValue());
-    lst.add("deletesById", deleteByIdCommands.longValue());
-    lst.add("deletesByQuery", deleteByQueryCommands.longValue());
-    lst.add("errors", numErrors.longValue());
-    lst.add("cumulative_adds", addCommandsCumulative.getCount());
-    lst.add("cumulative_deletesById", deleteByIdCommandsCumulative.getCount());
-    lst.add("cumulative_deletesByQuery", deleteByQueryCommandsCumulative.getCount());
-    lst.add("cumulative_errors", numErrorsCumulative.getCount());
-    if (this.ulog != null) {
-      lst.add("transaction_logs_total_size", ulog.getTotalLogsSize());
-      lst.add("transaction_logs_total_number", ulog.getTotalLogsNumber());
-    }
-    return lst;
-  }
-
-  @Override
-  public String toString() {
-    return "DirectUpdateHandler2" + getStatistics();
-  }
-  
-  @Override
   public SolrCoreState getSolrCoreState() {
     return solrCoreState;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index 1f4d18c..2e5f958 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -125,11 +125,6 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean {
     return Category.UPDATE;
   }
 
-  @Override
-  public NamedList getStatistics() {
-    return null;
-  }
-
   public HttpClient getHttpClient() {
     return client;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java b/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
index ba1284e..1007234 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
@@ -226,7 +226,7 @@ public class MetricUtils {
         });
   }
 
-  static Map<String, Object> convertAggregateMetric(AggregateMetric metric, boolean skipAggregateValues) {
+  public static Map<String, Object> convertAggregateMetric(AggregateMetric metric, boolean skipAggregateValues) {
     Map<String, Object> response = new LinkedHashMap<>();
     response.put("count", metric.size());
     response.put(MAX, metric.getMax());
@@ -247,7 +247,7 @@ public class MetricUtils {
     return response;
   }
 
-  static Map<String, Object> convertHistogram(Histogram histogram) {
+  public static Map<String, Object> convertHistogram(Histogram histogram) {
     Map<String, Object> response = new LinkedHashMap<>();
     Snapshot snapshot = histogram.getSnapshot();
     response.put("count", histogram.getCount());
@@ -266,7 +266,7 @@ public class MetricUtils {
   }
 
   // some snapshots represent time in ns, other snapshots represent raw values (eg. chunk size)
-  static void addSnapshot(Map<String, Object> response, Snapshot snapshot, boolean ms) {
+  public static void addSnapshot(Map<String, Object> response, Snapshot snapshot, boolean ms) {
     response.put((ms ? MIN_MS: MIN), nsToMs(ms, snapshot.getMin()));
     response.put((ms ? MAX_MS: MAX), nsToMs(ms, snapshot.getMax()));
     response.put((ms ? MEAN_MS : MEAN), nsToMs(ms, snapshot.getMean()));
@@ -278,7 +278,7 @@ public class MetricUtils {
     response.put((ms ? P999_MS: P999), nsToMs(ms, snapshot.get999thPercentile()));
   }
 
-  static Map<String,Object> convertTimer(Timer timer, boolean skipHistograms) {
+  public static Map<String,Object> convertTimer(Timer timer, boolean skipHistograms) {
     Map<String, Object> response = new LinkedHashMap<>();
     response.put("count", timer.getCount());
     response.put("meanRate", timer.getMeanRate());
@@ -292,7 +292,7 @@ public class MetricUtils {
     return response;
   }
 
-  static Map<String, Object> convertMeter(Meter meter) {
+  public static Map<String, Object> convertMeter(Meter meter) {
     Map<String, Object> response = new LinkedHashMap<>();
     response.put("count", meter.getCount());
     response.put("meanRate", meter.getMeanRate());
@@ -302,7 +302,7 @@ public class MetricUtils {
     return response;
   }
 
-  static Object convertGauge(Gauge gauge, boolean compact) {
+  public static Object convertGauge(Gauge gauge, boolean compact) {
     if (compact) {
       return gauge.getValue();
     } else {
@@ -312,7 +312,7 @@ public class MetricUtils {
     }
   }
 
-  static Object convertCounter(Counter counter, boolean compact) {
+  public static Object convertCounter(Counter counter, boolean compact) {
     if (compact) {
       return counter.getCount();
     } else {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/test-files/solr/solr-jmxreporter.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/solr-jmxreporter.xml b/solr/core/src/test-files/solr/solr-jmxreporter.xml
new file mode 100644
index 0000000..bb9d05d
--- /dev/null
+++ b/solr/core/src/test-files/solr/solr-jmxreporter.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<solr>
+  <shardHandlerFactory name="shardHandlerFactory" class="HttpShardHandlerFactory">
+    <str name="urlScheme">${urlScheme:}</str>
+    <int name="socketTimeout">${socketTimeout:90000}</int>
+    <int name="connTimeout">${connTimeout:15000}</int>
+  </shardHandlerFactory>
+
+  <solrcloud>
+    <str name="host">127.0.0.1</str>
+    <int name="hostPort">${hostPort:8983}</int>
+    <str name="hostContext">${hostContext:solr}</str>
+    <int name="zkClientTimeout">${solr.zkclienttimeout:30000}</int>
+    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
+    <int name="leaderVoteWait">${leaderVoteWait:10000}</int>
+    <int name="distribUpdateConnTimeout">${distribUpdateConnTimeout:45000}</int>
+    <int name="distribUpdateSoTimeout">${distribUpdateSoTimeout:340000}</int>
+    <int name="autoReplicaFailoverWaitAfterExpiration">${autoReplicaFailoverWaitAfterExpiration:10000}</int>
+    <int name="autoReplicaFailoverWorkLoopDelay">${autoReplicaFailoverWorkLoopDelay:10000}</int>
+    <int name="autoReplicaFailoverBadNodeExpiration">${autoReplicaFailoverBadNodeExpiration:60000}</int>
+  </solrcloud>
+
+  <metrics>
+    <reporter name="defaultJmx" class="org.apache.solr.metrics.reporters.SolrJmxReporter"/>
+  </metrics>
+</solr>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b94db28c/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
index 6525ab4..0ab7500 100644
--- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
@@ -558,7 +558,7 @@ public class CollectionsAPIDistributedZkTest extends SolrCloudTestCase {
     for (SolrCore core : theCores) {
 
       // look for core props file
-      Path instancedir = (Path) core.getStatistics().get("instanceDir");
+      Path instancedir = (Path) core.getResourceLoader().getInstancePath();
       assertTrue("Could not find expected core.properties file", Files.exists(instancedir.resolve("core.properties")));
 
       Path expected = Paths.get(jetty.getSolrHome()).toAbsolutePath().resolve(core.getName());