SOLR-9921 Separate SolrMetricProducer from SolrInfoMBean.

This commit is contained in:
Andrzej Bialecki 2017-01-04 15:31:31 +01:00
parent ccdbb6ac0e
commit 12d8492217
11 changed files with 28 additions and 207 deletions

View File

@ -178,8 +178,8 @@ New Features
* SOLR-9860: Enable configuring invariantParams via HttpSolrClient.Builder (Hrishikesh Gadre, Ishan Chattopadhyaya)
* SOLR-4735: Improve metrics reporting. This uses the dropwizard metric library, adding an internal API
for registering and reporting metrics from Solr components. Several new metrics and an improved JMX
* SOLR-4735, SOLR-9921: Improve metrics reporting. This uses the dropwizard metric library, adding an internal
API for registering and reporting metrics from Solr components. Several new metrics and an improved JMX
reporter have been added (Alan Woodward, Jeff Wartes, Christine Poerschke, Kelvin Wong, shalin, ab)
* SOLR-9788: Use instrumented jetty classes provided by the dropwizard metric library. (shalin)

View File

@ -18,8 +18,6 @@ package org.apache.solr.handler;
import java.lang.invoke.MethodHandles;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Meter;
@ -133,14 +131,13 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registryName, String scope) {
public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) {
numErrors = manager.meter(registryName, "errors", getCategory().toString(), scope);
numServerErrors = manager.meter(registryName, "serverErrors", getCategory().toString(), scope);
numClientErrors = manager.meter(registryName, "clientErrors", getCategory().toString(), scope);
numTimeouts = manager.meter(registryName, "timeouts", getCategory().toString(), scope);
requests = manager.counter(registryName, "requests", getCategory().toString(), scope);
requestTimes = manager.timer(registryName, "requestTimes", getCategory().toString(), scope);
return Arrays.asList("errors", "serverErrors", "clientErrors", "timeouts", "requestTimes", "requests");
}
public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {

View File

@ -18,7 +18,6 @@ package org.apache.solr.handler.admin;
import java.io.File;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@ -115,11 +114,10 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registryName, String scope) {
Collection<String> metrics = super.initializeMetrics(manager, registryName, scope);
public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) {
super.initializeMetrics(manager, registryName, scope);
parallelExecutor = MetricUtils.instrumentedExecutorService(parallelExecutor, manager.registry(registryName),
SolrMetricManager.mkName("parallelCoreAdminExecutor", getCategory().name(),scope, "threadPool"));
return metrics;
}
/**

View File

@ -48,9 +48,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@ -365,48 +362,11 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public String getVersion() {
return getClass().getPackage().getSpecificationVersion();
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope) {
List<String> metricNames = new ArrayList<>(4);
metricNames.addAll(clientConnectionManager.initializeMetrics(manager, registry, scope));
metricNames.addAll(httpRequestExecutor.initializeMetrics(manager, registry, scope));
public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
clientConnectionManager.initializeMetrics(manager, registry, scope);
httpRequestExecutor.initializeMetrics(manager, registry, scope);
commExecutor = MetricUtils.instrumentedExecutorService(commExecutor,
manager.registry(registry),
SolrMetricManager.mkName("httpShardExecutor", scope, "threadPool"));
return metricNames;
}
@Override
public String getDescription() {
return "Metrics tracked by HttpShardHandlerFactory for distributed query requests";
}
@Override
public Category getCategory() {
return Category.OTHER;
}
@Override
public String getSource() {
return null;
}
@Override
public URL[] getDocs() {
return new URL[0];
}
@Override
public NamedList getStatistics() {
return null;
}
}

View File

@ -18,7 +18,6 @@ package org.apache.solr.metrics;
import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.lang.invoke.MethodHandles;
import org.apache.solr.core.NodeConfig;
@ -88,15 +87,11 @@ public class SolrCoreMetricManager implements Closeable {
* @param producer producer of metrics to be registered
*/
public void registerMetricProducer(String scope, SolrMetricProducer producer) {
if (scope == null || producer == null || producer.getCategory() == null) {
if (scope == null || producer == null) {
throw new IllegalArgumentException("registerMetricProducer() called with illegal arguments: " +
"scope = " + scope + ", producer = " + producer);
}
Collection<String> registered = producer.initializeMetrics(metricManager, getRegistryName(), scope);
if (registered == null || registered.isEmpty()) {
throw new IllegalArgumentException("registerMetricProducer() did not register any metrics " +
"for scope = " + scope + ", producer = " + producer);
}
producer.initializeMetrics(metricManager, getRegistryName(), scope);
}
/**

View File

@ -16,15 +16,10 @@
*/
package org.apache.solr.metrics;
import java.util.Collection;
import org.apache.solr.core.SolrInfoMBean;
/**
* Extension of {@link SolrInfoMBean} for use by objects that
* expose metrics through {@link SolrCoreMetricManager}.
* Used by objects that expose metrics through {@link SolrCoreMetricManager}.
*/
public interface SolrMetricProducer extends SolrInfoMBean {
public interface SolrMetricProducer {
/**
* Initializes metrics specific to this producer
@ -32,7 +27,6 @@ public interface SolrMetricProducer extends SolrInfoMBean {
* @param registry registry name where metrics are registered
* @param scope scope of the metrics (eg. handler name) to separate metrics of
* instances of the same component executing in different contexts
* @return registered (or existing) unqualified names of metrics specific to this producer.
*/
Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope);
void initializeMetrics(SolrMetricManager manager, String registry, String scope);
}

View File

@ -18,9 +18,6 @@ package org.apache.solr.update;
import java.lang.invoke.MethodHandles;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import com.codahale.metrics.InstrumentedExecutorService;
@ -34,6 +31,7 @@ import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.ExecutorUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SolrjNamedThreadFactory;
import org.apache.solr.core.SolrInfoMBean;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
import org.apache.solr.util.stats.InstrumentedHttpRequestExecutor;
@ -41,7 +39,7 @@ import org.apache.solr.util.stats.InstrumentedPoolingHttpClientConnectionManager
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UpdateShardHandler implements SolrMetricProducer {
public class UpdateShardHandler implements SolrMetricProducer, SolrInfoMBean {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -99,17 +97,15 @@ public class UpdateShardHandler implements SolrMetricProducer {
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope) {
List<String> metricNames = new ArrayList<>(4);
metricNames.addAll(clientConnectionManager.initializeMetrics(manager, registry, scope));
metricNames.addAll(httpRequestExecutor.initializeMetrics(manager, registry, scope));
public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
clientConnectionManager.initializeMetrics(manager, registry, scope);
httpRequestExecutor.initializeMetrics(manager, registry, scope);
updateExecutor = new InstrumentedExecutorService(updateExecutor,
manager.registry(registry),
SolrMetricManager.mkName("updateExecutor", scope, "threadPool"));
recoveryExecutor = new InstrumentedExecutorService(recoveryExecutor,
manager.registry(registry),
SolrMetricManager.mkName("recoveryExecutor", scope, "threadPool"));
return metricNames;
}
@Override

View File

@ -19,9 +19,6 @@ package org.apache.solr.util.stats;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import com.codahale.metrics.MetricRegistry;
@ -35,7 +32,6 @@ import org.apache.http.client.methods.HttpRequestWrapper;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
@ -71,45 +67,9 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public String getVersion() {
return getClass().getPackage().getSpecificationVersion();
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope) {
public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
this.metricsRegistry = manager.registry(registry);
this.scope = scope;
return Collections.emptyList(); // we do not know the names of the metrics yet
}
@Override
public String getDescription() {
return null;
}
@Override
public Category getCategory() {
return Category.OTHER;
}
@Override
public String getSource() {
return null;
}
@Override
public URL[] getDocs() {
return null;
}
@Override
public NamedList getStatistics() {
return null;
}
private String getNameFor(HttpRequest request) {

View File

@ -17,16 +17,11 @@
package org.apache.solr.util.stats;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import org.apache.http.config.Registry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
@ -51,17 +46,7 @@ public class InstrumentedPoolingHttpClientConnectionManager extends PoolingHttpC
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public String getVersion() {
return getClass().getPackage().getSpecificationVersion();
}
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope) {
public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
this.metricsRegistry = manager.registry(registry);
metricsRegistry.register(SolrMetricManager.mkName("availableConnections", scope),
(Gauge<Integer>) () -> {
@ -83,31 +68,5 @@ public class InstrumentedPoolingHttpClientConnectionManager extends PoolingHttpC
// this acquires a lock on the connection pool; remove if contention sucks
return getTotalStats().getPending();
});
return Arrays.asList("availableConnections", "leasedConnections", "maxConnections", "pendingConnections");
}
@Override
public String getDescription() {
return "";
}
@Override
public Category getCategory() {
return Category.OTHER;
}
@Override
public String getSource() {
return null;
}
@Override
public URL[] getDocs() {
return null;
}
@Override
public NamedList getStatistics() {
return null;
}
}

View File

@ -68,11 +68,10 @@ public class SolrCoreMetricManagerTest extends SolrTestCaseJ4 {
coreMetricManager.registerMetricProducer(scope, producer);
assertNotNull(scope);
assertNotNull(category);
assertNotNull(metrics);
assertRegistered(scope, metrics, coreMetricManager);
} catch (final IllegalArgumentException e) {
assertTrue("expected at least one null but got: scope="+scope+" category="+category+" metrics="+metrics,
(scope == null || category == null || metrics == null));
assertTrue("expected at least one null but got: scope="+scope+", category="+category,
(scope == null || category == null));
assertRegistered(scope, new HashMap<>(), coreMetricManager);
}
}
@ -130,7 +129,7 @@ public class SolrCoreMetricManagerTest extends SolrTestCaseJ4 {
}
private void assertRegistered(String scope, Map<String, Counter> newMetrics, SolrCoreMetricManager coreMetricManager) {
if (scope == null) {
if (scope == null || newMetrics == null) {
return;
}
String filter = "." + scope + ".";

View File

@ -16,17 +16,13 @@
*/
package org.apache.solr.metrics;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import com.codahale.metrics.Counter;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrInfoMBean;
public final class SolrMetricTestUtils {
@ -82,49 +78,16 @@ public final class SolrMetricTestUtils {
public static SolrMetricProducer getProducerOf(SolrMetricManager metricManager, SolrInfoMBean.Category category, String scope, Map<String, Counter> metrics) {
return new SolrMetricProducer() {
@Override
public Collection<String> initializeMetrics(SolrMetricManager manager, String registry, String scope) {
public void initializeMetrics(SolrMetricManager manager, String registry, String scope) {
if (category == null) {
throw new IllegalArgumentException("null category");
}
if (metrics == null || metrics.isEmpty()) {
return Collections.emptyList();
return;
}
for (Map.Entry<String, Counter> entry : metrics.entrySet()) {
manager.counter(registry, entry.getKey(), category.toString(), scope);
}
return metrics.keySet();
}
@Override
public String getName() {
return scope;
}
@Override
public String getVersion() {
return "0.0";
}
@Override
public String getDescription() {
return "foo";
}
@Override
public Category getCategory() {
return category;
}
@Override
public String getSource() {
return null;
}
@Override
public URL[] getDocs() {
return new URL[0];
}
@Override
public NamedList getStatistics() {
return null;
}
@Override