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/04/10 17:18:07 UTC
lucene-solr:jira/solr-9959: SOLR-9959 Several improvements and fixes:
* Add support for multiple "prefix" filters to most reporters. * Add support
for "enabled" flag to all reporters. * Refactor JMX reporter to reuse created
MBean servers for a specific
Repository: lucene-solr
Updated Branches:
refs/heads/jira/solr-9959 75dcf4f4e -> 4c774f1dc
SOLR-9959 Several improvements and fixes:
* Add support for multiple "prefix" filters to most reporters.
* Add support for "enabled" flag to all reporters.
* Refactor JMX reporter to reuse created MBean servers for a specific serviceUrl. Use
the same pattern for Graphite and Ganglia.
* Don't use reporter name in JMX object names.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/4c774f1d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/4c774f1d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/4c774f1d
Branch: refs/heads/jira/solr-9959
Commit: 4c774f1dc4b7added526a656a4ae2f42b744b014
Parents: 75dcf4f
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Mon Apr 10 19:15:06 2017 +0200
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Mon Apr 10 19:15:06 2017 +0200
----------------------------------------------------------------------
.../src/java/org/apache/solr/core/SolrCore.java | 2 +-
.../org/apache/solr/core/SolrXmlConfig.java | 4 +-
.../solr/metrics/SolrCoreMetricManager.java | 3 +
.../apache/solr/metrics/SolrMetricManager.java | 30 ++++++
.../apache/solr/metrics/SolrMetricReporter.java | 12 +++
.../metrics/reporters/JmxObjectNameFactory.java | 11 +-
.../reporters/MetricServiceRegistry.java | 23 ++++
.../metrics/reporters/SolrGangliaReporter.java | 55 ++++++++--
.../metrics/reporters/SolrGraphiteReporter.java | 49 +++++++--
.../solr/metrics/reporters/SolrJmxReporter.java | 106 ++++++++++++-------
.../metrics/reporters/SolrSlf4jReporter.java | 29 ++++-
.../reporters/solr/SolrClusterReporter.java | 14 +++
.../reporters/solr/SolrShardReporter.java | 14 ++-
.../src/test-files/solr/solr-solrreporter.xml | 4 +
.../solr/cloud/ReplicationFactorTest.java | 8 --
.../solr/metrics/SolrMetricReporterTest.java | 1 +
.../metrics/reporters/SolrJmxReporterTest.java | 27 ++++-
.../java/org/apache/solr/SolrTestCaseJ4.java | 14 +++
.../cloud/AbstractFullDistribZkTestBase.java | 8 --
.../java/org/apache/solr/util/TestHarness.java | 4 +-
20 files changed, 327 insertions(+), 91 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/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 419cafc..f099452 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -914,7 +914,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
SolrFieldCacheBean solrFieldCacheBean = new SolrFieldCacheBean();
// this is registered at the CONTAINER level because it's not core-specific - for now we
// also register it here for back-compat
- solrFieldCacheBean.initializeMetrics(metricManager, coreMetricManager.getRegistryName(), getCategory().toString());
+ solrFieldCacheBean.initializeMetrics(metricManager, coreMetricManager.getRegistryName(), "core");
infoRegistry.put("fieldCache", solrFieldCacheBean);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
index c6fe2ae..5f68286 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
@@ -471,10 +471,10 @@ public class SolrXmlConfig {
MBeanServer mBeanServer = JmxUtil.findFirstMBeanServer();
if (mBeanServer != null && !hasJmxReporter) {
log.info("MBean server found: " + mBeanServer + ", but no JMX reporters were configured - adding default JMX reporter.");
- Map<String,String> attributes = new HashMap<>();
+ Map<String,Object> attributes = new HashMap<>();
attributes.put("name", "default");
attributes.put("class", SolrJmxReporter.class.getName());
- PluginInfo defaultPlugin = new PluginInfo("reporter", attributes, null, null);
+ PluginInfo defaultPlugin = new PluginInfo("reporter", attributes);
configs.add(defaultPlugin);
}
return configs.toArray(new PluginInfo[configs.size()]);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
index 2a71047..193bf68 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
@@ -144,6 +144,9 @@ public class SolrCoreMetricManager implements Closeable {
@Override
public void close() throws IOException {
metricManager.closeReporters(getRegistryName(), tag);
+ if (getLeaderRegistryName() != null) {
+ metricManager.closeReporters(getLeaderRegistryName(), tag);
+ }
}
public SolrCore getCore() {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/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 a285b4c..d4eb06a 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -277,6 +277,36 @@ public class SolrMetricManager {
}
}
+ public static class AndFilter implements MetricFilter {
+ List<MetricFilter> filters = new ArrayList<>();
+
+ public AndFilter(Collection<MetricFilter> filters) {
+ if (filters != null) {
+ this.filters.addAll(filters);
+ }
+ }
+
+ public AndFilter(MetricFilter... filters) {
+ if (filters != null) {
+ for (MetricFilter filter : filters) {
+ if (filter != null) {
+ this.filters.add(filter);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean matches(String s, Metric metric) {
+ for (MetricFilter filter : filters) {
+ if (!filter.matches(s, metric)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
/**
* Return a set of existing registry names.
*/
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/SolrMetricReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricReporter.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricReporter.java
index ff2d3fc..9ad15d0 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricReporter.java
@@ -30,6 +30,7 @@ public abstract class SolrMetricReporter implements Closeable, PluginInfoInitial
protected final String registryName;
protected final SolrMetricManager metricManager;
protected PluginInfo pluginInfo;
+ protected boolean enabled = true;
/**
* Create a reporter for metrics managed in a named registry.
@@ -58,6 +59,17 @@ public abstract class SolrMetricReporter implements Closeable, PluginInfoInitial
}
/**
+ * Enable reporting, defaults to true. Implementations should check this flag in
+ * {@link #validate()} and accordingly enable or disable reporting.
+ * @param enabled enable, defaults to true when null or not set.
+ */
+ public void setEnabled(Boolean enabled) {
+ if (enabled != null) {
+ this.enabled = enabled;
+ }
+ }
+
+ /**
* Get the effective {@link PluginInfo} instance that was used for
* initialization of this plugin.
* @return plugin info, or null if not yet initialized.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/JmxObjectNameFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/JmxObjectNameFactory.java b/solr/core/src/java/org/apache/solr/metrics/reporters/JmxObjectNameFactory.java
index 7405f6e..b337cdd 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/JmxObjectNameFactory.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/JmxObjectNameFactory.java
@@ -105,9 +105,11 @@ public class JmxObjectNameFactory implements ObjectNameFactory {
sb.append(currentDomain);
sb.append(':');
}
- sb.append("reporter=");
- sb.append(reporterName);
+// sb.append("reporter=");
+// sb.append(reporterName);
+// sb.append(',');
if (props != null && props.length > 0) {
+ boolean added = false;
for (int i = 0; i < props.length; i += 2) {
if (props[i] == null || props[i].isEmpty()) {
continue;
@@ -119,9 +121,12 @@ public class JmxObjectNameFactory implements ObjectNameFactory {
sb.append(props[i]);
sb.append('=');
sb.append(props[i + 1]);
+ added = true;
+ }
+ if (added) {
+ sb.append(',');
}
}
- sb.append(',');
if (metricInfo != null) {
sb.append("category=");
sb.append(metricInfo.category.toString());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/MetricServiceRegistry.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/MetricServiceRegistry.java b/solr/core/src/java/org/apache/solr/metrics/reporters/MetricServiceRegistry.java
new file mode 100644
index 0000000..bacb104
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/MetricServiceRegistry.java
@@ -0,0 +1,23 @@
+package org.apache.solr.metrics.reporters;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ */
+public class MetricServiceRegistry<T> {
+ protected Map<String, T> registry = new ConcurrentHashMap<>();
+
+ public void register(String id, T service) {
+ registry.put(id, service);
+ }
+
+ public T get(String id) {
+ return registry.get(id);
+ }
+
+ public T unregister(String id) {
+ return registry.remove(id);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGangliaReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGangliaReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGangliaReporter.java
index 45561e5..28f7e83 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGangliaReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGangliaReporter.java
@@ -17,6 +17,9 @@
package org.apache.solr.metrics.reporters;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.MetricFilter;
@@ -24,21 +27,26 @@ import com.codahale.metrics.ganglia.GangliaReporter;
import info.ganglia.gmetric4j.gmetric.GMetric;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricReporter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
*/
public class SolrGangliaReporter extends SolrMetricReporter {
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private String host = null;
private int port = -1;
private boolean multicast;
private int period = 60;
private String instancePrefix = null;
- private String filterPrefix = null;
+ private List<String> filters = new ArrayList<>();
private boolean testing;
private GangliaReporter reporter;
+ private static final MetricServiceRegistry<GMetric> serviceRegistry = new MetricServiceRegistry<>();
+
// for unit tests
GMetric ganglia = null;
@@ -65,10 +73,24 @@ public class SolrGangliaReporter extends SolrMetricReporter {
this.instancePrefix = prefix;
}
- public void setFilter(String filter) {
- this.filterPrefix = filter;
+ /**
+ * Report only metrics with names matching any of the prefix filters.
+ * @param filters list of 0 or more prefixes. If the list is empty then
+ * all names will match.
+ */
+ public void setFilter(List<String> filters) {
+ if (filters == null || filters.isEmpty()) {
+ return;
+ }
+ this.filters.addAll(filters);
}
+ // due to vagaries of SolrPluginUtils.invokeSetters we need this too
+ public void setFilter(String filter) {
+ if (filter != null && !filter.isEmpty()) {
+ this.filters.add(filter);
+ }
+ }
public void setPeriod(int period) {
this.period = period;
@@ -89,6 +111,10 @@ public class SolrGangliaReporter extends SolrMetricReporter {
@Override
protected void validate() throws IllegalStateException {
+ if (!enabled) {
+ log.info("Reporter disabled for registry " + registryName);
+ return;
+ }
if (host == null) {
throw new IllegalStateException("Init argument 'host' must be set to a valid Ganglia server name.");
}
@@ -106,12 +132,19 @@ public class SolrGangliaReporter extends SolrMetricReporter {
//this is a separate method for unit tests
void start() {
if (!testing) {
- try {
- ganglia = new GMetric(host, port,
- multicast ? GMetric.UDPAddressingMode.MULTICAST : GMetric.UDPAddressingMode.UNICAST,
- 1);
- } catch (IOException ioe) {
- throw new IllegalStateException("Exception connecting to Ganglia", ioe);
+ synchronized (serviceRegistry) {
+ String id = host + ":" + port + ":" + multicast;
+ ganglia = serviceRegistry.get(id);
+ if (ganglia == null) {
+ try {
+ ganglia = new GMetric(host, port,
+ multicast ? GMetric.UDPAddressingMode.MULTICAST : GMetric.UDPAddressingMode.UNICAST,
+ 1);
+ serviceRegistry.register(id, ganglia);
+ } catch (IOException ioe) {
+ throw new IllegalStateException("Exception connecting to Ganglia", ioe);
+ }
+ }
}
}
if (instancePrefix == null) {
@@ -125,8 +158,8 @@ public class SolrGangliaReporter extends SolrMetricReporter {
.convertDurationsTo(TimeUnit.MILLISECONDS)
.prefixedWith(instancePrefix);
MetricFilter filter;
- if (filterPrefix != null) {
- filter = new SolrMetricManager.PrefixFilter(filterPrefix);
+ if (!filters.isEmpty()) {
+ filter = new SolrMetricManager.PrefixFilter(filters);
} else {
filter = MetricFilter.ALL;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
index 8565ce8..48416ce 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
@@ -18,6 +18,8 @@ package org.apache.solr.metrics.reporters;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.MetricFilter;
@@ -41,8 +43,11 @@ public class SolrGraphiteReporter extends SolrMetricReporter {
private int period = 60;
private boolean pickled = false;
private String instancePrefix = null;
- private String filterPrefix = null;
+ private List<String> filters = new ArrayList<>();
private GraphiteReporter reporter = null;
+ private boolean enabled = true;
+
+ private static final MetricServiceRegistry<GraphiteSender> serviceRegistry = new MetricServiceRegistry<>();
/**
* Create a Graphite reporter for metrics managed in a named registry.
@@ -67,10 +72,25 @@ public class SolrGraphiteReporter extends SolrMetricReporter {
this.instancePrefix = prefix;
}
+ /**
+ * Report only metrics with names matching any of the prefix filters.
+ * @param filters list of 0 or more prefixes. If the list is empty then
+ * all names will match.
+ */
+ public void setFilter(List<String> filters) {
+ if (filters == null || filters.isEmpty()) {
+ return;
+ }
+ this.filters.addAll(filters);
+ }
+
public void setFilter(String filter) {
- this.filterPrefix = filter;
+ if (filter != null && !filter.isEmpty()) {
+ this.filters.add(filter);
+ }
}
+
public void setPickled(boolean pickled) {
this.pickled = pickled;
}
@@ -81,6 +101,10 @@ public class SolrGraphiteReporter extends SolrMetricReporter {
@Override
protected void validate() throws IllegalStateException {
+ if (!enabled) {
+ log.info("Reporter disabled for registry " + registryName);
+ return;
+ }
if (host == null) {
throw new IllegalStateException("Init argument 'host' must be set to a valid Graphite server name.");
}
@@ -93,11 +117,18 @@ public class SolrGraphiteReporter extends SolrMetricReporter {
if (period < 1) {
throw new IllegalStateException("Init argument 'period' is in time unit 'seconds' and must be at least 1.");
}
- final GraphiteSender graphite;
- if (pickled) {
- graphite = new PickledGraphite(host, port);
- } else {
- graphite = new Graphite(host, port);
+ GraphiteSender graphite;
+ String id = host + ":" + port + ":" + pickled;
+ synchronized (serviceRegistry) {
+ graphite = serviceRegistry.get(id);
+ if (graphite == null) {
+ if (pickled) {
+ graphite = new PickledGraphite(host, port);
+ } else {
+ graphite = new Graphite(host, port);
+ }
+ serviceRegistry.register(id, graphite);
+ }
}
if (instancePrefix == null) {
instancePrefix = registryName;
@@ -110,8 +141,8 @@ public class SolrGraphiteReporter extends SolrMetricReporter {
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS);
MetricFilter filter;
- if (filterPrefix != null) {
- filter = new SolrMetricManager.PrefixFilter(filterPrefix);
+ if (!filters.isEmpty()) {
+ filter = new SolrMetricManager.PrefixFilter(filters);
} else {
filter = MetricFilter.ALL;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
index 6f13754..edbc17c 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
@@ -16,16 +16,18 @@
*/
package org.apache.solr.metrics.reporters;
+import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.JmxReporter;
@@ -50,10 +52,13 @@ public class SolrJmxReporter extends SolrMetricReporter {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private static final MetricServiceRegistry<MBeanServer> serviceRegistry = new MetricServiceRegistry<>();
+
private String domain;
private String agentId;
private String serviceUrl;
private String rootName;
+ private List<String> filters = new ArrayList<>();
private JmxReporter reporter;
private MetricRegistry registry;
@@ -81,20 +86,29 @@ public class SolrJmxReporter extends SolrMetricReporter {
public synchronized void init(PluginInfo pluginInfo) {
super.init(pluginInfo);
if (!enabled) {
- log.info("JMX monitoring disabled for registry " + registryName);
+ log.info("Reporter disabled for registry " + registryName);
return;
}
log.debug("Initializing for registry " + registryName);
if (serviceUrl != null && agentId != null) {
mBeanServer = JmxUtil.findFirstMBeanServer();
- log.warn("No more than one of serviceUrl(%s) and agentId(%s) should be configured, using first MBeanServer instead of configuration.",
+ log.warn("No more than one of serviceUrl({}) and agentId({}) should be configured, using first MBeanServer instead of configuration.",
serviceUrl, agentId, mBeanServer);
} else if (serviceUrl != null) {
- try {
- mBeanServer = JmxUtil.findMBeanServerForServiceUrl(serviceUrl);
- } catch (IOException e) {
- log.warn("findMBeanServerForServiceUrl(%s) exception: %s", serviceUrl, e);
- mBeanServer = null;
+ // reuse existing services
+ synchronized (serviceRegistry) {
+ mBeanServer = serviceRegistry.get(serviceUrl);
+ if (mBeanServer == null) {
+ try {
+ mBeanServer = JmxUtil.findMBeanServerForServiceUrl(serviceUrl);
+ if (mBeanServer != null) {
+ serviceRegistry.register(serviceUrl, mBeanServer);
+ }
+ } catch (IOException e) {
+ log.warn("findMBeanServerForServiceUrl({}) exception: {}", serviceUrl, e);
+ mBeanServer = null;
+ }
+ }
}
} else if (agentId != null) {
mBeanServer = JmxUtil.findMBeanServerForAgentId(agentId);
@@ -108,6 +122,9 @@ public class SolrJmxReporter extends SolrMetricReporter {
return;
}
+ if (domain == null || domain.isEmpty()) {
+ domain = registryName;
+ }
String fullDomain = domain;
if (rootName != null && !rootName.isEmpty()) {
fullDomain = rootName + "." + domain;
@@ -115,7 +132,15 @@ public class SolrJmxReporter extends SolrMetricReporter {
JmxObjectNameFactory jmxObjectNameFactory = new JmxObjectNameFactory(pluginInfo.name, fullDomain);
registry = metricManager.registry(registryName);
// filter out MetricsMap gauges - we have a better way of handling them
- MetricFilter filter = (name, metric) -> !(metric instanceof MetricsMap);
+ MetricFilter mmFilter = (name, metric) -> !(metric instanceof MetricsMap);
+ MetricFilter filter;
+ if (filters.isEmpty()) {
+ filter = mmFilter;
+ } else {
+ // apply also prefix filters
+ SolrMetricManager.PrefixFilter prefixFilter = new SolrMetricManager.PrefixFilter(filters);
+ filter = new SolrMetricManager.AndFilter(prefixFilter, mmFilter);
+ }
reporter = JmxReporter.forRegistry(registry)
.registerWith(mBeanServer)
@@ -224,14 +249,20 @@ public class SolrJmxReporter extends SolrMetricReporter {
}
/**
- * Enable reporting, defaults to true.
- * @param enabled enable, defaults to true when null or not set.
+ * Report only metrics with names matching any of the prefix filters.
+ * @param filters list of 0 or more prefixes. If the list is empty then
+ * all names will match.
*/
- public void setEnabled(Boolean enabled) {
- if (enabled == null) {
- this.enabled = true;
- } else {
- this.enabled = enabled;
+ public void setFilter(List<String> filters) {
+ if (filters == null || filters.isEmpty()) {
+ return;
+ }
+ this.filters.addAll(filters);
+ }
+
+ public void setFilter(String filter) {
+ if (filter != null && !filter.isEmpty()) {
+ this.filters.add(filter);
}
}
@@ -254,7 +285,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
@Override
public String toString() {
- return String.format(Locale.ENGLISH, "[%s@%s: rootName = %, domain = %s, service url = %s, agent id = %s]",
+ return String.format(Locale.ENGLISH, "[%s@%s: rootName = %s, domain = %s, service url = %s, agent id = %s]",
getClass().getName(), Integer.toHexString(hashCode()), rootName, domain, serviceUrl, agentId);
}
@@ -263,8 +294,6 @@ public class SolrJmxReporter extends SolrMetricReporter {
JmxObjectNameFactory nameFactory;
// keep the names so that we can unregister them on core close
Set<ObjectName> registered = new HashSet<>();
- // prevent ConcurrentModificationException when closing
- ReentrantLock lock = new ReentrantLock();
MetricsMapListener(MBeanServer server, JmxObjectNameFactory nameFactory) {
this.server = server;
@@ -276,38 +305,41 @@ public class SolrJmxReporter extends SolrMetricReporter {
if (!(gauge instanceof MetricsMap)) {
return;
}
- if (!lock.tryLock()) {
- return;
- }
- try {
- ObjectName objectName = nameFactory.createName("gauges", nameFactory.getDomain(), name);
- // some MBean servers re-write object name to include additional properties
- ObjectInstance instance = server.registerMBean(gauge, objectName);
- if (instance != null) {
- registered.add(instance.getObjectName());
+ synchronized (server) {
+ try {
+ ObjectName objectName = nameFactory.createName("gauges", nameFactory.getDomain(), name);
+ log.debug("REGISTER " + objectName);
+ if (registered.contains(objectName) || server.isRegistered(objectName)) {
+ log.debug("-unregistering old instance of " + objectName);
+ try {
+ server.unregisterMBean(objectName);
+ } catch (InstanceNotFoundException e) {
+ // ignore
+ }
+ }
+ // some MBean servers re-write object name to include additional properties
+ ObjectInstance instance = server.registerMBean(gauge, objectName);
+ if (instance != null) {
+ registered.add(instance.getObjectName());
+ }
+ } catch (Exception e) {
+ log.warn("bean registration error", e);
}
- } catch (Exception e) {
- log.warn("bean registration error", e);
- } finally {
- lock.unlock();
}
}
public void close() {
- lock.lock();
- try {
+ synchronized (server) {
for (ObjectName name : registered) {
try {
if (server.isRegistered(name)) {
server.unregisterMBean(name);
}
} catch (Exception e) {
- log.warn("bean unregistration error", e);
+ log.debug("bean unregistration error", e);
}
}
registered.clear();
- } finally {
- lock.unlock();
}
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
index 817dda1..8b7c35e 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
@@ -18,6 +18,8 @@ package org.apache.solr.metrics.reporters;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.MetricFilter;
@@ -47,7 +49,7 @@ public class SolrSlf4jReporter extends SolrMetricReporter {
private int period = 60;
private String instancePrefix = null;
private String logger = null;
- private String filterPrefix = null;
+ private List<String> filters = new ArrayList<>();
private Slf4jReporter reporter;
/**
@@ -65,10 +67,25 @@ public class SolrSlf4jReporter extends SolrMetricReporter {
this.instancePrefix = prefix;
}
+ /**
+ * Report only metrics with names matching any of the prefix filters.
+ * @param filters list of 0 or more prefixes. If the list is empty then
+ * all names will match.
+ */
+ public void setFilter(List<String> filters) {
+ if (filters == null || filters.isEmpty()) {
+ return;
+ }
+ this.filters.addAll(filters);
+ }
+
public void setFilter(String filter) {
- this.filterPrefix = filter;
+ if (filter != null && !filter.isEmpty()) {
+ this.filters.add(filter);
+ }
}
+
public void setLogger(String logger) {
this.logger = logger;
}
@@ -79,6 +96,10 @@ public class SolrSlf4jReporter extends SolrMetricReporter {
@Override
protected void validate() throws IllegalStateException {
+ if (!enabled) {
+ log.info("Reporter disabled for registry " + registryName);
+ return;
+ }
if (period < 1) {
throw new IllegalStateException("Init argument 'period' is in time unit 'seconds' and must be at least 1.");
}
@@ -93,8 +114,8 @@ public class SolrSlf4jReporter extends SolrMetricReporter {
.convertDurationsTo(TimeUnit.MILLISECONDS);
MetricFilter filter;
- if (filterPrefix != null) {
- filter = new SolrMetricManager.PrefixFilter(filterPrefix);
+ if (!filters.isEmpty()) {
+ filter = new SolrMetricManager.PrefixFilter(filters);
} else {
filter = MetricFilter.ALL;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
index 56dc36f..30d31d9 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrClusterReporter.java
@@ -159,6 +159,16 @@ public class SolrClusterReporter extends SolrMetricReporter {
});
}
+ public void setReport(Map map) {
+ if (map == null || map.isEmpty()) {
+ return;
+ }
+ SolrReporter.Report r = SolrReporter.Report.fromMap(map);
+ if (r != null) {
+ reports.add(r);
+ }
+ }
+
// for unit tests
int getPeriod() {
return period;
@@ -189,6 +199,10 @@ public class SolrClusterReporter extends SolrMetricReporter {
if (reporter != null) {
reporter.close();;
}
+ if (!enabled) {
+ log.info("Reporter disabled for registry " + registryName);
+ return;
+ }
// start reporter only in cloud mode
if (!cc.isZooKeeperAware()) {
log.warn("Not ZK-aware, not starting...");
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
index 8b36d3e..6cc5a07 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrShardReporter.java
@@ -98,7 +98,13 @@ public class SolrShardReporter extends SolrMetricReporter {
if (filterConfig == null || filterConfig.isEmpty()) {
return;
}
- filters = filterConfig;
+ filters.addAll(filterConfig);
+ }
+
+ public void setFilter(String filter) {
+ if (filter != null && !filter.isEmpty()) {
+ this.filters.add(filter);
+ }
}
// for unit tests
@@ -128,13 +134,17 @@ public class SolrShardReporter extends SolrMetricReporter {
if (reporter != null) {
reporter.close();
}
+ if (!enabled) {
+ log.info("Reporter disabled for registry " + registryName);
+ return;
+ }
if (core.getCoreDescriptor().getCloudDescriptor() == null) {
// not a cloud core
log.warn("Not initializing shard reporter for non-cloud core " + core.getName());
return;
}
if (period < 1) { // don't start it
- log.warn("Not starting shard reporter ");
+ log.warn("period=" + period + ", not starting shard reporter ");
return;
}
// our id is coreNodeName
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/test-files/solr/solr-solrreporter.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/solr-solrreporter.xml b/solr/core/src/test-files/solr/solr-solrreporter.xml
index db03e42..a66d9d0 100644
--- a/solr/core/src/test-files/solr/solr-solrreporter.xml
+++ b/solr/core/src/test-files/solr/solr-solrreporter.xml
@@ -38,6 +38,10 @@
</solrcloud>
<metrics>
+ <!-- disable default JMX reporter to avoid conflicts with multiple CoreContainers. -->
+ <reporter name="defaultJmx" class="org.apache.solr.metrics.reporters.SolrJmxReporter">
+ <bool name="enabled">false</bool>
+ </reporter>
<reporter name="test" group="shard">
<int name="period">5</int>
<str name="filter">UPDATE\./update/.*requests</str>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java b/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java
index 9441e3f..5921318 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ReplicationFactorTest.java
@@ -71,14 +71,6 @@ public class ReplicationFactorTest extends AbstractFullDistribZkTestBase {
return createProxiedJetty(solrHome, dataDir, shardList, solrConfigOverride, schemaOverride);
}
- protected int getNextAvailablePort() throws Exception {
- int port = -1;
- try (ServerSocket s = new ServerSocket(0)) {
- port = s.getLocalPort();
- }
- return port;
- }
-
@Test
public void test() throws Exception {
log.info("replication factor test running");
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/test/org/apache/solr/metrics/SolrMetricReporterTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrMetricReporterTest.java b/solr/core/src/test/org/apache/solr/metrics/SolrMetricReporterTest.java
index b275919..eb9e32b 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricReporterTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricReporterTest.java
@@ -42,6 +42,7 @@ public class SolrMetricReporterTest extends LuceneTestCase {
Map<String, Object> attrs = new HashMap<>();
attrs.put(FieldType.CLASS_NAME, MockMetricReporter.class.getName());
attrs.put(CoreAdminParams.NAME, TestUtil.randomUnicodeString(random));
+ attrs.put("enabled", String.valueOf(random.nextBoolean()));
boolean shouldDefineConfigurable = random.nextBoolean();
String configurable = TestUtil.randomUnicodeString(random);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
index ba46691..41c75e0 100644
--- a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
@@ -21,6 +21,8 @@ import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
@@ -41,12 +43,16 @@ import org.apache.solr.metrics.SolrMetricTestUtils;
import org.apache.solr.schema.FieldType;
import org.junit.After;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
public class SolrJmxReporterTest extends SolrTestCaseJ4 {
private static final int MAX_ITERATIONS = 20;
+ private static Registry jmxRegistry;
+ private static int jmxPort;
+
private String domain;
private SolrCoreMetricManager coreMetricManager;
@@ -54,15 +60,24 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
private SolrJmxReporter reporter;
private MBeanServer mBeanServer;
private String reporterName;
+ private String rootName;
+
+ @BeforeClass
+ public static void init() throws Exception {
+ jmxPort = getNextAvailablePort();
+ assertFalse(jmxPort == -1);
+ jmxRegistry = LocateRegistry.createRegistry(jmxPort);
+ }
@Before
public void beforeTest() throws Exception {
// make sure we're running an MBeanServer
- ManagementFactory.getPlatformMBeanServer();
+ //ManagementFactory.getPlatformMBeanServer();
initCore("solrconfig-basic.xml", "schema.xml");
final SolrCore core = h.getCore();
domain = core.getName();
+ rootName = TestUtil.randomSimpleString(random(), 1, 10);
coreMetricManager = core.getCoreMetricManager();
metricManager = core.getCoreDescriptor().getCoreContainer().getMetricManager();
@@ -80,6 +95,8 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
reporter = (SolrJmxReporter) reporters.get(taggedName);
mBeanServer = reporter.getMBeanServer();
assertNotNull("MBean server not found.", mBeanServer);
+ System.err.println("jmxPort=" + jmxPort);
+// Thread.sleep(1000000000);
}
private PluginInfo createReporterPluginInfo() {
@@ -90,6 +107,8 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
Map<String, Object> attrs = new HashMap<>();
attrs.put(FieldType.CLASS_NAME, className);
attrs.put(CoreAdminParams.NAME, reporterName);
+ attrs.put("rootName", rootName);
+ attrs.put("serviceUrl", "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/solrjmx");
boolean shouldOverrideDomain = random.nextBoolean();
if (shouldOverrideDomain) {
@@ -129,7 +148,7 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
Set<ObjectInstance> objects = mBeanServer.queryMBeans(null, null);
assertEquals(registered.size(), objects.stream().
filter(o -> scope.equals(o.getObjectName().getKeyProperty("scope")) &&
- reporterName.equals(o.getObjectName().getKeyProperty("reporter"))).count());
+ rootName.equals(o.getObjectName().getDomain())).count());
}
}
@@ -145,7 +164,7 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
Set<ObjectInstance> objects = mBeanServer.queryMBeans(null, null);
assertEquals(metrics.size(), objects.stream().
filter(o -> scope.equals(o.getObjectName().getKeyProperty("scope")) &&
- reporterName.equals(o.getObjectName().getKeyProperty("reporter"))).count());
+ o.getObjectName().getDomain().equals(rootName)).count());
h.getCoreContainer().reload(h.getCore().getName());
PluginInfo pluginInfo = createReporterPluginInfo();
@@ -156,7 +175,7 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
objects = mBeanServer.queryMBeans(null, null);
assertEquals(metrics.size(), objects.stream().
filter(o -> scope.equals(o.getObjectName().getKeyProperty("scope")) &&
- pluginInfo.name.equals(o.getObjectName().getKeyProperty("reporter"))).count());
+ rootName.equals(o.getObjectName().getDomain())).count());
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 0d4cedd..54ab06d 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -33,6 +33,7 @@ import java.lang.annotation.Target;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
+import java.net.ServerSocket;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -802,6 +803,19 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
configString = schemaString = null;
}
+ /**
+ * Find next available local port.
+ * @return available port number or -1 if none could be found
+ * @throws Exception on IO errors
+ */
+ protected static int getNextAvailablePort() throws Exception {
+ int port = -1;
+ try (ServerSocket s = new ServerSocket(0)) {
+ port = s.getLocalPort();
+ }
+ return port;
+ }
+
/** Validates an update XML String is successful
*/
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
index ade1c69..0a06d78 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
@@ -598,14 +598,6 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
return proxy;
}
- protected int getNextAvailablePort() throws Exception {
- int port = -1;
- try (ServerSocket s = new ServerSocket(0)) {
- port = s.getLocalPort();
- }
- return port;
- }
-
private File getRelativeSolrHomePath(File solrHome) {
final Path solrHomePath = solrHome.toPath();
final Path curDirPath = new File("").getAbsoluteFile().toPath();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4c774f1d/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
index 2386681..982f2b1 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
@@ -193,10 +193,10 @@ public class TestHarness extends BaseTestHarness {
30000, 30000,
UpdateShardHandlerConfig.DEFAULT_METRICNAMESTRATEGY);
// universal default metric reporter
- Map<String,String> attributes = new HashMap<>();
+ Map<String,Object> attributes = new HashMap<>();
attributes.put("name", "default");
attributes.put("class", SolrJmxReporter.class.getName());
- PluginInfo defaultPlugin = new PluginInfo("reporter", attributes, null, null);
+ PluginInfo defaultPlugin = new PluginInfo("reporter", attributes);
return new NodeConfig.NodeConfigBuilder("testNode", loader)
.setUseSchemaCache(Boolean.getBoolean("shareSchema"))