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"));
+ }
+ });
+ }
+
}