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/01/23 14:40:38 UTC

[1/2] lucene-solr:jira/solr-9857: SOLR-9857 Improve metric names from PeerSync. Add tracking of update count to AggregateMetric. Fix the test.

Repository: lucene-solr
Updated Branches:
  refs/heads/jira/solr-9857 aef1f73a3 -> 3219de0e1


SOLR-9857 Improve metric names from PeerSync. Add tracking of update count to
AggregateMetric. Fix the test.


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

Branch: refs/heads/jira/solr-9857
Commit: fcd18f6c7ea614a6273bd3d90fe6446c51bd367f
Parents: aef1f73
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Mon Jan 23 13:36:17 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Mon Jan 23 13:36:17 2017 +0100

----------------------------------------------------------------------
 .../handler/admin/MetricsCollectorHandler.java  | 39 ++++++-----
 .../apache/solr/metrics/AggregateMetric.java    | 66 ++++++++++++++----
 .../apache/solr/metrics/SolrMetricManager.java  |  3 +-
 .../reporters/solr/SolrReplicaReporter.java     | 36 +++++++---
 .../metrics/reporters/solr/SolrReporter.java    |  1 +
 .../java/org/apache/solr/update/PeerSync.java   |  8 ++-
 .../reporters/solr/SolrReplicaReporterTest.java | 73 +++++++++++++++++++-
 7 files changed, 182 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
index c504273..494eab0 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
@@ -22,13 +22,11 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.codahale.metrics.MetricRegistry;
-import org.apache.solr.client.solrj.io.stream.metrics.Metric;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ContentStream;
-import org.apache.solr.common.util.JavaBinCodec;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.handler.loader.ContentStreamLoader;
@@ -90,7 +88,7 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
 
   @Override
   public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
-    log.info("#### " + req.toString());
+    //log.info("#### " + req.toString());
     for (ContentStream cs : req.getContentStreams()) {
       if (cs.getContentType() == null) {
         log.warn("Missing content type - ignoring");
@@ -100,14 +98,14 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
       if (loader == null) {
         throw new SolrException(SolrException.ErrorCode.UNSUPPORTED_MEDIA_TYPE, "Unsupported content type for stream: " + cs.getSourceInfo() + ", contentType=" + cs.getContentType());
       }
-      String id = req.getParams().get(SolrReporter.REPORTER_ID);
+      String reporterId = req.getParams().get(SolrReporter.REPORTER_ID);
       String group = req.getParams().get(SolrReporter.GROUP_ID);
-      if (id == null || group == null) {
+      if (reporterId == null || group == null) {
         throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing " + SolrReporter.REPORTER_ID +
             " or " + SolrReporter.GROUP_ID + " in request params: " + req.getParamString());
       }
       MetricRegistry registry = metricManager.registry(group);
-      loader.load(req, rsp, cs, new MetricUpdateProcessor(registry, id, group));
+      loader.load(req, rsp, cs, new MetricUpdateProcessor(registry, reporterId, group));
     }
   }
 
