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/14 11:36:22 UTC

[1/2] lucene-solr:branch_6x: SOLR-10247: Fix a cherry-pick issue.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x a7e9dbc56 -> 0e3b0b05f


SOLR-10247: Fix a cherry-pick issue.


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

Branch: refs/heads/branch_6x
Commit: 0e3b0b05fc1e1faf8943d8a55bdc62141c10583b
Parents: cd4cc72
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Tue Mar 14 12:28:31 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Tue Mar 14 12:36:04 2017 +0100

----------------------------------------------------------------------
 .../test/org/apache/solr/handler/admin/MetricsHandlerTest.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0e3b0b05/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
index e2f4132..81e14d9 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
@@ -57,9 +57,9 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
     assertEquals(0L, ((Map) nl.get("SEARCHER.new.errors")).get("count"));
     nl = (NamedList) values.get("solr.node");
     assertNotNull(nl.get("CONTAINER.cores.loaded")); // int gauge
-    assertEquals(1, ((NamedList) nl.get("CONTAINER.cores.loaded")).get("value"));
+    assertEquals(1, ((Map) nl.get("CONTAINER.cores.loaded")).get("value"));
     assertNotNull(nl.get("ADMIN./admin/authorization.clientErrors")); // timer type
-    assertEquals(5, ((NamedList) nl.get("ADMIN./admin/authorization.clientErrors")).size());
+    assertEquals(5, ((Map) nl.get("ADMIN./admin/authorization.clientErrors")).size());
 
     resp = new SolrQueryResponse();
     handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", "group", "jvm,jetty"), resp);


[2/2] lucene-solr:branch_6x: SOLR-10247: Support non-numeric metrics and a "compact" format of /admin/metrics.

Posted by ab...@apache.org.
SOLR-10247: Support non-numeric metrics and a "compact" format of /admin/metrics.


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

Branch: refs/heads/branch_6x
Commit: cd4cc72b8ea27dba111c6bcd874bc1726b0f8e05
Parents: a7e9dbc
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Tue Mar 14 11:17:56 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Tue Mar 14 12:36:04 2017 +0100

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   2 +
 .../org/apache/solr/core/CoreContainer.java     |  18 +-
 .../src/java/org/apache/solr/core/SolrCore.java |  36 ++--
 .../solr/handler/admin/MetricsHandler.java      |   6 +-
 .../apache/solr/metrics/SolrMetricManager.java  |   5 +-
 .../solr/update/DirectUpdateHandler2.java       |  22 +--
 .../org/apache/solr/update/SolrIndexWriter.java |  25 +--
 .../java/org/apache/solr/update/UpdateLog.java  |  14 +-
 ...trumentedPoolingClientConnectionManager.java |  37 +---
 .../org/apache/solr/util/stats/MetricUtils.java | 193 +++++++++++--------
 .../solr/handler/admin/MetricsHandlerTest.java  |  27 ++-
 .../solr/update/DirectUpdateHandlerTest.java    |  18 +-
 .../solr/update/SolrIndexMetricsTest.java       |   5 +-
 .../apache/solr/util/stats/MetricUtilsTest.java |  70 ++++++-
 14 files changed, 284 insertions(+), 194 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 1050492..ff7fb2f 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -272,6 +272,8 @@ Other Changes
 
 * SOLR-8876: change morphline test config files to work around 'importCommands' bug when using java9 (hossman)
 
+* SOLR-10247: Support non-numeric metrics and a "compact" format of /admin/metrics output. (ab)
+
 ==================  6.4.2 ==================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 8698713..981b7bc 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -36,7 +36,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