@@ -118,13 +116,13 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
 
   private static class MetricUpdateProcessor extends UpdateRequestProcessor {
     private final MetricRegistry registry;
-    private final String id;
+    private final String reporterId;
     private final String group;
 
-    public MetricUpdateProcessor(MetricRegistry registry, String id, String group) {
+    public MetricUpdateProcessor(MetricRegistry registry, String reporterId, String group) {
       super(null);
       this.registry = registry;
-      this.id = id;
+      this.reporterId = reporterId;
       this.group = group;
     }
 
@@ -134,7 +132,7 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
       if (doc == null) {
         return;
       }
-      String metricName = (String)doc.getFieldValue("name");
+      String metricName = (String)doc.getFieldValue(MetricUtils.NAME);
       if (metricName == null) {
         log.warn("Missing metric 'name' field in document, skipping: " + doc);
         return;
@@ -145,13 +143,22 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
       doc.remove(SolrReporter.GROUP_ID);
       // remaining fields should only contain numeric values
       doc.forEach(f -> {
-        String key = MetricRegistry.name(metricName, f.getName());
-        AggregateMetric metric = (AggregateMetric)registry.getMetrics().get(key);
-        if (metric == null) {
-          metric = new AggregateMetric();
-          registry.register(key, metric);
+        if (f.getFirstValue() instanceof Number) {
+          String key = MetricRegistry.name(metricName, f.getName());
+          AggregateMetric metric = (AggregateMetric)registry.getMetrics().get(key);
+          if (metric == null) {
+            metric = new AggregateMetric();
+            registry.register(key, metric);
+          }
+          Object o = f.getFirstValue();
+          if (o != null && (o instanceof Number)) {
+            metric.set(reporterId, ((Number)o).doubleValue());
+          } else {
+            // silently discard
+          }
+        } else {
+          // silently discard
         }
-        metric.set(id, ((Number)f.getFirstValue()).doubleValue());
       });
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java b/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
index 09ed42e..f4c8c6a 100644
--- a/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
+++ b/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
@@ -3,6 +3,7 @@ package org.apache.solr.metrics;
 import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import com.codahale.metrics.Metric;
 
@@ -10,10 +11,45 @@ import com.codahale.metrics.Metric;
  * This class is used for keeping several partial named values and providing useful statistics over them.
  */
 public class AggregateMetric implements Metric {
-  private final Map<String, Double> values = new ConcurrentHashMap<>();
+
+  /**
+   * Simple class to represent current value and how many times it was set.
+   */
+  public static class Update {
+    public Number value;
+    public final AtomicInteger updateCount = new AtomicInteger();
+
+    public Update(Number value) {
+      update(value);
+    }
+
+    public void update(Number value) {
+      this.value = value;
+      updateCount.incrementAndGet();
+    }
+
+    @Override
+    public String toString() {
+      return "Update{" +
+          "value=" + value +
+          ", updateCount=" + updateCount +
+          '}';
+    }
+  }
+
+  private final Map<String, Update> values = new ConcurrentHashMap<>();
 
   public void set(String name, double value) {
-    values.put(name, value);
+    final Update existing = values.get(name);
+    if (existing == null) {
+      final Update created = new Update(value);
+      final Update raced = values.putIfAbsent(name, created);
+      if (raced != null) {
+        raced.update(value);
+      }
+    } else {
+      existing.update(value);
+    }
   }
 
   public void clear(String name) {
@@ -32,7 +68,7 @@ public class AggregateMetric implements Metric {
     return values.isEmpty();
   }
 
-  public Map<String, Double> getValues() {
+  public Map<String, Update> getValues() {
     return Collections.unmodifiableMap(values);
   }
 
@@ -42,13 +78,13 @@ public class AggregateMetric implements Metric {
       return 0;
     }
     Double res = null;
-    for (Double d : values.values()) {
+    for (Update u : values.values()) {
       if (res == null) {
-        res = d;
+        res = u.value.doubleValue();
         continue;
       }
-      if (d > res) {
-        res = d;
+      if (u.value.doubleValue() > res) {
+        res = u.value.doubleValue();
       }
     }
     return res;
@@ -59,13 +95,13 @@ public class AggregateMetric implements Metric {
       return 0;
     }
     Double res = null;
-    for (Double d : values.values()) {
+    for (Update u : values.values()) {
       if (res == null) {
-        res = d;
+        res = u.value.doubleValue();
         continue;
       }
-      if (d < res) {
-        res = d;
+      if (u.value.doubleValue() < res) {
+        res = u.value.doubleValue();
       }
     }
     return res;
@@ -76,8 +112,8 @@ public class AggregateMetric implements Metric {
       return 0;
     }
     double total = 0;
-    for (Double d : values.values()) {
-      total += d;
+    for (Update u : values.values()) {
+      total += u.value.doubleValue();
     }
     return total / values.size();
   }
@@ -89,8 +125,8 @@ public class AggregateMetric implements Metric {
     }
     final double mean = getMean();
     double sum = 0;
-    for (Double d : values.values()) {
-      final double diff = d - mean;
+    for (Update u : values.values()) {
+      final double diff = u.value.doubleValue() - mean;
       sum += diff * diff;
     }
     final double variance = sum / (size - 1);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/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 f97645c..dc08103 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -45,6 +45,7 @@ import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoMBean;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.metrics.reporters.solr.SolrReplicaReporter;
+import org.apache.solr.metrics.reporters.solr.SolrReporter;
 import org.apache.solr.util.plugin.SolrCoreAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -693,7 +694,7 @@ public class SolrMetricManager {
     attrs.put("name", "replica");
     attrs.put("class", SolrReplicaReporter.class.getName());
     NamedList initArgs = new NamedList();
-    initArgs.add(SolrReplicaReporter.LEADER_REGISTRY, leaderRegistryName);
+    initArgs.add(SolrReporter.GROUP_ID, leaderRegistryName);
     initArgs.add("period", 5);
     PluginInfo pluginInfo = new PluginInfo("reporter", attrs, initArgs, null);
     try {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReplicaReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReplicaReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReplicaReporter.java
index bddb1f0..afb4da2 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReplicaReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReplicaReporter.java
@@ -17,6 +17,7 @@
 package org.apache.solr.metrics.reporters.solr;
 
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
 
@@ -26,22 +27,26 @@ import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.handler.admin.MetricsCollectorHandler;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricReporter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * This class reports selected metrics from replicas to a shard leader.
  */
 public class SolrReplicaReporter extends SolrMetricReporter {
-  public static final String LEADER_REGISTRY = "leaderRegistry";
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  public static final String[] METRICS = {
+  public static final String[] DEFAULT_METRICS = {
     "TLOG", "REPLICATION", "INDEX"
   };
 
-  private String leaderRegistry;
-  private String handler;
+  private String solrGroupId;
+  private String handler = MetricsCollectorHandler.HANDLER_PATH;
   private int period = 60;
+  private String[] metrics = DEFAULT_METRICS;
 
   private SolrReporter reporter;
 
@@ -56,8 +61,8 @@ public class SolrReplicaReporter extends SolrMetricReporter {
     super(metricManager, registryName);
   }
 
-  public void setLeaderRegistry(String leaderRegistry) {
-    this.leaderRegistry = leaderRegistry;
+  public void setSolrGroupId(String solrGroupId) {
+    this.solrGroupId = solrGroupId;
   }
 
   public void setHandler(String handler) {
@@ -68,6 +73,16 @@ public class SolrReplicaReporter extends SolrMetricReporter {
     this.period = period;
   }
 
+  public void setMetrics(String prefixList) {
+    if (prefixList == null || prefixList.isEmpty()) {
+      return;
+    }
+    String[] newMetrics = prefixList.split("[\\s,]+");
+    if (newMetrics.length > 0) {
+      metrics = newMetrics;
+    }
+  }
+
   @Override
   protected void validate() throws IllegalStateException {
     if (period < 1) {
@@ -87,9 +102,14 @@ public class SolrReplicaReporter extends SolrMetricReporter {
     if (reporter != null) {
       reporter.close();
     }
+    if (core.getCoreDescriptor().getCloudDescriptor() == null) {
+      // not a cloud core
+      log.warn("Not initializing replica reporter for non-cloud core " + core.getName());
+      return;
+    }
     // our id is nodeName
     String id = core.getCoreDescriptor().getCloudDescriptor().getCoreNodeName();
-    MetricFilter filter = new SolrMetricManager.PrefixFilter(METRICS);
+    MetricFilter filter = new SolrMetricManager.PrefixFilter(metrics);
     reporter = SolrReporter.Builder.forRegistry(metricManager.registry(registryName))
         .convertRatesTo(TimeUnit.SECONDS)
         .convertDurationsTo(TimeUnit.MILLISECONDS)
@@ -97,7 +117,7 @@ public class SolrReplicaReporter extends SolrMetricReporter {
         .filter(filter)
         .withId(id)
         .cloudClient(false) // we want to send reports specifically to a selected leader instance
-        .withGroup(leaderRegistry)
+        .withGroup(solrGroupId)
         .build(core.getCoreDescriptor().getCoreContainer().getUpdateShardHandler().getHttpClient(), new LeaderUrlSupplier(core));
 
     reporter.start(period, TimeUnit.SECONDS);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
index ddbc2c2..36a9f5a 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java
@@ -262,6 +262,7 @@ public class SolrReporter extends ScheduledReporter {
         skipHistograms, metadata, doc -> req.add(doc));
 
     try {
+      //log.info("%%% sending to " + url + ": " + req.getParams());
       solr.request(req);
     } catch (SolrServerException sse) {
       log.warn("Error sending metric report", sse);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/java/org/apache/solr/update/PeerSync.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java
index 861cbf7..cb448eb 100644
--- a/solr/core/src/java/org/apache/solr/update/PeerSync.java
+++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java
@@ -160,11 +160,13 @@ public class PeerSync implements SolrMetricProducer {
     core.getCoreMetricManager().registerMetricProducer(SolrInfoMBean.Category.REPLICATION.toString(), this);
   }
 
+  public static final String METRIC_SCOPE = "peerSync";
+
   @Override
   public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
-    syncTime = manager.timer(registry, "time", scope);
-    syncErrors = manager.counter(registry, "errors", scope);
-    syncSkipped = manager.counter(registry, "skipped", scope);
+    syncTime = manager.timer(registry, "time", scope, METRIC_SCOPE);
+    syncErrors = manager.counter(registry, "errors", scope, METRIC_SCOPE);
+    syncSkipped = manager.counter(registry, "skipped", scope, METRIC_SCOPE);
   }
 
   /** optional list of updates we had before possibly receiving new updates */

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/fcd18f6c/solr/core/src/test/org/apache/solr/metrics/reporters/solr/SolrReplicaReporterTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/metrics/reporters/solr/SolrReplicaReporterTest.java b/solr/core/src/test/org/apache/solr/metrics/reporters/solr/SolrReplicaReporterTest.java
index 55a59ba..70a785e 100644
--- a/solr/core/src/test/org/apache/solr/metrics/reporters/solr/SolrReplicaReporterTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/reporters/solr/SolrReplicaReporterTest.java
@@ -1,19 +1,90 @@
 package org.apache.solr.metrics.reporters.solr;
 
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+
+import com.codahale.metrics.Metric;
+import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
+import org.apache.solr.cloud.CloudDescriptor;
+import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.CoreDescriptor;
+import org.apache.solr.metrics.AggregateMetric;
+import org.apache.solr.metrics.SolrCoreMetricManager;
+import org.apache.solr.metrics.SolrMetricManager;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class SolrReplicaReporterTest extends AbstractFullDistribZkTestBase {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   public SolrReplicaReporterTest() {
     schemaString = "schema15.xml";      // we need a string id
   }
 
   @Test
   public void test() throws Exception {
+    waitForRecoveriesToFinish("control_collection",
+        jettys.get(0).getCoreContainer().getZkController().getZkStateReader(), false);
+    waitForRecoveriesToFinish("collection1",
+        jettys.get(0).getCoreContainer().getZkController().getZkStateReader(), false);
     printLayout();
-    Thread.sleep(10000000);
+    // wait for at least two reports
+    Thread.sleep(10000);
+    ClusterState state = jettys.get(0).getCoreContainer().getZkController().getClusterState();
+    for (JettySolrRunner jetty : jettys) {
+      CoreContainer cc = jetty.getCoreContainer();
+      SolrMetricManager metricManager = cc.getMetricManager();
+      for (final String coreName : cc.getCoreNames()) {
+        CoreDescriptor cd = cc.getCoreDescriptor(coreName);
+        if (cd.getCloudDescriptor() == null) { // not a cloud collection
+          continue;
+        }
+        CloudDescriptor cloudDesc = cd.getCloudDescriptor();
+        DocCollection docCollection = state.getCollection(cloudDesc.getCollectionName());
+        String registryName = SolrCoreMetricManager.createRegistryName(true,
+            cloudDesc.getCollectionName(), cloudDesc.getShardId(), cloudDesc.getCoreNodeName(), null);
+        String leaderRegistryName = SolrCoreMetricManager.createLeaderRegistryName(true,
+            cloudDesc.getCollectionName(), cloudDesc.getShardId());
+        boolean leader = cloudDesc.isLeader();
+        Slice slice = docCollection.getSlice(cloudDesc.getShardId());
+        int numReplicas = slice.getReplicas().size();
+        if (leader) {
+          assertTrue(metricManager.registryNames() + " doesn't contain " + leaderRegistryName,
+              metricManager.registryNames().contains(leaderRegistryName));
+          Map<String, Metric> metrics = metricManager.registry(leaderRegistryName).getMetrics();
+          metrics.forEach((k, v) -> {
+            assertTrue("Unexpected type of " + k + ": " + v.getClass().getName() + ", " + v,
+                v instanceof AggregateMetric);
+            AggregateMetric am = (AggregateMetric)v;
+            if (!k.startsWith("REPLICATION.peerSync")) {
+              assertEquals(coreName + "::" + registryName + "::" + k + ": " + am.toString(), numReplicas, am.size());
+            }
+          });
+        } else {
+          assertFalse(metricManager.registryNames() + " contains " + leaderRegistryName +
+              " but it's not a leader!",
+              metricManager.registryNames().contains(leaderRegistryName));
+          Map<String, Metric> metrics = metricManager.registry(leaderRegistryName).getMetrics();
+          metrics.forEach((k, v) -> {
+            assertTrue("Unexpected type of " + k + ": " + v.getClass().getName() + ", " + v,
+                v instanceof AggregateMetric);
+            AggregateMetric am = (AggregateMetric)v;
+            if (!k.startsWith("REPLICATION.peerSync")) {
+              assertEquals(coreName + "::" + registryName + "::" + k + ": " + am.toString(), 1, am.size());
+            }
+          });
+        }
+        assertTrue(metricManager.registryNames() + " doesn't contain " + registryName,
+            metricManager.registryNames().contains(registryName));
+      }
+    }
   }
 }


[2/2] lucene-solr:jira/solr-9857: SOLR-9857 Improve AggregateMetric + test.

Posted by ab...@apache.org.
SOLR-9857 Improve AggregateMetric + test.


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

Branch: refs/heads/jira/solr-9857
Commit: 3219de0e19f209c9c2bb5712ab8887426858ea37
Parents: fcd18f6
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Mon Jan 23 15:40:12 2017 +0100
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Mon Jan 23 15:40:12 2017 +0100

----------------------------------------------------------------------
 .../apache/solr/metrics/AggregateMetric.java    |  2 +-
 .../org/apache/solr/util/stats/MetricUtils.java |  7 ++-
 .../apache/solr/util/stats/MetricUtilsTest.java | 52 ++++++++++++++++++++
 3 files changed, 59 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3219de0e/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java b/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
index f4c8c6a..2123bfc 100644
--- a/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
+++ b/solr/core/src/java/org/apache/solr/metrics/AggregateMetric.java
@@ -39,7 +39,7 @@ public class AggregateMetric implements Metric {
 
   private final Map<String, Update> values = new ConcurrentHashMap<>();
 
-  public void set(String name, double value) {
+  public void set(String name, Number value) {
     final Update existing = values.get(name);
     if (existing == null) {
       final Update created = new Update(value);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3219de0e/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 6c54822..13add27 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
@@ -221,7 +221,12 @@ public class MetricUtils {
     if (!metric.isEmpty()) {
       Map<String, Object> values = new LinkedHashMap<>();
       response.put(VALUES, values);
-      metric.getValues().forEach((k, v) -> values.put(k, v));
+      metric.getValues().forEach((k, v) -> {
+        Map<String, Object> map = new LinkedHashMap<>();
+        map.put("value", v.value);
+        map.put("updateCount", v.updateCount.get());
+        values.put(k, map);
+      });
     }
     return response;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3219de0e/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 0954569..8dcf063 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,12 +17,20 @@
 
 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.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;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.metrics.AggregateMetric;
 import org.junit.Test;
 
 public class MetricUtilsTest extends SolrTestCaseJ4 {
@@ -52,5 +60,49 @@ 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(100);
+    ctx.stop();
+    Meter meter = registry.meter("meter");
+    meter.mark();
+    Histogram histogram = registry.histogram("histogram");
+    histogram.update(10);
+    AggregateMetric am = new AggregateMetric();
+    registry.register("aggregate", am);
+    am.set("foo", 10);
+    am.set("bar", 1);
+    am.set("bar", 2);
+    MetricUtils.toNamedMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
+        false, (k, v) -> {
+      if (k.startsWith("counter")) {
+        assertEquals(1L, v.get("count"));
+      } 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"));
+      } else if (k.startsWith("aggregate")) {
+        assertEquals(2, v.get("count"));
+        Map<String, Object> values = (Map<String, Object>)v.get("values");
+        assertNotNull(values);
+        assertEquals(2, values.size());
+        Map<String, Object> update = (Map<String, Object>)values.get("foo");
+        assertEquals(10, update.get("value"));
+        assertEquals(1, update.get("updateCount"));
+        update = (Map<String, Object>)values.get("bar");
+        assertEquals(2, update.get("value"));
+        assertEquals(2, update.get("updateCount"));
+      }
+    });
+  }
+
 }