-import com.codahale.metrics.Gauge;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import org.apache.lucene.index.CorruptIndexException;
@@ -506,16 +505,13 @@ public class CoreContainer {
     containerProperties.putAll(cfg.getSolrProperties());
 
     // initialize gauges for reporting the number of cores
-    Gauge<Integer> loadedCores = () -> solrCores.getCores().size();
-    Gauge<Integer> lazyCores = () -> solrCores.getCoreNames().size() - solrCores.getCores().size();
-    Gauge<Integer> unloadedCores = () -> solrCores.getAllCoreNames().size() - solrCores.getCoreNames().size();
-
-    metricManager.register(SolrMetricManager.getRegistryName(SolrInfoMBean.Group.node),
-        loadedCores, true, "loaded", SolrInfoMBean.Category.CONTAINER.toString(), "cores");
-    metricManager.register(SolrMetricManager.getRegistryName(SolrInfoMBean.Group.node),
-        lazyCores, true, "lazy",SolrInfoMBean.Category.CONTAINER.toString(), "cores");
-    metricManager.register(SolrMetricManager.getRegistryName(SolrInfoMBean.Group.node),
-        unloadedCores, true, "unloaded",SolrInfoMBean.Category.CONTAINER.toString(), "cores");
+    String registryName = SolrMetricManager.getRegistryName(SolrInfoMBean.Group.node);
+    metricManager.registerGauge(registryName, () -> solrCores.getCores().size(),
+        true, "loaded", SolrInfoMBean.Category.CONTAINER.toString(), "cores");
+    metricManager.registerGauge(registryName, () -> solrCores.getCoreNames().size() - solrCores.getCores().size(),
+        true, "lazy",SolrInfoMBean.Category.CONTAINER.toString(), "cores");
+    metricManager.registerGauge(registryName, () -> solrCores.getAllCoreNames().size() - solrCores.getCoreNames().size(),
+        true, "unloaded",SolrInfoMBean.Category.CONTAINER.toString(), "cores");
 
     // setup executor to load cores in parallel
     ExecutorService coreLoadExecutor = MetricUtils.instrumentedExecutorService(

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/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 228de1d..8cc3ceb 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -168,7 +168,7 @@ import static org.apache.solr.common.params.CommonParams.PATH;
 /**
  *
  */
-public final class SolrCore implements SolrInfoMBean, Closeable {
+public final class SolrCore implements SolrInfoMBean, SolrMetricProducer, Closeable {
 
   public static final String version="1.0";
 
@@ -213,11 +213,11 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
   private final ReentrantLock ruleExpiryLock;
   private final ReentrantLock snapshotDelLock; // A lock instance to guard against concurrent deletions.
 
-  private final Timer newSearcherTimer;
-  private final Timer newSearcherWarmupTimer;
-  private final Counter newSearcherCounter;
-  private final Counter newSearcherMaxReachedCounter;
-  private final Counter newSearcherOtherErrorsCounter;
+  private Timer newSearcherTimer;
+  private Timer newSearcherWarmupTimer;
+  private Counter newSearcherCounter;
+  private Counter newSearcherMaxReachedCounter;
+  private Counter newSearcherOtherErrorsCounter;
 
   public Date getStartTimeStamp() { return startTime; }
 
@@ -882,11 +882,7 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
     SolrMetricManager metricManager = this.coreDescriptor.getCoreContainer().getMetricManager();
 
     // initialize searcher-related metrics
-    newSearcherCounter = metricManager.counter(coreMetricManager.getRegistryName(), "new", Category.SEARCHER.toString());
-    newSearcherTimer = metricManager.timer(coreMetricManager.getRegistryName(), "time", Category.SEARCHER.toString(), "new");
-    newSearcherWarmupTimer = metricManager.timer(coreMetricManager.getRegistryName(), "warmup", Category.SEARCHER.toString(), "new");
-    newSearcherMaxReachedCounter = metricManager.counter(coreMetricManager.getRegistryName(), "maxReached", Category.SEARCHER.toString(), "new");
-    newSearcherOtherErrorsCounter = metricManager.counter(coreMetricManager.getRegistryName(), "errors", Category.SEARCHER.toString(), "new");
+    initializeMetrics(metricManager, coreMetricManager.getRegistryName(), null);
 
     // Initialize JMX
     this.infoRegistry = initInfoRegistry(name, config);
@@ -1107,6 +1103,24 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
     return coreMetricManager;
   }
 
+  @Override
+  public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
+    newSearcherCounter = manager.counter(registry, "new", Category.SEARCHER.toString());
+    newSearcherTimer = manager.timer(registry, "time", Category.SEARCHER.toString(), "new");
+    newSearcherWarmupTimer = manager.timer(registry, "warmup", Category.SEARCHER.toString(), "new");
+    newSearcherMaxReachedCounter = manager.counter(registry, "maxReached", Category.SEARCHER.toString(), "new");
+    newSearcherOtherErrorsCounter = manager.counter(registry, "errors", Category.SEARCHER.toString(), "new");
+
+    manager.registerGauge(registry, () -> name == null ? "(null)" : name, true, "coreName", Category.CORE.toString());
+    manager.registerGauge(registry, () -> startTime, true, "startTime", Category.CORE.toString());
+    manager.registerGauge(registry, () -> getOpenCount(), true, "refCount", Category.CORE.toString());
+    manager.registerGauge(registry, () -> resourceLoader.getInstancePath(), true, "instanceDir", Category.CORE.toString());
+    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());
+  }
+
   private Map<String,SolrInfoMBean> initInfoRegistry(String name, SolrConfig config) {
     if (config.jmxConfig.enabled) {
       return new JmxMonitoredMap<String, SolrInfoMBean>(name, String.valueOf(this.hashCode()), config.jmxConfig);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
index 385317b..25f317c 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/MetricsHandler.java
@@ -50,6 +50,8 @@ public class MetricsHandler extends RequestHandlerBase implements PermissionName
   final CoreContainer container;
   final SolrMetricManager metricManager;
 
+  public static final String COMPACT_PARAM = "compact";
+
   public MetricsHandler() {
     this.container = null;
     this.metricManager = null;
@@ -71,6 +73,7 @@ public class MetricsHandler extends RequestHandlerBase implements PermissionName
       throw new SolrException(SolrException.ErrorCode.INVALID_STATE, "Core container instance not initialized");
     }
 
+    boolean compact = req.getParams().getBool(COMPACT_PARAM, false);
     MetricFilter mustMatchFilter = parseMustMatchFilter(req);
     List<MetricType> metricTypes = parseMetricTypes(req);
     List<MetricFilter> metricFilters = metricTypes.stream().map(MetricType::asMetricFilter).collect(Collectors.toList());
@@ -79,7 +82,8 @@ public class MetricsHandler extends RequestHandlerBase implements PermissionName
     NamedList response = new NamedList();
     for (String registryName : requestedRegistries) {
       MetricRegistry registry = metricManager.registry(registryName);
-      response.add(registryName, MetricUtils.toNamedList(registry, metricFilters, mustMatchFilter));
+      response.add(registryName, MetricUtils.toNamedList(registry, metricFilters, mustMatchFilter, false,
+          false, compact, null));
     }
     rsp.getValues().add("metrics", response);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
index cac5389..cdc1adf 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -31,6 +31,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
 import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.Metric;
@@ -384,7 +385,9 @@ public class SolrMetricManager {
     }
   }
 
-
+  public void registerGauge(String registry, Gauge<?> gauge, boolean force, String metricName, String... metricPath) {
+    register(registry, gauge, force, metricName, metricPath);
+  }
 
   /**
    * This method creates a hierarchical name with arbitrary levels of hierarchy

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/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 73e316b..a893260 100644
--- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
+++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
@@ -26,7 +26,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.LongAdder;
 
-import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Meter;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -154,25 +153,18 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
   @Override
   public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
     commitCommands = manager.meter(registry, "commits", getCategory().toString(), scope);
-    Gauge<Integer> autoCommits = () -> commitTracker.getCommitCount();
-    manager.register(registry, autoCommits, true, "autoCommits", getCategory().toString(), scope);
-    Gauge<Integer> softAutoCommits = () -> softCommitTracker.getCommitCount();
-    manager.register(registry, softAutoCommits, true, "softAutoCommits", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> softCommitTracker.getCommitCount(), true, "softAutoCommits", 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);
     mergeIndexesCommands = manager.meter(registry, "merges", getCategory().toString(), scope);
     expungeDeleteCommands = manager.meter(registry, "expungeDeletes", getCategory().toString(), scope);
-    Gauge<Long> docsPending = () -> numDocsPending.longValue();
-    manager.register(registry, docsPending, true, "docsPending", getCategory().toString(), scope);
-    Gauge<Long> adds = () -> addCommands.longValue();
-    manager.register(registry, adds, true, "adds", getCategory().toString(), scope);
-    Gauge<Long> deletesById = () -> deleteByIdCommands.longValue();
-    manager.register(registry, deletesById, true, "deletesById", getCategory().toString(), scope);
-    Gauge<Long> deletesByQuery = () -> deleteByQueryCommands.longValue();
-    manager.register(registry, deletesByQuery, true, "deletesByQuery", getCategory().toString(), scope);
-    Gauge<Long> errors = () -> numErrors.longValue();
-    manager.register(registry, errors, true, "errors", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> numDocsPending.longValue(), true, "docsPending", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> addCommands.longValue(), true, "adds", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString(), scope);
+    manager.registerGauge(registry, () -> numErrors.longValue(), true, "errors", getCategory().toString(), scope);
 
     addCommandsCumulative = manager.meter(registry, "cumulativeAdds", getCategory().toString(), scope);
     deleteByIdCommandsCumulative = manager.meter(registry, "cumulativeDeletesById", getCategory().toString(), scope);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 3c0c1a5..e4c0a62 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -24,7 +24,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import com.codahale.metrics.Counter;
-import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Meter;
 import com.codahale.metrics.Timer;
 import org.apache.lucene.codecs.Codec;
@@ -80,17 +79,11 @@ public class SolrIndexWriter extends IndexWriter {
   private boolean mergeTotals = false;
   private boolean mergeDetails = false;
   private final AtomicInteger runningMajorMerges = new AtomicInteger();
-  private Gauge<Integer> runningMajorMergesGauge;
   private final AtomicInteger runningMinorMerges = new AtomicInteger();
-  private Gauge<Integer> runningMinorMergesGauge;
   private final AtomicInteger runningMajorMergesSegments = new AtomicInteger();
-  private Gauge<Integer> runningMajorMergesSegmentsGauge;
   private final AtomicInteger runningMinorMergesSegments = new AtomicInteger();
-  private Gauge<Integer> runningMinorMergesSegmentsGauge;
   private final AtomicLong runningMajorMergesDocs = new AtomicLong();
-  private Gauge<Long> runningMajorMergesDocsGauge;
   private final AtomicLong runningMinorMergesDocs = new AtomicLong();
-  private Gauge<Long> runningMinorMergesDocsGauge;
 
   public static SolrIndexWriter create(SolrCore core, String name, String path, DirectoryFactory directoryFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, Codec codec) throws IOException {
 
@@ -164,18 +157,12 @@ public class SolrIndexWriter extends IndexWriter {
         minorMerge = metricManager.timer(registry, "minor", SolrInfoMBean.Category.INDEX.toString(), "merge");
         majorMerge = metricManager.timer(registry, "major", SolrInfoMBean.Category.INDEX.toString(), "merge");
         mergeErrors = metricManager.counter(registry, "errors", SolrInfoMBean.Category.INDEX.toString(), "merge");
-        runningMajorMergesGauge = () -> runningMajorMerges.get();
-        runningMinorMergesGauge = () -> runningMinorMerges.get();
-        runningMajorMergesDocsGauge = () -> runningMajorMergesDocs.get();
-        runningMinorMergesDocsGauge = () -> runningMinorMergesDocs.get();
-        runningMajorMergesSegmentsGauge = () -> runningMajorMergesSegments.get();
-        runningMinorMergesSegmentsGauge = () -> runningMinorMergesSegments.get();
-        metricManager.register(registry, runningMajorMergesGauge, true, "running", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
-        metricManager.register(registry, runningMinorMergesGauge, true, "running", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
-        metricManager.register(registry, runningMajorMergesDocsGauge, true, "running.docs", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
-        metricManager.register(registry, runningMinorMergesDocsGauge, true, "running.docs", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
-        metricManager.register(registry, runningMajorMergesSegmentsGauge, true, "running.segments", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
-        metricManager.register(registry, runningMinorMergesSegmentsGauge, true, "running.segments", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
+        metricManager.registerGauge(registry, () -> runningMajorMerges.get(), true, "running", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
+        metricManager.registerGauge(registry, () -> runningMinorMerges.get(), true, "running", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
+        metricManager.registerGauge(registry, () -> runningMajorMergesDocs.get(), true, "running.docs", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
+        metricManager.registerGauge(registry, () -> runningMinorMergesDocs.get(), true, "running.docs", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
+        metricManager.registerGauge(registry, () -> runningMajorMergesSegments.get(), true, "running.segments", SolrInfoMBean.Category.INDEX.toString(), "merge", "major");
+        metricManager.registerGauge(registry, () -> runningMinorMergesSegments.get(), true, "running.segments", SolrInfoMBean.Category.INDEX.toString(), "merge", "minor");
         flushMeter = metricManager.meter(registry, "flush", SolrInfoMBean.Category.INDEX.toString());
       }
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
index 16eff9c..610cc20 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
@@ -233,9 +233,6 @@ public static final int VERSION_IDX = 1;
 
   // metrics
   protected Gauge<Integer> bufferedOpsGauge;
-  protected Gauge<Integer> replayLogsCountGauge;
-  protected Gauge<Long> replayBytesGauge;
-  protected Gauge<Integer> stateGauge;
   protected Meter applyingBufferedOpsMeter;
   protected Meter replayOpsMeter;
 
@@ -423,16 +420,13 @@ public static final int VERSION_IDX = 1;
         return 0;
       }
     };
-    replayLogsCountGauge = () -> logs.size();
-    replayBytesGauge = () -> getTotalLogsSize();
 
-    manager.register(registry, bufferedOpsGauge, true, "ops", scope, "buffered");
-    manager.register(registry, replayLogsCountGauge, true, "logs", scope, "replay", "remaining");
-    manager.register(registry, replayBytesGauge, true, "bytes", scope, "replay", "remaining");
+    manager.registerGauge(registry, bufferedOpsGauge, true, "ops", scope, "buffered");
+    manager.registerGauge(registry, () -> logs.size(), true, "logs", scope, "replay", "remaining");
+    manager.registerGauge(registry, () -> getTotalLogsSize(), true, "bytes", scope, "replay", "remaining");
     applyingBufferedOpsMeter = manager.meter(registry, "ops", scope, "applyingBuffered");
     replayOpsMeter = manager.meter(registry, "ops", scope, "replay");
-    stateGauge = () -> state.getValue();
-    manager.register(registry, stateGauge, true, "state", scope);
+    manager.registerGauge(registry, () -> state.getValue(), true, "state", scope);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingClientConnectionManager.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingClientConnectionManager.java
index 10ca069..823df97 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingClientConnectionManager.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingClientConnectionManager.java
@@ -17,8 +17,6 @@
 
 package org.apache.solr.util.stats;
 
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.MetricRegistry;
 import org.apache.http.conn.scheme.SchemeRegistry;
 import org.apache.http.impl.conn.PoolingClientConnectionManager;
 import org.apache.solr.metrics.SolrMetricManager;
@@ -29,42 +27,17 @@ import org.apache.solr.metrics.SolrMetricProducer;
  * Inspired by dropwizard metrics-httpclient library implementation.
  */
 public class InstrumentedPoolingClientConnectionManager extends PoolingClientConnectionManager implements SolrMetricProducer {
-  protected MetricRegistry metricsRegistry;
 
   public InstrumentedPoolingClientConnectionManager(SchemeRegistry schreg) {
     super(schreg);
   }
 
-  public MetricRegistry getMetricsRegistry() {
-    return metricsRegistry;
-  }
-
-  public void setMetricsRegistry(MetricRegistry metricRegistry) {
-    this.metricsRegistry = metricRegistry;
-  }
-
   @Override
   public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
-    this.metricsRegistry = manager.registry(registry);
-    metricsRegistry.register(SolrMetricManager.mkName("availableConnections", scope),
-        (Gauge<Integer>) () -> {
-          // this acquires a lock on the connection pool; remove if contention sucks
-          return getTotalStats().getAvailable();
-        });
-    metricsRegistry.register(SolrMetricManager.mkName("leasedConnections", scope),
-        (Gauge<Integer>) () -> {
-          // this acquires a lock on the connection pool; remove if contention sucks
-          return getTotalStats().getLeased();
-        });
-    metricsRegistry.register(SolrMetricManager.mkName("maxConnections", scope),
-        (Gauge<Integer>) () -> {
-          // this acquires a lock on the connection pool; remove if contention sucks
-          return getTotalStats().getMax();
-        });
-    metricsRegistry.register(SolrMetricManager.mkName("pendingConnections", scope),
-        (Gauge<Integer>) () -> {
-          // this acquires a lock on the connection pool; remove if contention sucks
-          return getTotalStats().getPending();
-        });
+    // these acquire a lock on the connection pool; remove if contention sucks
+    manager.registerGauge(registry, () -> getTotalStats().getAvailable(), true, SolrMetricManager.mkName("availableConnections", scope));
+    manager.registerGauge(registry, () -> getTotalStats().getLeased(), true, SolrMetricManager.mkName("leasedConnections", scope));
+    manager.registerGauge(registry, () -> getTotalStats().getMax(), true, SolrMetricManager.mkName("maxConnections", scope));
+    manager.registerGauge(registry, () -> getTotalStats().getPending(), true, SolrMetricManager.mkName("pendingConnections", scope));
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/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 c12d021..a7d8e21 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
@@ -16,11 +16,13 @@
  */
 package org.apache.solr.util.stats;
 
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
 
 import com.codahale.metrics.Counter;
 import com.codahale.metrics.Gauge;
@@ -40,6 +42,29 @@ import org.apache.solr.common.util.SimpleOrderedMap;
  */
 public class MetricUtils {
 
+  public static final String VALUE = "value";
+
+  static final String MS = "_ms";
+
+  static final String MIN = "min";
+  static final String MIN_MS = MIN + MS;
+  static final String MAX = "max";
+  static final String MAX_MS = MAX + MS;
+  static final String MEAN = "mean";
+  static final String MEAN_MS = MEAN + MS;
+  static final String MEDIAN = "median";
+  static final String MEDIAN_MS = MEDIAN + MS;
+  static final String STDDEV = "stddev";
+  static final String STDDEV_MS = STDDEV + MS;
+  static final String P75 = "p75";
+  static final String P75_MS = P75 + MS;
+  static final String P95 = "p95";
+  static final String P95_MS = P95 + MS;
+  static final String P99 = "p99";
+  static final String P99_MS = P99 + MS;
+  static final String P999 = "p999";
+  static final String P999_MS = P999 + MS;
+
   /**
    * Adds metrics from a Timer to a NamedList, using well-known back-compat names.
    * @param lst The NamedList to add the metrics data to
@@ -78,41 +103,62 @@ public class MetricUtils {
    *                           included in the output
    * @param mustMatchFilter a {@link MetricFilter}.
    *                        A metric <em>must</em> match this filter to be included in the output.
+   * @param skipHistograms discard any {@link Histogram}-s and histogram parts of {@link Timer}-s.
+   * @param compact use compact representation for counters and gauges.
+   * @param metadata optional metadata. If not null and not empty then this map will be added under a
+   *                 {@code _metadata_} key.
    * @return a {@link NamedList}
    */
-  public static NamedList toNamedList(MetricRegistry registry, List<MetricFilter> shouldMatchFilters, MetricFilter mustMatchFilter) {
-    NamedList response = new SimpleOrderedMap();
+  public static NamedList toNamedList(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
+                                      MetricFilter mustMatchFilter, boolean skipHistograms,
+                                      boolean skipAggregateValues, boolean compact,
+                                      Map<String, Object> metadata) {
+    NamedList result = new SimpleOrderedMap();
+    toMaps(registry, shouldMatchFilters, mustMatchFilter, skipHistograms, skipAggregateValues, compact, (k, v) -> {
+      result.add(k, v);
+    });
+    if (metadata != null && !metadata.isEmpty()) {
+      result.add("_metadata_", metadata);
+    }
+    return result;
+  }
+
+  public static void toMaps(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
+                            MetricFilter mustMatchFilter, boolean skipHistograms, boolean skipAggregateValues,
+                            boolean compact,
+                            BiConsumer<String, Object> consumer) {
     Map<String, Metric> metrics = registry.getMetrics();
     SortedSet<String> names = registry.getNames();
     names.stream()
         .filter(s -> shouldMatchFilters.stream().anyMatch(metricFilter -> metricFilter.matches(s, metrics.get(s))))
         .filter(s -> mustMatchFilter.matches(s, metrics.get(s)))
         .forEach(n -> {
-      Metric metric = metrics.get(n);
-      if (metric instanceof Counter) {
-        Counter counter = (Counter) metric;
-        response.add(n, counterToNamedList(counter));
-      } else if (metric instanceof Gauge) {
-        Gauge gauge = (Gauge) metric;
-        response.add(n, gaugeToNamedList(gauge));
-      } else if (metric instanceof Meter) {
-        Meter meter = (Meter) metric;
-        response.add(n, meterToNamedList(meter));
-      } else if (metric instanceof Timer) {
-        Timer timer = (Timer) metric;
-        response.add(n, timerToNamedList(timer));
-      } else if (metric instanceof Histogram) {
-        Histogram histogram = (Histogram) metric;
-        response.add(n, histogramToNamedList(histogram));
-      }
-    });
-    return response;
+          Metric metric = metrics.get(n);
+          if (metric instanceof Counter) {
+            Counter counter = (Counter) metric;
+            consumer.accept(n, convertCounter(counter, compact));
+          } else if (metric instanceof Gauge) {
+            Gauge gauge = (Gauge) metric;
+            consumer.accept(n, convertGauge(gauge, compact));
+          } else if (metric instanceof Meter) {
+            Meter meter = (Meter) metric;
+            consumer.accept(n, convertMeter(meter));
+          } else if (metric instanceof Timer) {
+            Timer timer = (Timer) metric;
+            consumer.accept(n, convertTimer(timer, skipHistograms));
+          } else if (metric instanceof Histogram) {
+            if (!skipHistograms) {
+              Histogram histogram = (Histogram) metric;
+              consumer.accept(n, convertHistogram(histogram));
+            }
+          }
+        });
   }
 
-  static NamedList histogramToNamedList(Histogram histogram) {
-    NamedList response = new SimpleOrderedMap();
+  static Map<String, Object> convertHistogram(Histogram histogram) {
+    Map<String, Object> response = new LinkedHashMap<>();
     Snapshot snapshot = histogram.getSnapshot();
-    response.add("count", histogram.getCount());
+    response.put("count", histogram.getCount());
     // non-time based values
     addSnapshot(response, snapshot, false);
     return response;
@@ -127,72 +173,61 @@ public class MetricUtils {
     }
   }
 
-  static final String MS = "_ms";
-
-  static final String MIN = "min";
-  static final String MIN_MS = MIN + MS;
-  static final String MAX = "max";
-  static final String MAX_MS = MAX + MS;
-  static final String MEAN = "mean";
-  static final String MEAN_MS = MEAN + MS;
-  static final String MEDIAN = "median";
-  static final String MEDIAN_MS = MEDIAN + MS;
-  static final String STDDEV = "stddev";
-  static final String STDDEV_MS = STDDEV + MS;
-  static final String P75 = "p75";
-  static final String P75_MS = P75 + MS;
-  static final String P95 = "p95";
-  static final String P95_MS = P95 + MS;
-  static final String P99 = "p99";
-  static final String P99_MS = P99 + MS;
-  static final String P999 = "p999";
-  static final String P999_MS = P999 + MS;
-
   // some snapshots represent time in ns, other snapshots represent raw values (eg. chunk size)
-  static void addSnapshot(NamedList response, Snapshot snapshot, boolean ms) {
-    response.add((ms ? MIN_MS: MIN), nsToMs(ms, snapshot.getMin()));
-    response.add((ms ? MAX_MS: MAX), nsToMs(ms, snapshot.getMax()));
-    response.add((ms ? MEAN_MS : MEAN), nsToMs(ms, snapshot.getMean()));
-    response.add((ms ? MEDIAN_MS: MEDIAN), nsToMs(ms, snapshot.getMedian()));
-    response.add((ms ? STDDEV_MS: STDDEV), nsToMs(ms, snapshot.getStdDev()));
-    response.add((ms ? P75_MS: P75), nsToMs(ms, snapshot.get75thPercentile()));
-    response.add((ms ? P95_MS: P95), nsToMs(ms, snapshot.get95thPercentile()));
-    response.add((ms ? P99_MS: P99), nsToMs(ms, snapshot.get99thPercentile()));
-    response.add((ms ? P999_MS: P999), nsToMs(ms, snapshot.get999thPercentile()));
+  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()));
+    response.put((ms ? MEDIAN_MS: MEDIAN), nsToMs(ms, snapshot.getMedian()));
+    response.put((ms ? STDDEV_MS: STDDEV), nsToMs(ms, snapshot.getStdDev()));
+    response.put((ms ? P75_MS: P75), nsToMs(ms, snapshot.get75thPercentile()));
+    response.put((ms ? P95_MS: P95), nsToMs(ms, snapshot.get95thPercentile()));
+    response.put((ms ? P99_MS: P99), nsToMs(ms, snapshot.get99thPercentile()));
+    response.put((ms ? P999_MS: P999), nsToMs(ms, snapshot.get999thPercentile()));
   }
 
-  static NamedList timerToNamedList(Timer timer) {
-    NamedList response = new SimpleOrderedMap();
-    response.add("count", timer.getCount());
-    response.add("meanRate", timer.getMeanRate());
-    response.add("1minRate", timer.getOneMinuteRate());
-    response.add("5minRate", timer.getFiveMinuteRate());
-    response.add("15minRate", timer.getFifteenMinuteRate());
-    // time-based values in nanoseconds
-    addSnapshot(response, timer.getSnapshot(), true);
+  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());
+    response.put("1minRate", timer.getOneMinuteRate());
+    response.put("5minRate", timer.getFiveMinuteRate());
+    response.put("15minRate", timer.getFifteenMinuteRate());
+    if (!skipHistograms) {
+      // time-based values in nanoseconds
+      addSnapshot(response, timer.getSnapshot(), true);
+    }
     return response;
   }
 
-  static NamedList meterToNamedList(Meter meter) {
-    NamedList response = new SimpleOrderedMap();
-    response.add("count", meter.getCount());
-    response.add("meanRate", meter.getMeanRate());
-    response.add("1minRate", meter.getOneMinuteRate());
-    response.add("5minRate", meter.getFiveMinuteRate());
-    response.add("15minRate", meter.getFifteenMinuteRate());
+  static Map<String, Object> convertMeter(Meter meter) {
+    Map<String, Object> response = new LinkedHashMap<>();
+    response.put("count", meter.getCount());
+    response.put("meanRate", meter.getMeanRate());
+    response.put("1minRate", meter.getOneMinuteRate());
+    response.put("5minRate", meter.getFiveMinuteRate());
+    response.put("15minRate", meter.getFifteenMinuteRate());
     return response;
   }
 
-  static NamedList gaugeToNamedList(Gauge gauge) {
-    NamedList response = new SimpleOrderedMap();
-    response.add("value", gauge.getValue());
-    return response;
+  static Object convertGauge(Gauge gauge, boolean compact) {
+    if (compact) {
+      return gauge.getValue();
+    } else {
+      Map<String, Object> response = new LinkedHashMap<>();
+      response.put("value", gauge.getValue());
+      return response;
+    }
   }
 
-  static NamedList counterToNamedList(Counter counter) {
-    NamedList response = new SimpleOrderedMap();
-    response.add("count", counter.getCount());
-    return response;
+  static Object convertCounter(Counter counter, boolean compact) {
+    if (compact) {
+      return counter.getCount();
+    } else {
+      Map<String, Object> response = new LinkedHashMap<>();
+      response.put("count", counter.getCount());
+      return response;
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
index a1b29db..e2f4132 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.handler.admin;
 
+import java.util.Map;
+
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.util.NamedList;
@@ -47,9 +49,12 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
     assertNotNull(values.get("solr.node"));
     NamedList nl = (NamedList) values.get("solr.core.collection1");
     assertNotNull(nl);
-    assertNotNull(nl.get("SEARCHER.new.errors")); // counter type
-    assertNotNull(((NamedList) nl.get("SEARCHER.new.errors")).get("count"));
-    assertEquals(0L, ((NamedList) nl.get("SEARCHER.new.errors")).get("count"));
+    Object o = nl.get("SEARCHER.new.errors");
+    assertNotNull(o); // counter type
+    assertTrue(o instanceof Map);
+    // response wasn't serialized so we get here whatever MetricUtils produced instead of NamedList
+    assertNotNull(((Map) o).get("count"));
+    assertEquals(0L, ((Map) nl.get("SEARCHER.new.errors")).get("count"));
     nl = (NamedList) values.get("solr.node");
     assertNotNull(nl.get("CONTAINER.cores.loaded")); // int gauge
     assertEquals(1, ((NamedList) nl.get("CONTAINER.cores.loaded")).get("value"));
@@ -146,4 +151,20 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
     assertEquals(1, values.size());
     assertEquals(0, ((NamedList)values.get("solr.node")).size());
   }
+
+  @Test
+  public void testCompact() throws Exception {
+    MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
+
+    SolrQueryResponse resp = new SolrQueryResponse();
+    handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", MetricsHandler.COMPACT_PARAM, "true"), resp);
+    NamedList values = resp.getValues();
+    assertNotNull(values.get("metrics"));
+    values = (NamedList) values.get("metrics");
+    NamedList nl = (NamedList) values.get("solr.core.collection1");
+    assertNotNull(nl);
+    Object o = nl.get("SEARCHER.new.errors");
+    assertNotNull(o); // counter type
+    assertTrue(o instanceof Number);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
index 2816354..462241a 100644
--- a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
@@ -119,7 +119,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     String delsQName = PREFIX + "deletesByQuery";
     String cumulativeDelsQName = PREFIX + "cumulativeDeletesByQuery";
     long commits = ((Meter) metrics.get(commitsName)).getCount();
-    long adds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+    long adds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
     long cumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
     long cumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
     long cumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
@@ -137,7 +137,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     assertQ(req("q","id:5"), "//*[@numFound='0']");
     assertQ(req("q","id:6"), "//*[@numFound='0']");
 
-    long newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+    long newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
     long newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
     assertEquals("new adds", 2, newAdds - adds);
     assertEquals("new cumulative adds", 2, newCumulativeAdds - cumulativeAdds);
@@ -147,7 +147,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     long newCommits = ((Meter) metrics.get(commitsName)).getCount();
     assertEquals("new commits", 1, newCommits - commits);
 
-    newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+    newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
     newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
     // adds should be reset to 0 after commit
     assertEquals("new adds after commit", 0, newAdds);
@@ -161,7 +161,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     // now delete one
     assertU(delI("5"));
 
-    long newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+    long newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
     long newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
     assertEquals("new delsI", 1, newDelsI);
     assertEquals("new cumulative delsI", 1, newCumulativeDelsI - cumulativeDelsI);
@@ -171,7 +171,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
 
     assertU(commit());
     // delsI should be reset to 0 after commit
-    newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+    newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
     newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
     assertEquals("new delsI after commit", 0, newDelsI);
     assertEquals("new cumulative delsI after commit", 1, newCumulativeDelsI - cumulativeDelsI);
@@ -183,7 +183,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     // now delete all
     assertU(delQ("*:*"));
 
-    long newDelsQ = ((Gauge<Long>) metrics.get(delsQName)).getValue();
+    long newDelsQ = ((Gauge<Number>) metrics.get(delsQName)).getValue().longValue();
     long newCumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
     assertEquals("new delsQ", 1, newDelsQ);
     assertEquals("new cumulative delsQ", 1, newCumulativeDelsQ - cumulativeDelsQ);
@@ -193,7 +193,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
 
     assertU(commit());
 
-    newDelsQ = ((Gauge<Long>) metrics.get(delsQName)).getValue();
+    newDelsQ = ((Gauge<Number>) metrics.get(delsQName)).getValue().longValue();
     newCumulativeDelsQ = ((Meter) metrics.get(cumulativeDelsQName)).getCount();
     assertEquals("new delsQ after commit", 0, newDelsQ);
     assertEquals("new cumulative delsQ after commit", 1, newCumulativeDelsQ - cumulativeDelsQ);
@@ -204,11 +204,11 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
     // verify final metrics
     newCommits = ((Meter) metrics.get(commitsName)).getCount();
     assertEquals("new commits", 3, newCommits - commits);
-    newAdds = ((Gauge<Long>) metrics.get(addsName)).getValue();
+    newAdds = ((Gauge<Number>) metrics.get(addsName)).getValue().longValue();
     assertEquals("new adds", 0, newAdds);
     newCumulativeAdds = ((Meter) metrics.get(cumulativeAddsName)).getCount();
     assertEquals("new cumulative adds", 2, newCumulativeAdds - cumulativeAdds);
-    newDelsI = ((Gauge<Long>) metrics.get(delsIName)).getValue();
+    newDelsI = ((Gauge<Number>) metrics.get(delsIName)).getValue().longValue();
     assertEquals("new delsI", 0, newDelsI);
     newCumulativeDelsI = ((Meter) metrics.get(cumulativeDelsIName)).getCount();
     assertEquals("new cumulative delsI", 1, newCumulativeDelsI - cumulativeDelsI);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java b/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
index c9935bb..9985937 100644
--- a/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
+++ b/solr/core/src/test/org/apache/solr/update/SolrIndexMetricsTest.java
@@ -67,7 +67,7 @@ public class SolrIndexMetricsTest extends SolrTestCaseJ4 {
 
     Map<String, Metric> metrics = registry.getMetrics();
 
-    assertEquals(10, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
+    assertEquals(12, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
 
     // check basic index meters
     Timer timer = (Timer)metrics.get("INDEX.merge.minor");
@@ -92,7 +92,8 @@ public class SolrIndexMetricsTest extends SolrTestCaseJ4 {
     assertNotNull(registry);
 
     Map<String, Metric> metrics = registry.getMetrics();
-    assertEquals(0, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
+    // INDEX.size, INDEX.sizeInBytes
+    assertEquals(2, metrics.entrySet().stream().filter(e -> e.getKey().startsWith("INDEX")).count());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd4cc72b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
index e39ad6e..3117121 100644
--- a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
+++ b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
@@ -17,8 +17,16 @@
 
 package org.apache.solr.util.stats;
 
+import java.util.Collections;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricFilter;
+import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.Snapshot;
 import com.codahale.metrics.Timer;
 import org.apache.solr.SolrTestCaseJ4;
@@ -36,7 +44,7 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
       timer.update(Math.abs(random().nextInt()) + 1, TimeUnit.NANOSECONDS);
     }
     // obtain timer metrics
-    NamedList lst = MetricUtils.timerToNamedList(timer);
+    NamedList lst = new NamedList(MetricUtils.convertTimer(timer, false));
     // check that expected metrics were obtained
     assertEquals(14, lst.size());
     final Snapshot snapshot = timer.getSnapshot();
@@ -52,5 +60,65 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
     assertEquals(MetricUtils.nsToMs(snapshot.get999thPercentile()), lst.get("p999_ms"));
   }
 
+  @Test
+  public void testMetrics() throws Exception {
+    MetricRegistry registry = new MetricRegistry();
+    Counter counter = registry.counter("counter");
+    counter.inc();
+    Timer timer = registry.timer("timer");
+    Timer.Context ctx = timer.time();
+    Thread.sleep(150);
+    ctx.stop();
+    Meter meter = registry.meter("meter");
+    meter.mark();
+    Histogram histogram = registry.histogram("histogram");
+    histogram.update(10);
+    Gauge<String> gauge = () -> "foobar";
+    registry.register("gauge", gauge);
+    MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
+        false, false, false, (k, o) -> {
+      Map v = (Map)o;
+      if (k.startsWith("counter")) {
+        assertEquals(1L, v.get("count"));
+      } else if (k.startsWith("gauge")) {
+        assertEquals("foobar", v.get("value"));
+      } else if (k.startsWith("timer")) {
+        assertEquals(1L, v.get("count"));
+        assertTrue(((Number)v.get("min_ms")).intValue() > 100);
+      } else if (k.startsWith("meter")) {
+        assertEquals(1L, v.get("count"));
+      } else if (k.startsWith("histogram")) {
+        assertEquals(1L, v.get("count"));
+      }
+    });
+    // test compact format
+    MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
+        false, false, true, (k, o) -> {
+          if (k.startsWith("counter")) {
+            assertTrue(o instanceof Long);
+            assertEquals(1L, o);
+          } else if (k.startsWith("gauge")) {
+            assertTrue(o instanceof String);
+            assertEquals("foobar", o);
+          } else if (k.startsWith("timer")) {
+            assertTrue(o instanceof Map);
+            Map v = (Map)o;
+            assertEquals(1L, v.get("count"));
+            assertTrue(((Number)v.get("min_ms")).intValue() > 100);
+          } else if (k.startsWith("meter")) {
+            assertTrue(o instanceof Map);
+            Map v = (Map)o;
+            assertEquals(1L, v.get("count"));
+          } else if (k.startsWith("histogram")) {
+            assertTrue(o instanceof Map);
+            Map v = (Map)o;
+            assertEquals(1L, v.get("count"));
+          } else {
+            Map v = (Map)o;
+            assertEquals(1L, v.get("count"));
+          }
+        });
+
+  }
 }