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 2019/10/18 16:44:25 UTC
[lucene-solr] branch branch_8x updated: SOLR-13677: All Metrics
Gauges should be unregistered by components that registered them.
This is an automated email from the ASF dual-hosted git repository.
ab pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new 441af3e SOLR-13677: All Metrics Gauges should be unregistered by components that registered them.
441af3e is described below
commit 441af3e7aa5266e7929c93cb5f3abe0746e5c054
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Fri Oct 18 17:13:30 2019 +0200
SOLR-13677: All Metrics Gauges should be unregistered by components that registered them.
---
solr/CHANGES.txt | 2 +
.../solr/handler/dataimport/DataImportHandler.java | 8 +-
.../org/apache/solr/cloud/ReplicateFromLeader.java | 2 +-
.../java/org/apache/solr/core/CoreContainer.java | 79 ++++++-----
.../org/apache/solr/core/HdfsDirectoryFactory.java | 15 ++-
.../src/java/org/apache/solr/core/PluginBag.java | 18 ++-
.../src/java/org/apache/solr/core/SolrCore.java | 70 +++++-----
.../java/org/apache/solr/core/SolrInfoBean.java | 6 +
.../apache/solr/handler/ReplicationHandler.java | 47 ++++---
.../apache/solr/handler/RequestHandlerBase.java | 49 ++++---
.../solr/handler/admin/CoreAdminHandler.java | 9 +-
.../solr/handler/component/SuggestComponent.java | 23 ++--
.../apache/solr/metrics/SolrCoreMetricManager.java | 47 ++++---
.../org/apache/solr/metrics/SolrMetricManager.java | 28 ++--
.../apache/solr/metrics/SolrMetricProducer.java | 82 ++++++++++--
.../apache/solr/metrics/SolrMetricsContext.java | 114 ++++++++++++++++
.../java/org/apache/solr/search/CaffeineCache.java | 18 +--
.../java/org/apache/solr/search/FastLRUCache.java | 55 ++++----
.../src/java/org/apache/solr/search/LFUCache.java | 27 ++--
.../src/java/org/apache/solr/search/LRUCache.java | 37 +++---
.../src/java/org/apache/solr/search/SolrCache.java | 4 +-
.../org/apache/solr/search/SolrCacheHolder.java | 12 +-
.../org/apache/solr/search/SolrFieldCacheBean.java | 16 +--
.../org/apache/solr/search/SolrIndexSearcher.java | 65 ++++-----
.../apache/solr/security/AuditLoggerPlugin.java | 45 ++++---
.../apache/solr/security/AuthenticationPlugin.java | 61 ++++-----
.../apache/solr/servlet/SolrDispatchFilter.java | 3 +-
.../org/apache/solr/store/blockcache/Metrics.java | 20 +--
.../solr/store/hdfs/HdfsLocalityReporter.java | 21 +--
.../apache/solr/update/DirectUpdateHandler2.java | 62 ++++-----
.../org/apache/solr/update/SolrIndexWriter.java | 38 +++---
.../java/org/apache/solr/update/UpdateHandler.java | 6 -
.../org/apache/solr/update/UpdateShardHandler.java | 25 ++--
.../stats/InstrumentedHttpListenerFactory.java | 17 +--
...rumentedPoolingHttpClientConnectionManager.java | 30 +++--
.../solr/handler/admin/MetricsHandlerTest.java | 146 +++++++++++++++++++--
.../org/apache/solr/search/TestCaffeineCache.java | 1 +
.../org/apache/solr/search/TestFastLRUCache.java | 15 +--
.../test/org/apache/solr/search/TestLFUCache.java | 2 +-
.../test/org/apache/solr/search/TestLRUCache.java | 9 +-
.../org/apache/solr/common/util/ExecutorUtil.java | 1 +
41 files changed, 834 insertions(+), 501 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index e1f61c9..6861f79 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -273,6 +273,8 @@ Bug Fixes
* SOLR-13843: The MOVEREPLICA API ignores replica type and always adds 'nrt' replicas (Amrit Sarkar via shalin)
+* SOLR-13677: All Metrics Gauges should be unregistered by components that registered them. (noble, ab)
+
Other Changes
----------------------
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
index 50938e4..8b64b6f 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java
@@ -36,7 +36,7 @@ import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.RawResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
@@ -275,8 +275,8 @@ public class DataImportHandler extends RequestHandlerBase implements
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- super.initializeMetrics(manager, registryName, tag, scope);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ super.initializeMetrics(parentContext, scope);
metrics = new MetricsMap((detailed, map) -> {
if (importer != null) {
DocBuilder.Statistics cumulative = importer.cumulativeStatistics;
@@ -299,7 +299,7 @@ public class DataImportHandler extends RequestHandlerBase implements
map.put(DataImporter.MSG.TOTAL_DOCS_SKIPPED, cumulative.skipDocCount);
}
});
- manager.registerGauge(this, registryName, metrics, tag, true, "importer", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, metrics, true, "importer", getCategory().toString(), scope);
}
// //////////////////////SolrInfoMBeans methods //////////////////////
diff --git a/solr/core/src/java/org/apache/solr/cloud/ReplicateFromLeader.java b/solr/core/src/java/org/apache/solr/cloud/ReplicateFromLeader.java
index 957b321..17a6ec3 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ReplicateFromLeader.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ReplicateFromLeader.java
@@ -133,7 +133,7 @@ public class ReplicateFromLeader {
public void stopReplication() {
if (replicationProcess != null) {
- replicationProcess.close();
+ replicationProcess.shutdown();
}
}
}
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 69aa976..0d83982 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -100,6 +100,7 @@ import org.apache.solr.logging.MDCLoggingContext;
import org.apache.solr.metrics.SolrCoreMetricManager;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.search.SolrFieldCacheBean;
@@ -210,7 +211,9 @@ public class CoreContainer {
protected volatile SolrMetricManager metricManager;
- protected volatile String metricTag = Integer.toHexString(hashCode());
+ protected volatile String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null);
+
+ protected volatile SolrMetricsContext solrMetricsContext;
protected MetricsHandler metricsHandler;
@@ -609,6 +612,8 @@ public class CoreContainer {
containerHandlers.getApiBag().register(new AnnotatedApi(packageStoreAPI.writeAPI), Collections.EMPTY_MAP);
metricManager = new SolrMetricManager(loader, cfg.getMetricsConfig());
+ String registryName = SolrMetricManager.getRegistryName(SolrInfoBean.Group.node);
+ solrMetricsContext = new SolrMetricsContext(metricManager, registryName, metricTag);
coreContainerWorkExecutor = MetricUtils.instrumentedExecutorService(
coreContainerWorkExecutor, null,
@@ -622,7 +627,7 @@ public class CoreContainer {
}
updateShardHandler = new UpdateShardHandler(cfg.getUpdateShardHandlerConfig());
- updateShardHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, "updateShardHandler");
+ updateShardHandler.initializeMetrics(solrMetricsContext, "updateShardHandler");
solrCores.load(loader);
@@ -635,7 +640,9 @@ public class CoreContainer {
if (isZooKeeperAware()) {
pkiAuthenticationPlugin = new PKIAuthenticationPlugin(this, zkSys.getZkController().getNodeName(),
(PublicKeyHandler) containerHandlers.get(PublicKeyHandler.PATH));
- pkiAuthenticationPlugin.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, "/authentication/pki");
+ // use deprecated API for back-compat, remove in 9.0
+ pkiAuthenticationPlugin.initializeMetrics(
+ solrMetricsContext.metricManager, solrMetricsContext.registry, solrMetricsContext.tag, "/authentication/pki");
TracerConfigurator.loadTracer(loader, cfg.getTracerConfiguratorPluginInfo(), getZkController().getZkStateReader());
}
@@ -665,7 +672,7 @@ public class CoreContainer {
metricsCollectorHandler.init(null);
containerHandlers.put(AUTHZ_PATH, securityConfHandler);
- securityConfHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, AUTHZ_PATH);
+ securityConfHandler.initializeMetrics(solrMetricsContext, AUTHZ_PATH);
containerHandlers.put(AUTHC_PATH, securityConfHandler);
@@ -680,22 +687,20 @@ public class CoreContainer {
// initialize gauges for reporting the number of cores and disk total/free
- String registryName = SolrMetricManager.getRegistryName(SolrInfoBean.Group.node);
- String metricTag = Integer.toHexString(hashCode());
- metricManager.registerGauge(null, registryName, () -> solrCores.getCores().size(),
- metricTag, true, "loaded", SolrInfoBean.Category.CONTAINER.toString(), "cores");
- metricManager.registerGauge(null, registryName, () -> solrCores.getLoadedCoreNames().size() - solrCores.getCores().size(),
- metricTag, true, "lazy", SolrInfoBean.Category.CONTAINER.toString(), "cores");
- metricManager.registerGauge(null, registryName, () -> solrCores.getAllCoreNames().size() - solrCores.getLoadedCoreNames().size(),
- metricTag, true, "unloaded", SolrInfoBean.Category.CONTAINER.toString(), "cores");
+ solrMetricsContext.gauge(null, () -> solrCores.getCores().size(),
+ true, "loaded", SolrInfoBean.Category.CONTAINER.toString(), "cores");
+ solrMetricsContext.gauge(null, () -> solrCores.getLoadedCoreNames().size() - solrCores.getCores().size(),
+ true, "lazy", SolrInfoBean.Category.CONTAINER.toString(), "cores");
+ solrMetricsContext.gauge(null, () -> solrCores.getAllCoreNames().size() - solrCores.getLoadedCoreNames().size(),
+ true, "unloaded", SolrInfoBean.Category.CONTAINER.toString(), "cores");
Path dataHome = cfg.getSolrDataHome() != null ? cfg.getSolrDataHome() : cfg.getCoreRootDirectory();
- metricManager.registerGauge(null, registryName, () -> dataHome.toFile().getTotalSpace(),
- metricTag, true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs");
- metricManager.registerGauge(null, registryName, () -> dataHome.toFile().getUsableSpace(),
- metricTag, true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs");
- metricManager.registerGauge(null, registryName, () -> dataHome.toAbsolutePath().toString(),
- metricTag, true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs");
- metricManager.registerGauge(null, registryName, () -> {
+ solrMetricsContext.gauge(null, () -> dataHome.toFile().getTotalSpace(),
+ true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs");
+ solrMetricsContext.gauge(null, () -> dataHome.toFile().getUsableSpace(),
+ true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs");
+ solrMetricsContext.gauge(null, () -> dataHome.toAbsolutePath().toString(),
+ true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs");
+ solrMetricsContext.gauge(null, () -> {
try {
return org.apache.lucene.util.IOUtils.spins(dataHome.toAbsolutePath());
} catch (IOException e) {
@@ -703,14 +708,14 @@ public class CoreContainer {
return true;
}
},
- metricTag, true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs");
- metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toFile().getTotalSpace(),
- metricTag, true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
- metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toFile().getUsableSpace(),
- metricTag, true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
- metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toAbsolutePath().toString(),
- metricTag, true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
- metricManager.registerGauge(null, registryName, () -> {
+ true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs");
+ solrMetricsContext.gauge(null, () -> cfg.getCoreRootDirectory().toFile().getTotalSpace(),
+ true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
+ solrMetricsContext.gauge(null, () -> cfg.getCoreRootDirectory().toFile().getUsableSpace(),
+ true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
+ solrMetricsContext.gauge(null, () -> cfg.getCoreRootDirectory().toAbsolutePath().toString(),
+ true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
+ solrMetricsContext.gauge(null, () -> {
try {
return org.apache.lucene.util.IOUtils.spins(cfg.getCoreRootDirectory().toAbsolutePath());
} catch (IOException e) {
@@ -718,15 +723,15 @@ public class CoreContainer {
return true;
}
},
- metricTag, true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
+ true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot");
// add version information
- metricManager.registerGauge(null, registryName, () -> this.getClass().getPackage().getSpecificationVersion(),
- metricTag, true, "specification", SolrInfoBean.Category.CONTAINER.toString(), "version");
- metricManager.registerGauge(null, registryName, () -> this.getClass().getPackage().getImplementationVersion(),
- metricTag, true, "implementation", SolrInfoBean.Category.CONTAINER.toString(), "version");
+ solrMetricsContext.gauge(null, () -> this.getClass().getPackage().getSpecificationVersion(),
+ true, "specification", SolrInfoBean.Category.CONTAINER.toString(), "version");
+ solrMetricsContext.gauge(null, () -> this.getClass().getPackage().getImplementationVersion(),
+ true, "implementation", SolrInfoBean.Category.CONTAINER.toString(), "version");
SolrFieldCacheBean fieldCacheBean = new SolrFieldCacheBean();
- fieldCacheBean.initializeMetrics(metricManager, registryName, metricTag, null);
+ fieldCacheBean.initializeMetrics(solrMetricsContext, null);
if (isZooKeeperAware()) {
metricManager.loadClusterReporters(metricReporters, this);
@@ -815,7 +820,7 @@ public class CoreContainer {
// initialize this handler here when SolrCloudManager is ready
autoScalingHandler = new AutoScalingHandler(getZkController().getSolrCloudManager(), loader);
containerHandlers.put(AutoScalingHandler.HANDLER_PATH, autoScalingHandler);
- autoScalingHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, AutoScalingHandler.HANDLER_PATH);
+ autoScalingHandler.initializeMetrics(solrMetricsContext, AutoScalingHandler.HANDLER_PATH);
}
// This is a bit redundant but these are two distinct concepts for all they're accomplished at the same time.
status |= LOAD_COMPLETE | INITIAL_CORE_LOAD_COMPLETE;
@@ -863,7 +868,7 @@ public class CoreContainer {
metricsHistoryHandler = new MetricsHistoryHandler(name, metricsHandler,
client, cloudManager, initArgs);
containerHandlers.put(METRICS_HISTORY_PATH, metricsHistoryHandler);
- metricsHistoryHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, METRICS_HISTORY_PATH);
+ metricsHistoryHandler.initializeMetrics(solrMetricsContext, METRICS_HISTORY_PATH);
}
public void securityNodeChanged() {
@@ -1796,7 +1801,9 @@ public class CoreContainer {
containerHandlers.put(path, (SolrRequestHandler) handler);
}
if (handler instanceof SolrMetricProducer) {
- ((SolrMetricProducer) handler).initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, path);
+ // use deprecated method for back-compat, remove in 9.0
+ ((SolrMetricProducer) handler).initializeMetrics(solrMetricsContext.metricManager,
+ solrMetricsContext.registry, solrMetricsContext.tag, path);
}
return handler;
}
diff --git a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
index 464b030..942f429 100644
--- a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
+++ b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
@@ -53,8 +53,8 @@ import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.IOUtils;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.store.blockcache.BlockCache;
import org.apache.solr.store.blockcache.BlockDirectory;
import org.apache.solr.store.blockcache.BlockDirectoryCache;
@@ -141,6 +141,13 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol
}
tmpFsCache.invalidateAll();
tmpFsCache.cleanUp();
+ try {
+ SolrMetricProducer.super.close();
+ MetricsHolder.metrics.close();
+ LocalityHolder.reporter.close();
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
}
private final static class LocalityHolder {
@@ -497,9 +504,9 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- MetricsHolder.metrics.initializeMetrics(manager, registry, tag, scope);
- LocalityHolder.reporter.initializeMetrics(manager, registry, tag, scope);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ MetricsHolder.metrics.initializeMetrics(parentContext, scope);
+ LocalityHolder.reporter.initializeMetrics(parentContext, scope);
}
@Override
diff --git a/solr/core/src/java/org/apache/solr/core/PluginBag.java b/solr/core/src/java/org/apache/solr/core/PluginBag.java
index 6088f52..fa2c3e3 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginBag.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginBag.java
@@ -195,7 +195,7 @@ public class PluginBag<T> implements AutoCloseable {
return old == null ? null : old.get();
}
- PluginHolder<T> put(String name, PluginHolder<T> plugin) {
+ public PluginHolder<T> put(String name, PluginHolder<T> plugin) {
Boolean registerApi = null;
Boolean disableHandler = null;
if (plugin.pluginInfo != null) {
@@ -231,11 +231,15 @@ public class PluginBag<T> implements AutoCloseable {
apiBag.registerLazy((PluginHolder<SolrRequestHandler>) plugin, plugin.pluginInfo);
}
}
- if(disableHandler == null) disableHandler = Boolean.FALSE;
+ if (disableHandler == null) disableHandler = Boolean.FALSE;
PluginHolder<T> old = null;
- if(!disableHandler) old = registry.put(name, plugin);
+ if (!disableHandler) old = registry.put(name, plugin);
if (plugin.pluginInfo != null && plugin.pluginInfo.isDefault()) setDefault(name);
if (plugin.isLoaded()) registerMBean(plugin.get(), core, name);
+ // old instance has been replaced - close it to prevent mem leaks
+ if (old != null && old != plugin) {
+ closeQuietly(old);
+ }
return old;
}
@@ -324,6 +328,14 @@ public class PluginBag<T> implements AutoCloseable {
}
}
+ public static void closeQuietly(Object inst) {
+ try {
+ if (inst != null && inst instanceof AutoCloseable) ((AutoCloseable) inst).close();
+ } catch (Exception e) {
+ log.error("Error closing "+ inst , e);
+ }
+ }
+
/**
* An indirect reference to a plugin. It just wraps a plugin instance.
* subclasses may choose to lazily load the plugin
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 fca1823..aff53a3 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -108,8 +108,8 @@ import org.apache.solr.handler.component.HighlightComponent;
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.logging.MDCLoggingContext;
import org.apache.solr.metrics.SolrCoreMetricManager;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.BinaryResponseWriter;
@@ -231,7 +231,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
private final CoreContainer coreContainer;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private String metricTag = Integer.toHexString(hashCode());
+ private final String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null);
+ private final SolrMetricsContext solrMetricsContext;
public volatile boolean searchEnabled = true;
public volatile boolean indexEnabled = true;
@@ -919,6 +920,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
this.configSetProperties = configSetProperties;
// Initialize the metrics manager
this.coreMetricManager = initCoreMetricManager(config);
+ solrMetricsContext = coreMetricManager.getSolrMetricsContext();
this.coreMetricManager.loadReporters();
if (updateHandler == null) {
@@ -940,15 +942,13 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
checkVersionFieldExistsInSchema(schema, coreDescriptor);
- SolrMetricManager metricManager = coreContainer.getMetricManager();
-
// initialize searcher-related metrics
- initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, null);
+ initializeMetrics(solrMetricsContext, null);
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(), metricTag, "core");
+ solrFieldCacheBean.initializeMetrics(solrMetricsContext, "core");
infoRegistry.put("fieldCache", solrFieldCacheBean);
initSchema(config, schema);
@@ -1015,8 +1015,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
// Allow the directory factory to report metrics
if (directoryFactory instanceof SolrMetricProducer) {
- ((SolrMetricProducer) directoryFactory).initializeMetrics(metricManager, coreMetricManager.getRegistryName(),
- metricTag, "directoryFactory");
+ // XXX use deprecated method for back-compat, remove in 9.0
+ ((SolrMetricProducer) directoryFactory).initializeMetrics(
+ solrMetricsContext.metricManager, solrMetricsContext.registry, solrMetricsContext.tag, "directoryFactory");
}
// seed version buckets with max from index during core initialization ... requires a searcher!
@@ -1163,61 +1164,66 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- newSearcherCounter = manager.counter(this, registry, "new", Category.SEARCHER.toString());
- newSearcherTimer = manager.timer(this, registry, "time", Category.SEARCHER.toString(), "new");
- newSearcherWarmupTimer = manager.timer(this, registry, "warmup", Category.SEARCHER.toString(), "new");
- newSearcherMaxReachedCounter = manager.counter(this, registry, "maxReached", Category.SEARCHER.toString(), "new");
- newSearcherOtherErrorsCounter = manager.counter(this, registry, "errors", Category.SEARCHER.toString(), "new");
-
- manager.registerGauge(this, registry, () -> name == null ? "(null)" : name, getMetricTag(), true, "coreName", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> startTime, getMetricTag(), true, "startTime", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> getOpenCount(), getMetricTag(), true, "refCount", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> resourceLoader.getInstancePath().toString(), getMetricTag(), true, "instanceDir", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> isClosed() ? "(closed)" : getIndexDir(), getMetricTag(), true, "indexDir", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> isClosed() ? 0 : getIndexSize(), getMetricTag(), true, "sizeInBytes", Category.INDEX.toString());
- manager.registerGauge(this, registry, () -> isClosed() ? "(closed)" : NumberUtils.readableSize(getIndexSize()), getMetricTag(), true, "size", Category.INDEX.toString());
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ newSearcherCounter = parentContext.counter(this, "new", Category.SEARCHER.toString());
+ newSearcherTimer = parentContext.timer(this, "time", Category.SEARCHER.toString(), "new");
+ newSearcherWarmupTimer = parentContext.timer(this, "warmup", Category.SEARCHER.toString(), "new");
+ newSearcherMaxReachedCounter = parentContext.counter(this, "maxReached", Category.SEARCHER.toString(), "new");
+ newSearcherOtherErrorsCounter = parentContext.counter(this, "errors", Category.SEARCHER.toString(), "new");
+
+ parentContext.gauge(this, () -> name == null ? "(null)" : name, true, "coreName", Category.CORE.toString());
+ parentContext.gauge(this, () -> startTime, true, "startTime", Category.CORE.toString());
+ parentContext.gauge(this, () -> getOpenCount(), true, "refCount", Category.CORE.toString());
+ parentContext.gauge(this, () -> resourceLoader.getInstancePath().toString(), true, "instanceDir", Category.CORE.toString());
+ parentContext.gauge(this, () -> isClosed() ? "(closed)" : getIndexDir(), true, "indexDir", Category.CORE.toString());
+ parentContext.gauge(this, () -> isClosed() ? 0 : getIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
+ parentContext.gauge(this, () -> isClosed() ? "(closed)" : NumberUtils.readableSize(getIndexSize()), true, "size", Category.INDEX.toString());
if (coreContainer != null) {
- manager.registerGauge(this, registry, () -> coreContainer.getNamesForCore(this), getMetricTag(), true, "aliases", Category.CORE.toString());
+ parentContext.gauge(this, () -> coreContainer.getNamesForCore(this), true, "aliases", Category.CORE.toString());
final CloudDescriptor cd = getCoreDescriptor().getCloudDescriptor();
if (cd != null) {
- manager.registerGauge(this, registry, () -> {
+ parentContext.gauge(this, () -> {
if (cd.getCollectionName() != null) {
return cd.getCollectionName();
} else {
return "_notset_";
}
- }, getMetricTag(), true, "collection", Category.CORE.toString());
+ }, true, "collection", Category.CORE.toString());
- manager.registerGauge(this, registry, () -> {
+ parentContext.gauge(this, () -> {
if (cd.getShardId() != null) {
return cd.getShardId();
} else {
return "_auto_";
}
- }, getMetricTag(), true, "shard", Category.CORE.toString());
+ }, true, "shard", Category.CORE.toString());
}
}
// initialize disk total / free metrics
Path dataDirPath = Paths.get(dataDir);
File dataDirFile = dataDirPath.toFile();
- manager.registerGauge(this, registry, () -> dataDirFile.getTotalSpace(), getMetricTag(), true, "totalSpace", Category.CORE.toString(), "fs");
- manager.registerGauge(this, registry, () -> dataDirFile.getUsableSpace(), getMetricTag(), true, "usableSpace", Category.CORE.toString(), "fs");
- manager.registerGauge(this, registry, () -> dataDirPath.toAbsolutePath().toString(), getMetricTag(), true, "path", Category.CORE.toString(), "fs");
- manager.registerGauge(this, registry, () -> {
+ parentContext.gauge(this, () -> dataDirFile.getTotalSpace(), true, "totalSpace", Category.CORE.toString(), "fs");
+ parentContext.gauge(this, () -> dataDirFile.getUsableSpace(), true, "usableSpace", Category.CORE.toString(), "fs");
+ parentContext.gauge(this, () -> dataDirPath.toAbsolutePath().toString(), true, "path", Category.CORE.toString(), "fs");
+ parentContext.gauge(this, () -> {
try {
return org.apache.lucene.util.IOUtils.spins(dataDirPath.toAbsolutePath());
} catch (IOException e) {
// default to spinning
return true;
}
- }, getMetricTag(), true, "spins", Category.CORE.toString(), "fs");
+ }, true, "spins", Category.CORE.toString(), "fs");
}
public String getMetricTag() {
return metricTag;
}
+ @Override
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
private void checkVersionFieldExistsInSchema(IndexSchema schema, CoreDescriptor coreDescriptor) {
if (null != coreDescriptor.getCloudDescriptor()) {
// we are evidently running in cloud mode.
diff --git a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
index bfb3428..dc0f599 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
@@ -21,6 +21,8 @@ import java.util.Set;
import com.codahale.metrics.MetricRegistry;
import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.util.stats.MetricUtils;
/**
@@ -77,6 +79,10 @@ public interface SolrInfoBean {
* (default is null, which means no registry).
*/
default MetricRegistry getMetricRegistry() {
+ if (this instanceof SolrMetricProducer) {
+ SolrMetricsContext context = ((SolrMetricProducer)this).getSolrMetricsContext();
+ return context != null ? context.getMetricRegistry() : null;
+ }
return null;
}
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index 9843240..436cd74 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -93,7 +93,7 @@ import org.apache.solr.core.backup.repository.BackupRepository;
import org.apache.solr.core.backup.repository.LocalFileSystemRepository;
import org.apache.solr.handler.IndexFetcher.IndexFetchResult;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.SolrIndexSearcher;
@@ -865,21 +865,20 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- super.initializeMetrics(manager, registry, tag, scope);
-
- manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? NumberUtils.readableSize(core.getIndexSize()) : ""),
- tag, true, "indexSize", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? getIndexVersion().toString() : ""),
- tag, true, "indexVersion", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? getIndexVersion().generation : 0),
- tag, true, GENERATION, getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? core.getIndexDir() : ""),
- tag, true, "indexPath", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> isMaster,
- tag, true, "isMaster", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> isSlave,
- tag, true, "isSlave", getCategory().toString(), scope);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ super.initializeMetrics(parentContext, scope);
+ solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? NumberUtils.readableSize(core.getIndexSize()) : ""),
+ true, "indexSize", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? getIndexVersion().toString() : ""),
+ true, "indexVersion", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? getIndexVersion().generation : 0),
+ true, GENERATION, getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? core.getIndexDir() : ""),
+ true, "indexPath", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> isMaster,
+ true, "isMaster", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> isSlave,
+ true, "isSlave", getCategory().toString(), scope);
final MetricsMap fetcherMap = new MetricsMap((detailed, map) -> {
IndexFetcher fetcher = currentIndexFetcher;
if (fetcher != null) {
@@ -908,13 +907,13 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
addVal(map, IndexFetcher.CONF_FILES_REPLICATED, props, String.class);
}
});
- manager.registerGauge(this, registry, fetcherMap, tag, true, "fetcher", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> isMaster && includeConfFiles != null ? includeConfFiles : "",
- tag, true, "confFilesToReplicate", getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> isMaster ? getReplicateAfterStrings() : Collections.<String>emptyList(),
- tag, true, REPLICATE_AFTER, getCategory().toString(), scope);
- manager.registerGauge(this, registry, () -> isMaster && replicationEnabled.get(),
- tag, true, "replicationEnabled", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this , fetcherMap, true, "fetcher", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> isMaster && includeConfFiles != null ? includeConfFiles : "",
+ true, "confFilesToReplicate", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> isMaster ? getReplicateAfterStrings() : Collections.<String>emptyList(),
+ true, REPLICATE_AFTER, getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> isMaster && replicationEnabled.get(),
+ true, "replicationEnabled", getCategory().toString(), scope);
}
//TODO Should a failure retrieving any piece of info mark the overall request as a failure? Is there a core set of values that are required to make a response here useful?
@@ -1394,7 +1393,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
});
}
- public void close() {
+ public void shutdown() {
if (executorService != null) executorService.shutdown();
if (pollingIndexFetcher != null) {
pollingIndexFetcher.destroy();
diff --git a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
index eca391b..4d9e96b 100644
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@ -22,11 +22,13 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import com.codahale.metrics.MetricRegistry;
-import com.google.common.collect.ImmutableList;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
+import com.google.common.collect.ImmutableList;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.api.ApiSupport;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
@@ -36,16 +38,13 @@ import org.apache.solr.core.PluginBag;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.util.SolrPluginUtils;
-import org.apache.solr.api.Api;
-import org.apache.solr.api.ApiBag;
-import org.apache.solr.api.ApiSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,9 +78,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
private PluginInfo pluginInfo;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
- protected String registryName;
- protected SolrMetricManager metricManager;
+ protected SolrMetricsContext solrMetricsContext;
@SuppressForbidden(reason = "Need currentTimeMillis, used only for stats output")
@@ -144,21 +141,24 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, final String scope) {
- this.metricManager = manager;
- this.registryName = registryName;
- this.registry = manager.registry(registryName);
- numErrors = manager.meter(this, registryName, "errors", getCategory().toString(), scope);
- numServerErrors = manager.meter(this, registryName, "serverErrors", getCategory().toString(), scope);
- numClientErrors = manager.meter(this, registryName, "clientErrors", getCategory().toString(), scope);
- numTimeouts = manager.meter(this, registryName, "timeouts", getCategory().toString(), scope);
- requests = manager.counter(this, registryName, "requests", getCategory().toString(), scope);
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext.getChildContext(this);
+ numErrors = solrMetricsContext.meter(this, "errors", getCategory().toString(), scope);
+ numServerErrors = solrMetricsContext.meter(this, "serverErrors", getCategory().toString(), scope);
+ numClientErrors = solrMetricsContext.meter(this, "clientErrors", getCategory().toString(), scope);
+ numTimeouts = solrMetricsContext.meter(this, "timeouts", getCategory().toString(), scope);
+ requests = solrMetricsContext.counter(this, "requests", getCategory().toString(), scope);
MetricsMap metricsMap = new MetricsMap((detail, map) ->
shardPurposes.forEach((k, v) -> map.put(k, v.getCount())));
- manager.registerGauge(this, registryName, metricsMap, tag, true, "shardRequests", getCategory().toString(), scope);
- requestTimes = manager.timer(this, registryName, "requestTimes", getCategory().toString(), scope);
- totalTime = manager.counter(this, registryName, "totalTime", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> handlerStart, tag, true, "handlerStart", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, metricsMap, true, "shardRequests", getCategory().toString(), scope);
+ requestTimes = solrMetricsContext.timer(this,"requestTimes", getCategory().toString(), scope);
+ totalTime = solrMetricsContext.counter(this, "totalTime", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> handlerStart, true, "handlerStart", getCategory().toString(), scope);
}
public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) {
@@ -273,11 +273,6 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
-
- @Override
public SolrRequestHandler getSubHandler(String subPath) {
return null;
}
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
index cd6cd38..589a1ca 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
@@ -46,6 +46,7 @@ import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.logging.MDCLoggingContext;
import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.AuthorizationContext;
@@ -120,10 +121,10 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- super.initializeMetrics(manager, registryName, tag, scope);
- parallelExecutor = MetricUtils.instrumentedExecutorService(parallelExecutor, this, manager.registry(registryName),
- SolrMetricManager.mkName("parallelCoreAdminExecutor", getCategory().name(),scope, "threadPool"));
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ super.initializeMetrics(parentContext, scope);
+ parallelExecutor = MetricUtils.instrumentedExecutorService(parallelExecutor, this, solrMetricsContext.getMetricRegistry(),
+ SolrMetricManager.mkName("parallelCoreAdminExecutor", getCategory().name(), scope, "threadPool"));
}
@Override
public Boolean registerV2() {
diff --git a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
index 2d6fdb1..d70cf99 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java
@@ -48,8 +48,8 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrEventListener;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.spelling.suggest.SolrSuggester;
import org.apache.solr.spelling.suggest.SuggesterOptions;
@@ -88,9 +88,8 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
@SuppressWarnings("unchecked")
protected NamedList initParams;
- protected SolrMetricManager metricManager;
- protected String registryName;
-
+ protected SolrMetricsContext metricsContext;
+
/**
* Key is the dictionary name used in SolrConfig, value is the corresponding {@link SolrSuggester}
*/
@@ -351,18 +350,22 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- this.registryName = registryName;
- this.metricManager = manager;
- registry = manager.registry(registryName);
- manager.registerGauge(this, registryName, () -> ramBytesUsed(), tag, true, "totalSizeInBytes", getCategory().toString(), scope);
+ public SolrMetricsContext getSolrMetricsContext() {
+ return metricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.metricsContext = parentContext.getChildContext(this);
+
+ this.metricsContext.gauge(this, () -> ramBytesUsed(), true, "totalSizeInBytes", getCategory().toString());
MetricsMap suggestersMap = new MetricsMap((detailed, map) -> {
for (Map.Entry<String, SolrSuggester> entry : suggesters.entrySet()) {
SolrSuggester suggester = entry.getValue();
map.put(entry.getKey(), suggester.toString());
}
});
- manager.registerGauge(this, registryName, suggestersMap, tag, true, "suggesters", getCategory().toString(), scope);
+ this.metricsContext.gauge(this, suggestersMap, true, "suggesters", getCategory().toString(), scope);
}
@Override
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 c57a704..c318b8c 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java
@@ -40,9 +40,8 @@ public class SolrCoreMetricManager implements Closeable {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final SolrCore core;
- private final String tag;
- private final SolrMetricManager metricManager;
- private String registryName;
+ private SolrMetricsContext solrMetricsContext;
+ private SolrMetricManager metricManager;
private String collectionName;
private String shardName;
private String replicaName;
@@ -56,10 +55,10 @@ public class SolrCoreMetricManager implements Closeable {
*/
public SolrCoreMetricManager(SolrCore core) {
this.core = core;
- this.tag = core.getMetricTag();
- this.metricManager = core.getCoreContainer().getMetricManager();
initCloudMode();
- registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
+ metricManager = core.getCoreContainer().getMetricManager();
+ String registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
+ solrMetricsContext = new SolrMetricsContext(metricManager, registryName, core.getMetricTag());
leaderRegistryName = createLeaderRegistryName(cloudMode, collectionName, shardName);
}
@@ -86,8 +85,8 @@ public class SolrCoreMetricManager implements Closeable {
CoreContainer coreContainer = core.getCoreContainer();
NodeConfig nodeConfig = coreContainer.getConfig();
PluginInfo[] pluginInfos = nodeConfig.getMetricsConfig().getMetricReporters();
- metricManager.loadReporters(pluginInfos, core.getResourceLoader(), coreContainer, core, tag,
- SolrInfoBean.Group.core, registryName);
+ metricManager.loadReporters(pluginInfos, core.getResourceLoader(), coreContainer, core, solrMetricsContext.tag,
+ SolrInfoBean.Group.core, solrMetricsContext.registry);
if (cloudMode) {
metricManager.loadShardReporters(pluginInfos, core);
}
@@ -99,19 +98,20 @@ public class SolrCoreMetricManager implements Closeable {
* This method also reloads reporters so that they use the new core name.
*/
public void afterCoreSetName() {
- String oldRegistryName = registryName;
+ String oldRegistryName = solrMetricsContext.registry;
String oldLeaderRegistryName = leaderRegistryName;
initCloudMode();
- registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
+ String newRegistryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName());
leaderRegistryName = createLeaderRegistryName(cloudMode, collectionName, shardName);
- if (oldRegistryName.equals(registryName)) {
+ if (oldRegistryName.equals(newRegistryName)) {
return;
}
// close old reporters
- metricManager.closeReporters(oldRegistryName, tag);
+ metricManager.closeReporters(oldRegistryName, solrMetricsContext.tag);
if (oldLeaderRegistryName != null) {
- metricManager.closeReporters(oldLeaderRegistryName, tag);
+ metricManager.closeReporters(oldLeaderRegistryName, solrMetricsContext.tag);
}
+ solrMetricsContext = new SolrMetricsContext(metricManager, newRegistryName, solrMetricsContext.tag);
// load reporters again, using the new core name
loadReporters();
}
@@ -127,15 +127,16 @@ public class SolrCoreMetricManager implements Closeable {
throw new IllegalArgumentException("registerMetricProducer() called with illegal arguments: " +
"scope = " + scope + ", producer = " + producer);
}
- producer.initializeMetrics(metricManager, getRegistryName(), tag, scope);
+ // use deprecated method for back-compat, remove in 9.0
+ producer.initializeMetrics(solrMetricsContext.metricManager, solrMetricsContext.registry, solrMetricsContext.tag, scope);
}
/**
* Return the registry used by this SolrCore.
*/
public MetricRegistry getRegistry() {
- if (registryName != null) {
- return metricManager.registry(registryName);
+ if (solrMetricsContext != null) {
+ return solrMetricsContext.getMetricRegistry();
} else {
return null;
}
@@ -146,11 +147,15 @@ public class SolrCoreMetricManager implements Closeable {
*/
@Override
public void close() throws IOException {
- metricManager.closeReporters(getRegistryName(), tag);
+ metricManager.closeReporters(solrMetricsContext.registry, solrMetricsContext.tag);
if (getLeaderRegistryName() != null) {
- metricManager.closeReporters(getLeaderRegistryName(), tag);
+ metricManager.closeReporters(getLeaderRegistryName(), solrMetricsContext.tag);
}
- metricManager.unregisterGauges(getRegistryName(), tag);
+ metricManager.unregisterGauges(solrMetricsContext.registry, solrMetricsContext.tag);
+ }
+
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
public SolrCore getCore() {
@@ -175,7 +180,7 @@ public class SolrCoreMetricManager implements Closeable {
* @return the metric registry name of the manager.
*/
public String getRegistryName() {
- return registryName;
+ return solrMetricsContext != null ? solrMetricsContext.registry : null;
}
/**
@@ -190,7 +195,7 @@ public class SolrCoreMetricManager implements Closeable {
* Return a tag specific to this instance.
*/
public String getTag() {
- return tag;
+ return solrMetricsContext.tag;
}
public static String createRegistryName(boolean cloud, String collectionName, String shardName, String replicaName, String coreName) {
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 7d2877d..977b0ca 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -724,20 +724,24 @@ public class SolrMetricManager {
registerMetric(info, registry, new GaugeWrapper(gauge, tag), force, metricName, metricPath);
}
- public int unregisterGauges(String registryName, String tag) {
- if (tag == null) {
+ public int unregisterGauges(String registryName, String tagSegment) {
+ if (tagSegment == null) {
return 0;
}
MetricRegistry registry = registry(registryName);
+ if (registry == null) return 0;
AtomicInteger removed = new AtomicInteger();
registry.removeMatching((name, metric) -> {
- if (metric instanceof GaugeWrapper &&
- tag.equals(((GaugeWrapper) metric).getTag())) {
- removed.incrementAndGet();
- return true;
- } else {
- return false;
+ if (metric instanceof GaugeWrapper) {
+ GaugeWrapper wrapper = (GaugeWrapper) metric;
+ boolean toRemove = wrapper.getTag().contains(tagSegment);
+ if (toRemove) {
+ removed.incrementAndGet();
+ }
+ return toRemove;
}
+ return false;
+
});
return removed.get();
}
@@ -752,10 +756,16 @@ public class SolrMetricManager {
* segments prepended to the name.
*/
public static String mkName(String name, String... path) {
+ return makeName(path == null || path.length == 0 ? Collections.emptyList() : Arrays.asList(path),
+ name);
+
+ }
+
+ public static String makeName(List<String> path, String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("name must not be empty");
}
- if (path == null || path.length == 0) {
+ if (path == null || path.size() == 0) {
return name;
} else {
StringBuilder sb = new StringBuilder();
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
index 265d7e4..29c14ce 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
@@ -19,17 +19,83 @@ package org.apache.solr.metrics;
/**
* Used by objects that expose metrics through {@link SolrMetricManager}.
*/
-public interface SolrMetricProducer {
+public interface SolrMetricProducer extends AutoCloseable {
+
+ /**
+ * Unique metric tag identifies components with the same life-cycle, which should
+ * be registered / unregistered together. It is in the format of A:B:C, where
+ * A is the parent of B is the parent of C and so on.
+ * If object "B" is unregistered C also must get unregistered.
+ * If object "A" is unregistered B and C also must get unregistered.
+ * @param o object to create a tag for
+ * @param parentName parent object name, or null if no parent exists
+ */
+ static String getUniqueMetricTag(Object o, String parentName) {
+ String name = o.getClass().getSimpleName() + "@" + Integer.toHexString(o.hashCode());
+ if (parentName != null && parentName.contains(name)) {
+ throw new RuntimeException("Parent already includes this component! parent=" + parentName + ", this=" + name);
+ }
+ return parentName == null ?
+ name :
+ parentName + ":" + name;
+ }
/**
* Initializes metrics specific to this producer
- * @param manager an instance of {@link SolrMetricManager}
+ *
+ * @param manager an instance of {@link SolrMetricManager}
* @param registry registry name where metrics are registered
- * @param tag a symbolic tag that represents this instance of the producer,
- * or a group of related instances that have the same life-cycle. This tag is
- * used when managing life-cycle of some metrics and is set when
- * {@link #initializeMetrics(SolrMetricManager, String, String, String)} is called.
- * @param scope scope of the metrics (eg. handler name) to separate metrics of
+ * @param tag a symbolic tag that represents this instance of the producer,
+ * or a group of related instances that have the same life-cycle. This tag is
+ * used when managing life-cycle of some metrics.
+ * @param scope scope of the metrics (eg. handler name) to separate metrics of components with
+ * the same implementation but different scope.
+ * @deprecated use {@link #initializeMetrics(SolrMetricsContext, String)} instead
+ */
+ @Deprecated
+ default void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
+ initializeMetrics(new SolrMetricsContext(manager, registry, tag), scope);
+
+ }
+
+ /**
+ * Initialize metrics specific to this producer.
+ * @param parentContext parent metrics context. If this component has the same life-cycle as the parent
+ * it can simply use the parent context, otherwise it should obtain a child context
+ * using {@link SolrMetricsContext#getChildContext(Object)} passing <code>this</code>
+ * as the child.
+ * @param scope component scope
+ */
+ default void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ throw new RuntimeException("In class " + getClass().getName() +
+ " you must implement either initializeMetrics(SolrMetricsContext, String) or " +
+ "initializeMetrics(SolrMetricManager, String, String, String)");
+
+ }
+
+ /**
+ * Implementing classes should override this method to provide the context obtained in
+ * {@link #initializeMetrics(SolrMetricsContext, String)} to ensure proper cleanup of metrics
+ * at the end of the life-cycle of this component.
+ */
+ default SolrMetricsContext getSolrMetricsContext() {
+ return null;
+ }
+
+ /**
+ * Implementations should always call <code>SolrMetricProducer.super.close()</code> to ensure that
+ * metrics with the same life-cycle as this component are properly unregistered. This prevents
+ * obscure memory leaks.
*/
- void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope);
+ @Override
+ default void close() throws Exception {
+ SolrMetricsContext context = getSolrMetricsContext();
+ if (context == null) {
+ return;
+ } else {
+ context.unregister();
+ }
+ // ??? (ab) no idea what this was supposed to avoid
+ //if (info == null || info.tag.indexOf(':') == -1) return;//this will end up unregistering the root itself
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
new file mode 100644
index 0000000..dd37e1f
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.metrics;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+import org.apache.solr.core.SolrInfoBean;
+
+/**
+ * This class represents a metrics context that ties together components with the same life-cycle
+ * and provides convenient access to the metric registry.
+ */
+public class SolrMetricsContext {
+ public final String registry;
+ public final SolrMetricManager metricManager;
+ public final String tag;
+
+ public SolrMetricsContext(SolrMetricManager metricManager, String registry, String tag) {
+ this.registry = registry;
+ this.metricManager = metricManager;
+ this.tag = tag;
+ }
+
+ /**
+ * Metrics tag that represents objects with the same life-cycle.
+ */
+ public String getTag() {
+ return tag;
+ }
+
+ /**
+ * Unregister all {@link Gauge} metrics that use this context's tag.
+ *
+ * <p><b>NOTE: This method MUST be called at the end of a life-cycle (typically in <code>close()</code>)
+ * of components that register gauge metrics with references to the current object's instance. Failure to
+ * do so may result in hard-to-debug memory leaks.</b></p>
+ */
+ public void unregister() {
+ metricManager.unregisterGauges(registry, tag);
+ }
+
+ /**
+ * Get a context with the same registry name but a tag that represents a parent-child relationship.
+ * Since it's a different tag than the parent's context it is assumed that the life-cycle of the parent
+ * and child are different.
+ * @param child child object that produces metrics with a different life-cycle than the parent.
+ */
+ public SolrMetricsContext getChildContext(Object child) {
+ SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registry, SolrMetricProducer.getUniqueMetricTag(child, tag));
+ return childContext;
+ }
+
+ /**
+ * Convenience method for {@link SolrMetricManager#meter(SolrInfoBean, String, String, String...)}.
+ */
+ public Meter meter(SolrInfoBean info, String metricName, String... metricPath) {
+ return metricManager.meter(info, registry, metricName, metricPath);
+ }
+
+ /**
+ * Convenience method for {@link SolrMetricManager#counter(SolrInfoBean, String, String, String...)}.
+ */
+ public Counter counter(SolrInfoBean info, String metricName, String... metricPath) {
+ return metricManager.counter(info, registry, metricName, metricPath);
+
+ }
+
+ /**
+ * Convenience method for {@link SolrMetricManager#registerGauge(SolrInfoBean, String, Gauge, String, boolean, String, String...)}.
+ */
+ public void gauge(SolrInfoBean info, Gauge<?> gauge, boolean force, String metricName, String... metricPath) {
+ metricManager.registerGauge(info, registry, gauge, tag, force, metricName, metricPath);
+ }
+
+ /**
+ * Convenience method for {@link SolrMetricManager#meter(SolrInfoBean, String, String, String...)}.
+ */
+ public Timer timer(SolrInfoBean info, String metricName, String... metricPath) {
+ return metricManager.timer(info, registry, metricName, metricPath);
+ }
+
+ /**
+ * Convenience method for {@link SolrMetricManager#histogram(SolrInfoBean, String, String, String...)}.
+ */
+ public Histogram histogram(SolrInfoBean info, String metricName, String... metricPath) {
+ return metricManager.histogram(info, registry, metricName, metricPath);
+ }
+
+ /**
+ * Get the MetricRegistry instance that is used for registering metrics in this context.
+ */
+ public MetricRegistry getMetricRegistry() {
+ return metricManager.registry(registry);
+ }
+}
diff --git a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
index 71eb86f..f3c4c66 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -31,14 +31,13 @@ import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
-import com.codahale.metrics.MetricRegistry;
import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.RemovalListener;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.solr.common.SolrException;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -88,7 +87,7 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
private MetricsMap cacheMap;
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
private long initialRamBytes = 0;
private final LongAdder ramBytes = new LongAdder();
@@ -202,7 +201,8 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
}
@Override
- public void close() {
+ public void close() throws Exception {
+ SolrCache.super.close();
cache.invalidateAll();
cache.cleanUp();
if (executor instanceof ExecutorService) {
@@ -322,8 +322,8 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
@Override
@@ -337,8 +337,8 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
cacheMap = new MetricsMap((detailed, map) -> {
if (cache != null) {
CacheStats stats = cache.stats();
@@ -362,6 +362,6 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
map.put("cumulative_evictions", cumulativeStats.evictionCount());
}
});
- manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+ solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
}
}
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index 2dc1c1e..b74b63f 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -16,24 +16,23 @@
*/
package org.apache.solr.search;
-import com.codahale.metrics.MetricRegistry;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.solr.common.SolrException;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.util.ConcurrentLRUCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-
/**
* SolrCache based on ConcurrentLRUCache implementation.
* <p>
@@ -42,12 +41,11 @@ import java.util.concurrent.TimeUnit;
* <p>
* Also see <a href="http://wiki.apache.org/solr/SolrCaching">SolrCaching</a>
*
- *
* @see org.apache.solr.util.ConcurrentLRUCache
* @see org.apache.solr.search.SolrCache
* @since solr 1.4
*/
-public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>, Accountable {
+public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K, V>, Accountable {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(FastLRUCache.class);
@@ -61,7 +59,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
private long warmupTime = 0;
private String description = "Concurrent LRU Cache";
- private ConcurrentLRUCache<K,V> cache;
+ private ConcurrentLRUCache<K, V> cache;
private int showItems = 0;
private long maxRamBytes;
@@ -75,7 +73,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
private MetricsMap cacheMap;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
@Override
public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -117,7 +115,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
str = (String) args.get(MAX_RAM_MB_PARAM);
long maxRamMB = str == null ? -1 : (long) Double.parseDouble(str);
this.maxRamBytes = maxRamMB < 0 ? Long.MAX_VALUE : maxRamMB * 1024L * 1024L;
- if (maxRamBytes != Long.MAX_VALUE) {
+ if (maxRamBytes != Long.MAX_VALUE) {
ramLowerWatermark = Math.round(maxRamBytes * 0.8);
description = generateDescription(maxRamBytes, ramLowerWatermark, cleanupThread);
cache = new ConcurrentLRUCache<>(ramLowerWatermark, maxRamBytes, cleanupThread, null, maxIdleTimeSec);
@@ -213,7 +211,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
*/
protected String generateDescription(int limit, int initialSize, int minLimit, int acceptableLimit, boolean newThread) {
String description = "Concurrent LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize +
- ", minSize="+minLimit + ", acceptableSize="+acceptableLimit+", cleanupThread="+newThread;
+ ", minSize=" + minLimit + ", acceptableSize=" + acceptableLimit + ", cleanupThread=" + newThread;
if (isAutowarmingOn()) {
description += ", " + getAutowarmDescription();
}
@@ -274,10 +272,9 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
for (int i = itemsArr.length - 1; i >= 0; i--) {
try {
boolean continueRegen = regenerator.regenerateItem(searcher,
- this, old, itemsArr[i].getKey(), itemsArr[i].getValue());
+ this, old, itemsArr[i].getKey(), itemsArr[i].getValue());
if (!continueRegen) break;
- }
- catch (Exception e) {
+ } catch (Exception e) {
SolrException.log(log, "Error during auto-warming of key:" + itemsArr[i].getKey(), e);
}
}
@@ -287,7 +284,8 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
@Override
- public void close() {
+ public void close() throws Exception {
+ SolrCache.super.close();
// add the stats to the cumulative stats object (the first in the statsList)
statsList.get(0).add(cache.getStats());
statsList.remove(cache.getStats());
@@ -310,10 +308,16 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
return metricNames;
}
+
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
- manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext.getChildContext(this);
+ this.solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
}
// for unit tests only
@@ -322,11 +326,6 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K,V>,
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
-
- @Override
public String toString() {
return name() + (cacheMap != null ? cacheMap.getValue().toString() : "");
}
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 20cf664..125f08a 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -17,19 +17,18 @@
package org.apache.solr.search;
import java.lang.invoke.MethodHandles;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
-import com.codahale.metrics.MetricRegistry;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.solr.common.SolrException;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.util.ConcurrentLFUCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,7 +78,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
private int maxIdleTimeSec;
private MetricsMap cacheMap;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
+
private int maxSize;
private int minSizeLimit;
@@ -230,7 +230,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
@Override
- public void close() {
+ public void close() throws Exception {
+ SolrCache.super.close();
// add the stats to the cumulative stats object (the first in the statsList)
statsList.get(0).add(cache.getStats());
statsList.remove(cache.getStats());
@@ -263,8 +264,13 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
cacheMap = new MetricsMap((detailed, map) -> {
if (cache != null) {
ConcurrentLFUCache.Stats stats = cache.getStats();
@@ -330,7 +336,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
}
});
- manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+ solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
}
// for unit tests only
@@ -344,11 +350,6 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
-
- @Override
public String toString() {
return name + (cacheMap != null ? cacheMap.getValue().toString() : "");
}
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index c733c07..7a1b37c 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -18,22 +18,21 @@ package org.apache.solr.search;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
-import com.codahale.metrics.MetricRegistry;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Accountables;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.TimeSource;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,7 +76,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
private String description="LRU Cache";
private MetricsMap cacheMap;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
private int maxSize;
private int initialSize;
@@ -234,8 +233,8 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
}
/**
- *
- * @return Returns the description of this cache.
+ *
+ * @return Returns the description of this cache.
*/
private String generateDescription() {
String description = "LRU Cache(maxSize=" + getMaxSize() + ", initialSize=" + initialSize;
@@ -341,9 +340,9 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
// Don't do the autowarming in the synchronized block, just pull out the keys and values.
synchronized (other.map) {
-
+
int sz = autowarm.getWarmCount(other.map.size());
-
+
keys = new Object[sz];
vals = new Object[sz];
@@ -378,12 +377,6 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
warmupTime = TimeUnit.MILLISECONDS.convert(System.nanoTime() - warmingStartTime, TimeUnit.NANOSECONDS);
}
- @Override
- public void close() {
-
- }
-
-
//////////////////////// SolrInfoMBeans methods //////////////////////
@@ -403,8 +396,13 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
cacheMap = new MetricsMap((detailed, res) -> {
synchronized (map) {
res.put(LOOKUPS_PARAM, lookups);
@@ -433,7 +431,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
res.put("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue());
res.put("cumulative_evictionsIdleTime", stats.evictionsIdleTime.longValue());
});
- manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString());
+ solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
}
// for unit tests only
@@ -442,11 +440,6 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
-
- @Override
public String toString() {
return name() + (cacheMap != null ? cacheMap.getValue().toString() : "");
}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCache.java b/solr/core/src/java/org/apache/solr/search/SolrCache.java
index 4a16b39..55f57ec 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCache.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCache.java
@@ -137,7 +137,9 @@ public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer {
/** Frees any non-memory resources */
- public void close();
+ default void close() throws Exception {
+ SolrMetricProducer.super.close();
+ }
/** Returns maximum size limit (number of items) if set and supported, -1 otherwise. */
int getMaxSize();
diff --git a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
index 66b8ab1..7afe96d 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -22,8 +22,7 @@ import java.util.Map;
import java.util.Set;
import com.codahale.metrics.MetricRegistry;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,7 +76,7 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
return delegate;
}
- public void close() {
+ public void close() throws Exception {
delegate.close();
}
@@ -142,11 +141,8 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- log.debug("Going to register cachemetrics " + Utils.toJSONString(factory));
-
- delegate.initializeMetrics(manager, registry, tag,scope);
-
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ delegate.initializeMetrics(parentContext, scope);
}
}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
index b2647cd..b6deb7c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
@@ -19,11 +19,10 @@ package org.apache.solr.search;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import com.codahale.metrics.MetricRegistry;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.uninverting.UninvertingReader;
/**
@@ -35,7 +34,7 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer {
private boolean disableEntryList = Boolean.getBoolean("disableSolrFieldCacheMBeanEntryList");
private boolean disableJmxEntryList = Boolean.getBoolean("disableSolrFieldCacheMBeanEntryListJmx");
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
@Override
@@ -50,14 +49,15 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer {
public Set<String> getMetricNames() {
return metricNames;
}
+
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext;
MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
if (detailed && !disableEntryList && !disableJmxEntryList) {
UninvertingReader.FieldCacheStats fieldCacheStats = UninvertingReader.getUninvertedStats();
@@ -72,6 +72,6 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer {
map.put("entries_count", UninvertingReader.getUninvertedStatsSize());
}
});
- manager.registerGauge(this, registryName, metricsMap, tag, true, "fieldCache", Category.CACHE.toString(), scope);
+ solrMetricsContext.gauge(this, metricsMap, true, "fieldCache", Category.CACHE.toString(), scope);
}
}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 7d33a19..a831b45 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-import com.codahale.metrics.MetricRegistry;
import com.google.common.collect.Iterables;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
@@ -69,6 +68,7 @@ import org.apache.solr.index.SlowCompositeReaderWrapper;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
@@ -140,8 +140,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
private final StatsCache statsCache;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private SolrMetricManager metricManager;
- private String registryName;
+ private SolrMetricsContext solrMetricsContext;
private static DirectoryReader getReader(SolrCore core, SolrIndexConfig config, DirectoryFactory directoryFactory,
String path) throws IOException {
@@ -431,12 +430,13 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
cache.setState(SolrCache.State.LIVE);
infoRegistry.put(cache.name(), cache);
}
- metricManager = core.getCoreContainer().getMetricManager();
- registryName = core.getCoreMetricManager().getRegistryName();
+ this.solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
for (SolrCache cache : cacheList) {
- cache.initializeMetrics(metricManager, registryName, core.getMetricTag(), SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
+ // XXX use the deprecated method for back-compat. remove in 9.0
+ cache.initializeMetrics(solrMetricsContext.metricManager,
+ solrMetricsContext.registry, solrMetricsContext.tag, SolrMetricManager.mkName(cache.name(), STATISTICS_KEY));
}
- initializeMetrics(metricManager, registryName, core.getMetricTag(), STATISTICS_KEY);
+ initializeMetrics(solrMetricsContext, STATISTICS_KEY);
registerTime = new Date();
}
@@ -479,7 +479,11 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
}
for (SolrCache cache : cacheList) {
- cache.close();
+ try {
+ cache.close();
+ } catch (Exception e) {
+ SolrException.log(log, "Exception closing cache " + cache.name(), e);
+ }
}
if (releaseDirectory) {
@@ -2275,23 +2279,26 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- this.registryName = registry;
- this.metricManager = manager;
- manager.registerGauge(this, registry, () -> name, tag, true, "searcherName", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> cachingEnabled, tag, true, "caching", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> openTime, tag, true, "openedAt", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> warmupTime, tag, true, "warmupTime", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> registerTime, tag, true, "registeredAt", Category.SEARCHER.toString(), scope);
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ parentContext.gauge(this, () -> name, true, "searcherName", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> cachingEnabled, true, "caching", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> openTime, true, "openedAt", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> warmupTime, true, "warmupTime", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> registerTime, true, "registeredAt", Category.SEARCHER.toString(), scope);
// reader stats
- manager.registerGauge(this, registry, () -> reader.numDocs(), tag, true, "numDocs", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> reader.maxDoc(), tag, true, "maxDoc", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> reader.maxDoc() - reader.numDocs(), tag, true, "deletedDocs", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> reader.toString(), tag, true, "reader", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> reader.directory().toString(), tag, true, "readerDir", Category.SEARCHER.toString(), scope);
- manager.registerGauge(this, registry, () -> reader.getVersion(), tag, true, "indexVersion", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.numDocs(), true, "numDocs", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.maxDoc(), true, "maxDoc", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.maxDoc() - reader.numDocs(), true, "deletedDocs", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.toString(), true, "reader", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.directory().toString(), true, "readerDir", Category.SEARCHER.toString(), scope);
+ parentContext.gauge(this, () -> reader.getVersion(), true, "indexVersion", Category.SEARCHER.toString(), scope);
// size of the currently opened commit
- manager.registerGauge(this, registry, () -> {
+ parentContext.gauge(this, () -> {
try {
Collection<String> files = reader.getIndexCommit().getFileNames();
long total = 0;
@@ -2302,19 +2309,13 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
} catch (Exception e) {
return -1;
}
- }, tag, true, "indexCommitSize", Category.SEARCHER.toString(), scope);
+ }, true, "indexCommitSize", Category.SEARCHER.toString(), scope);
// statsCache metrics
- manager.registerGauge(this, registry,
+ parentContext.gauge(this,
new MetricsMap((detailed, map) -> {
statsCache.getCacheMetrics().getSnapshot(map::put);
map.put("statsCacheImpl", statsCache.getClass().getSimpleName());
- }),
- tag, true, "statsCache", Category.CACHE.toString(), scope);
- }
-
- @Override
- public MetricRegistry getMetricRegistry() {
- return core.getMetricRegistry();
+ }), true, "statsCache", Category.CACHE.toString(), scope);
}
private static class FilterImpl extends Filter {
diff --git a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
index a6c364a..d5ff666 100644
--- a/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuditLoggerPlugin.java
@@ -36,7 +36,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Meter;
-import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -45,8 +44,8 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.ExecutorUtil;
import org.apache.solr.common.util.SolrjNamedThreadFactory;
import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.security.AuditEvent.EventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -75,14 +74,12 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
int blockingQueueSize;
protected AuditEventFormatter formatter;
- private MetricRegistry registry;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
private ExecutorService executorService;
private boolean closed;
private MuteRules muteRules;
-
- protected String registryName;
- protected SolrMetricManager metricManager;
+
+ protected SolrMetricsContext solrMetricsContext;
protected Meter numErrors = new Meter();
protected Meter numLost = new Meter();
protected Meter numLogged = new Meter();
@@ -239,24 +236,21 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, final String scope) {
+ public void initializeMetrics(SolrMetricsContext parentContext, final String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
String className = this.getClass().getSimpleName();
log.debug("Initializing metrics for {}", className);
- this.metricManager = manager;
- this.registryName = registryName;
- // Metrics
- registry = manager.registry(registryName);
- numErrors = manager.meter(this, registryName, "errors", getCategory().toString(), scope, className);
- numLost = manager.meter(this, registryName, "lost", getCategory().toString(), scope, className);
- numLogged = manager.meter(this, registryName, "count", getCategory().toString(), scope, className);
- requestTimes = manager.timer(this, registryName, "requestTimes", getCategory().toString(), scope, className);
- totalTime = manager.counter(this, registryName, "totalTime", getCategory().toString(), scope, className);
+ numErrors = solrMetricsContext.meter(this, "errors", getCategory().toString(), scope, className);
+ numLost = solrMetricsContext.meter(this, "lost", getCategory().toString(), scope, className);
+ numLogged = solrMetricsContext.meter(this, "count", getCategory().toString(), scope, className);
+ requestTimes = solrMetricsContext.timer(this, "requestTimes", getCategory().toString(), scope, className);
+ totalTime = solrMetricsContext.counter(this, "totalTime", getCategory().toString(), scope, className);
if (async) {
- manager.registerGauge(this, registryName, () -> blockingQueueSize, "queueCapacity", true, "queueCapacity", getCategory().toString(), scope, className);
- manager.registerGauge(this, registryName, () -> blockingQueueSize - queue.remainingCapacity(), "queueSize", true, "queueSize", getCategory().toString(), scope, className);
- queuedTime = manager.timer(this, registryName, "queuedTime", getCategory().toString(), scope, className);
+ solrMetricsContext.gauge(this, () -> blockingQueueSize, true, "queueCapacity", getCategory().toString(), scope, className);
+ solrMetricsContext.gauge(this, () -> blockingQueueSize - queue.remainingCapacity(), true, "queueSize", getCategory().toString(), scope, className);
+ queuedTime = solrMetricsContext.timer(this, "queuedTime", getCategory().toString(), scope, className);
}
- manager.registerGauge(this, registryName, () -> async, "async", true, "async", getCategory().toString(), scope, className);
+ solrMetricsContext.gauge(this, () -> async, true, "async", getCategory().toString(), scope, className);
}
@Override
@@ -280,10 +274,10 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
-
+
/**
* Interface for formatting the event
*/
@@ -325,6 +319,11 @@ public abstract class AuditLoggerPlugin implements Closeable, Runnable, SolrInfo
closed = true;
log.info("Shutting down async Auditlogger background thread(s)");
executorService.shutdownNow();
+ try {
+ SolrMetricProducer.super.close();
+ } catch (Exception e) {
+ throw new IOException("Exception closing", e);
+ }
}
}
diff --git a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
index 5fd18a1..320f661 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
@@ -19,39 +19,33 @@ package org.apache.solr.security;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import java.io.Closeable;
-import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Meter;
-import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
-import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricProducer;
-
import org.apache.http.HttpRequest;
import org.apache.http.protocol.HttpContext;
+import org.apache.solr.core.SolrInfoBean;
+import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.eclipse.jetty.client.api.Request;
/**
*
* @lucene.experimental
*/
-public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, SolrMetricProducer {
+public abstract class AuthenticationPlugin implements SolrInfoBean, SolrMetricProducer {
final public static String AUTHENTICATION_PLUGIN_PROP = "authenticationPlugin";
final public static String HTTP_HEADER_X_SOLR_AUTHDATA = "X-Solr-AuthData";
// Metrics
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
+ protected SolrMetricsContext solrMetricsContext;
- protected String registryName;
- protected SolrMetricManager metricManager;
protected Meter numErrors = new Meter();
protected Counter requests = new Counter();
protected Timer requestTimes = new Timer();
@@ -66,7 +60,7 @@ public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, S
* @param pluginConfig Config parameters, possibly from a ZK source
*/
public abstract void init(Map<String, Object> pluginConfig);
-
+
/**
* This method attempts to authenticate the request. Upon a successful authentication, this
* must call the next filter in the filter chain and set the user principal of the request,
@@ -107,10 +101,10 @@ public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, S
* delegate to {@link PKIAuthenticationPlugin}. Return true to indicate that your plugin
* did handle the request, or false to signal that PKI plugin should handle it. This method
* will be called by {@link PKIAuthenticationPlugin}'s interceptor.
- *
+ *
* <p>
* If not overridden, this method will return true for plugins implementing {@link HttpClientBuilderPlugin}.
- * This method can be overridden by subclasses e.g. to set HTTP headers, even if you don't use a clientBuilder.
+ * This method can be overridden by subclasses e.g. to set HTTP headers, even if you don't use a clientBuilder.
* </p>
* @param httpRequest the httpRequest that is about to be sent to another internal Solr node
* @param httpContext the context of that request.
@@ -137,7 +131,7 @@ public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, S
protected boolean interceptInternodeRequest(Request request) {
return this instanceof HttpClientBuilderPlugin;
}
-
+
/**
* Cleanup any per request data
*/
@@ -145,23 +139,24 @@ public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, S
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, final String scope) {
- this.metricManager = manager;
- this.registryName = registryName;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext.getChildContext(this);
// Metrics
- registry = manager.registry(registryName);
- numErrors = manager.meter(this, registryName, "errors", getCategory().toString(), scope);
- requests = manager.counter(this, registryName, "requests", getCategory().toString(), scope);
- numAuthenticated = manager.counter(this, registryName, "authenticated", getCategory().toString(), scope);
- numPassThrough = manager.counter(this, registryName, "passThrough", getCategory().toString(), scope);
- numWrongCredentials = manager.counter(this, registryName, "failWrongCredentials", getCategory().toString(), scope);
- numMissingCredentials = manager.counter(this, registryName, "failMissingCredentials", getCategory().toString(), scope);
- requestTimes = manager.timer(this, registryName, "requestTimes", getCategory().toString(), scope);
- totalTime = manager.counter(this, registryName, "totalTime", getCategory().toString(), scope);
- metricNames.addAll(Arrays.asList("errors", "requests", "authenticated", "passThrough",
- "failWrongCredentials", "failMissingCredentials", "requestTimes", "totalTime"));
+ numErrors = this.solrMetricsContext.meter(this, "errors", getCategory().toString(), scope);
+ requests = this.solrMetricsContext.counter(this, "requests", getCategory().toString(), scope);
+ numAuthenticated = this.solrMetricsContext.counter(this, "authenticated",getCategory().toString(), scope);
+ numPassThrough = this.solrMetricsContext.counter(this, "passThrough", getCategory().toString(), scope);
+ numWrongCredentials = this.solrMetricsContext.counter(this, "failWrongCredentials",getCategory().toString(), scope);
+ numMissingCredentials = this.solrMetricsContext.counter(this, "failMissingCredentials",getCategory().toString(), scope);
+ requestTimes = this.solrMetricsContext.timer(this,"requestTimes", getCategory().toString(), scope);
+ totalTime = this.solrMetricsContext.counter(this,"totalTime", getCategory().toString(), scope);
}
-
+
@Override
public String getName() {
return this.getClass().getName();
@@ -181,10 +176,4 @@ public abstract class AuthenticationPlugin implements Closeable, SolrInfoBean, S
public Set<String> getMetricNames() {
return metricNames;
}
-
- @Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
-
}
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
index 90d6b17..3c3e26f 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
@@ -77,6 +77,7 @@ import org.apache.solr.metrics.AltBufferPoolMetricSet;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.OperatingSystemMetricSet;
import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricProducer;
import org.apache.solr.security.AuditEvent;
import org.apache.solr.security.AuthenticationPlugin;
import org.apache.solr.security.PKIAuthenticationPlugin;
@@ -108,7 +109,7 @@ public class SolrDispatchFilter extends BaseSolrFilter {
private boolean isV2Enabled = !"true".equals(System.getProperty("disable.v2.api", "false"));
- private final String metricTag = Integer.toHexString(hashCode());
+ private final String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null);
private SolrMetricManager metricManager;
private String registryName;
private volatile boolean closeOnDestroy = true;
diff --git a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
index 6d9e9ea..d7654b6 100644
--- a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
+++ b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java
@@ -20,11 +20,10 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
-import com.codahale.metrics.MetricRegistry;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.search.SolrCacheBase;
/**
@@ -54,17 +53,13 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr
public AtomicLong shardBuffercacheLost = new AtomicLong(0);
private MetricsMap metricsMap;
- private MetricRegistry registry;
private Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private SolrMetricManager metricManager;
- private String registryName;
+ private SolrMetricsContext solrMetricsContext;
private long previous = System.nanoTime();
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- this.metricManager = manager;
- this.registryName = registryName;
- registry = manager.registry(registryName);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
metricsMap = new MetricsMap((detailed, map) -> {
long now = System.nanoTime();
long delta = Math.max(now - previous, 1);
@@ -108,7 +103,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr
previous = now;
});
- manager.registerGauge(this, registryName, metricsMap, tag, true, getName(), getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, metricsMap, true, getName(), getCategory().toString(), scope);
}
private float getPerSecond(long value, double seconds) {
@@ -133,8 +128,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
-
}
diff --git a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
index 2bf60cb..0739ede 100644
--- a/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
+++ b/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java
@@ -32,8 +32,8 @@ import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,9 +51,7 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer {
private final ConcurrentMap<HdfsDirectory,ConcurrentMap<FileStatus,BlockLocation[]>> cache;
private final Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
- private SolrMetricManager metricManager;
- private String registryName;
+ private SolrMetricsContext solrMetricsContext;
public HdfsLocalityReporter() {
cache = new ConcurrentHashMap<>();
@@ -89,17 +87,20 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer {
@Override
public MetricRegistry getMetricRegistry() {
- return registry;
+ return solrMetricsContext != null ? solrMetricsContext.getMetricRegistry() : null;
+ }
+
+ @Override
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
/**
* Provide statistics on HDFS block locality, both in terms of bytes and block counts.
*/
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- this.metricManager = manager;
- this.registryName = registryName;
- registry = manager.registry(registryName);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
long totalBytes = 0;
long localBytes = 0;
@@ -149,7 +150,7 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer {
map.put(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount);
}
});
- manager.registerGauge(this, registryName, metricsMap, tag, true, "hdfsLocality", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, metricsMap, true, "hdfsLocality", getCategory().toString(), scope);
}
/**
diff --git a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
index 2b621a8..248f18b 100644
--- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
+++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
@@ -51,8 +51,8 @@ import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrConfig.UpdateHandlerInfo;
import org.apache.solr.core.SolrCore;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
@@ -96,8 +96,7 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
LongAdder numDocsPending = new LongAdder();
LongAdder numErrors = new LongAdder();
Meter numErrorsCumulative;
- SolrMetricManager metricManager;
- String registryName;
+ SolrMetricsContext solrMetricsContext;
// tracks when auto-commit should occur
protected final CommitTracker commitTracker;
@@ -170,48 +169,46 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- this.metricManager = manager;
- this.registryName = registryName;
- this.registry = manager.registry(registryName);
- commitCommands = manager.meter(this, registryName, "commits", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> commitTracker.getCommitCount(), tag, true, "autoCommits", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> softCommitTracker.getCommitCount(), tag, true, "softAutoCommits", getCategory().toString(), scope);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
+ commitCommands = solrMetricsContext.meter(this, "commits", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> commitTracker.getCommitCount(), true, "autoCommits", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> softCommitTracker.getCommitCount(), true, "softAutoCommits", getCategory().toString(), scope);
if (commitTracker.getDocsUpperBound() > 0) {
- manager.registerGauge(this, registryName, () -> commitTracker.getDocsUpperBound(), tag, true, "autoCommitMaxDocs",
+ solrMetricsContext.gauge(this, () -> commitTracker.getDocsUpperBound(), true, "autoCommitMaxDocs",
getCategory().toString(), scope);
}
if (commitTracker.getTimeUpperBound() > 0) {
- manager.registerGauge(this, registryName, () -> "" + commitTracker.getTimeUpperBound() + "ms", tag, true, "autoCommitMaxTime",
+ solrMetricsContext.gauge(this, () -> "" + commitTracker.getTimeUpperBound() + "ms", true, "autoCommitMaxTime",
getCategory().toString(), scope);
}
if (commitTracker.getTLogFileSizeUpperBound() > 0) {
- manager.registerGauge(this, registryName, () -> commitTracker.getTLogFileSizeUpperBound(), tag, true, "autoCommitMaxSize",
+ solrMetricsContext.gauge(this, () -> commitTracker.getTLogFileSizeUpperBound(), true, "autoCommitMaxSize",
getCategory().toString(), scope);
}
if (softCommitTracker.getDocsUpperBound() > 0) {
- manager.registerGauge(this, registryName, () -> softCommitTracker.getDocsUpperBound(), tag, true, "softAutoCommitMaxDocs",
+ solrMetricsContext.gauge(this, () -> softCommitTracker.getDocsUpperBound(), true, "softAutoCommitMaxDocs",
getCategory().toString(), scope);
}
if (softCommitTracker.getTimeUpperBound() > 0) {
- manager.registerGauge(this, registryName, () -> "" + softCommitTracker.getTimeUpperBound() + "ms", tag, true, "softAutoCommitMaxTime",
+ solrMetricsContext.gauge(this, () -> "" + softCommitTracker.getTimeUpperBound() + "ms", true, "softAutoCommitMaxTime",
getCategory().toString(), scope);
}
- optimizeCommands = manager.meter(this, registryName, "optimizes", getCategory().toString(), scope);
- rollbackCommands = manager.meter(this, registryName, "rollbacks", getCategory().toString(), scope);
- splitCommands = manager.meter(this, registryName, "splits", getCategory().toString(), scope);
- mergeIndexesCommands = manager.meter(this, registryName, "merges", getCategory().toString(), scope);
- expungeDeleteCommands = manager.meter(this, registryName, "expungeDeletes", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> numDocsPending.longValue(), tag, true, "docsPending", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> addCommands.longValue(), tag, true, "adds", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> deleteByIdCommands.longValue(), tag, true, "deletesById", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> deleteByQueryCommands.longValue(), tag, true, "deletesByQuery", getCategory().toString(), scope);
- manager.registerGauge(this, registryName, () -> numErrors.longValue(), tag, true, "errors", getCategory().toString(), scope);
+ optimizeCommands = solrMetricsContext.meter(this, "optimizes", getCategory().toString(), scope);
+ rollbackCommands = solrMetricsContext.meter(this, "rollbacks", getCategory().toString(), scope);
+ splitCommands = solrMetricsContext.meter(this, "splits", getCategory().toString(), scope);
+ mergeIndexesCommands = solrMetricsContext.meter(this, "merges", getCategory().toString(), scope);
+ expungeDeleteCommands = solrMetricsContext.meter(this, "expungeDeletes", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> numDocsPending.longValue(), true, "docsPending", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> addCommands.longValue(), true, "adds", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString(), scope);
+ solrMetricsContext.gauge(this, () -> numErrors.longValue(), true, "errors", getCategory().toString(), scope);
- addCommandsCumulative = manager.meter(this, registryName, "cumulativeAdds", getCategory().toString(), scope);
- deleteByIdCommandsCumulative = manager.meter(this, registryName, "cumulativeDeletesById", getCategory().toString(), scope);
- deleteByQueryCommandsCumulative = manager.meter(this, registryName, "cumulativeDeletesByQuery", getCategory().toString(), scope);
- numErrorsCumulative = manager.meter(this, registryName, "cumulativeErrors", getCategory().toString(), scope);
+ addCommandsCumulative = solrMetricsContext.meter(this, "cumulativeAdds", getCategory().toString(), scope);
+ deleteByIdCommandsCumulative = solrMetricsContext.meter(this, "cumulativeDeletesById", getCategory().toString(), scope);
+ deleteByQueryCommandsCumulative = solrMetricsContext.meter(this, "cumulativeDeletesByQuery", getCategory().toString(), scope);
+ numErrorsCumulative = solrMetricsContext.meter(this, "cumulativeErrors", getCategory().toString(), scope);
}
private void deleteAll() throws IOException {
@@ -805,6 +802,11 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
softCommitTracker.close();
numDocsPending.reset();
+ try {
+ SolrMetricProducer.super.close();
+ } catch (Exception e) {
+ throw new IOException("Error closing", e);
+ }
}
@@ -915,7 +917,7 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
}
/**
- * Calls either {@link IndexWriter#updateDocValues} or {@link IndexWriter#updateDocument}(s) as
+ * Calls either {@link IndexWriter#updateDocValues} or <code>IndexWriter#updateDocument</code>(s) as
* needed based on {@link AddUpdateCommand#isInPlaceUpdate}.
* <p>
* If the this is an UPDATE_INPLACE cmd, then all fields included in
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 27e0198..8cfdd39 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -42,7 +42,7 @@ import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.DirectoryFactory.DirContext;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.schema.IndexSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -88,8 +88,7 @@ public class SolrIndexWriter extends IndexWriter {
private final AtomicLong runningMajorMergesDocs = new AtomicLong();
private final AtomicLong runningMinorMergesDocs = new AtomicLong();
- private final SolrMetricManager metricManager;
- private final String registryName;
+ private final SolrMetricsContext solrMetricsContext;
// merge diagnostics.
private final Map<String, Long> runningMerges = new ConcurrentHashMap<>();
@@ -120,8 +119,7 @@ public class SolrIndexWriter extends IndexWriter {
// no metrics
mergeTotals = false;
mergeDetails = false;
- metricManager = null;
- registryName = null;
+ solrMetricsContext = null;
}
private SolrIndexWriter(SolrCore core, String name, String path, Directory directory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, Codec codec) throws IOException {
@@ -135,8 +133,7 @@ public class SolrIndexWriter extends IndexWriter {
infoStream = getConfig().getInfoStream();
this.directory = directory;
numOpens.incrementAndGet();
- metricManager = core.getCoreContainer().getMetricManager();
- registryName = core.getCoreMetricManager().getRegistryName();
+ solrMetricsContext = core.getSolrMetricsContext().getChildContext(this);
if (config.metricsInfo != null && config.metricsInfo.initArgs != null) {
Object v = config.metricsInfo.initArgs.get("majorMergeDocs");
if (v != null) {
@@ -160,21 +157,21 @@ public class SolrIndexWriter extends IndexWriter {
}
if (mergeDetails) {
mergeTotals = true; // override
- majorMergedDocs = metricManager.meter(null, registryName, "docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
- majorDeletedDocs = metricManager.meter(null, registryName, "deletedDocs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
+ majorMergedDocs = solrMetricsContext.meter(null, "docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
+ majorDeletedDocs = solrMetricsContext.meter(null, "deletedDocs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
}
if (mergeTotals) {
- minorMerge = metricManager.timer(null, registryName, "minor", SolrInfoBean.Category.INDEX.toString(), "merge");
- majorMerge = metricManager.timer(null, registryName, "major", SolrInfoBean.Category.INDEX.toString(), "merge");
- mergeErrors = metricManager.counter(null, registryName, "errors", SolrInfoBean.Category.INDEX.toString(), "merge");
+ minorMerge = solrMetricsContext.timer(null, "minor", SolrInfoBean.Category.INDEX.toString(), "merge");
+ majorMerge = solrMetricsContext.timer(null, "major", SolrInfoBean.Category.INDEX.toString(), "merge");
+ mergeErrors = solrMetricsContext.counter(null, "errors", SolrInfoBean.Category.INDEX.toString(), "merge");
String tag = core.getMetricTag();
- metricManager.registerGauge(null, registryName, () -> runningMajorMerges.get(), tag, true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
- metricManager.registerGauge(null, registryName, () -> runningMinorMerges.get(), tag, true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
- metricManager.registerGauge(null, registryName, () -> runningMajorMergesDocs.get(), tag, true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
- metricManager.registerGauge(null, registryName, () -> runningMinorMergesDocs.get(), tag, true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
- metricManager.registerGauge(null, registryName, () -> runningMajorMergesSegments.get(), tag, true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
- metricManager.registerGauge(null, registryName, () -> runningMinorMergesSegments.get(), tag, true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
- flushMeter = metricManager.meter(null, registryName, "flush", SolrInfoBean.Category.INDEX.toString());
+ solrMetricsContext.gauge(null, () -> runningMajorMerges.get(), true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
+ solrMetricsContext.gauge(null, () -> runningMinorMerges.get(), true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
+ solrMetricsContext.gauge(null, () -> runningMajorMergesDocs.get(), true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
+ solrMetricsContext.gauge(null, () -> runningMinorMergesDocs.get(), true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
+ solrMetricsContext.gauge(null, () -> runningMajorMergesSegments.get(), true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "major");
+ solrMetricsContext.gauge(null, () -> runningMinorMergesSegments.get(), true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "minor");
+ flushMeter = solrMetricsContext.meter(null, "flush", SolrInfoBean.Category.INDEX.toString());
}
}
}
@@ -345,6 +342,9 @@ public class SolrIndexWriter extends IndexWriter {
if (directoryFactory != null) {
directoryFactory.release(directory);
}
+ if (solrMetricsContext != null) {
+ solrMetricsContext.unregister();
+ }
}
}
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
index c8dbc10..59dae8a 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
@@ -22,7 +22,6 @@ import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
-import com.codahale.metrics.MetricRegistry;
import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.HdfsDirectoryFactory;
import org.apache.solr.core.PluginInfo;
@@ -57,7 +56,6 @@ public abstract class UpdateHandler implements SolrInfoBean {
protected final UpdateLog ulog;
protected Set<String> metricNames = ConcurrentHashMap.newKeySet();
- protected MetricRegistry registry;
private void parseEventListeners() {
final Class<SolrEventListener> clazz = SolrEventListener.class;
@@ -211,8 +209,4 @@ public abstract class UpdateHandler implements SolrInfoBean {
public Set<String> getMetricNames() {
return metricNames;
}
- @Override
- public MetricRegistry getMetricRegistry() {
- return registry;
- }
}
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index 8e3486b..fe966cb 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -25,7 +25,6 @@ import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
-import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -40,6 +39,7 @@ import org.apache.solr.common.util.SolrjNamedThreadFactory;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.security.HttpClientBuilderPlugin;
import org.apache.solr.update.processor.DistributedUpdateProcessor;
import org.apache.solr.update.processor.DistributingUpdateProcessorFactory;
@@ -90,7 +90,7 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean {
private final Set<String> metricNames = ConcurrentHashMap.newKeySet();
- private MetricRegistry registry;
+ private SolrMetricsContext solrMetricsContext;
private int socketTimeout = HttpClientUtil.DEFAULT_SO_TIMEOUT;
private int connectionTimeout = HttpClientUtil.DEFAULT_CONNECT_TIMEOUT;
@@ -179,14 +179,14 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean {
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) {
- registry = manager.registry(registryName);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ solrMetricsContext = parentContext.getChildContext(this);
String expandedScope = SolrMetricManager.mkName(scope, getCategory().name());
- updateHttpListenerFactory.initializeMetrics(manager, registryName, tag, expandedScope);
- defaultConnectionManager.initializeMetrics(manager, registryName, tag, expandedScope);
- updateExecutor = MetricUtils.instrumentedExecutorService(updateExecutor, this, registry,
+ updateHttpListenerFactory.initializeMetrics(solrMetricsContext, expandedScope);
+ defaultConnectionManager.initializeMetrics(solrMetricsContext, expandedScope);
+ updateExecutor = MetricUtils.instrumentedExecutorService(updateExecutor, this, solrMetricsContext.getMetricRegistry(),
SolrMetricManager.mkName("updateOnlyExecutor", expandedScope, "threadPool"));
- recoveryExecutor = MetricUtils.instrumentedExecutorService(recoveryExecutor, this, registry,
+ recoveryExecutor = MetricUtils.instrumentedExecutorService(recoveryExecutor, this, solrMetricsContext.getMetricRegistry(),
SolrMetricManager.mkName("recoveryExecutor", expandedScope, "threadPool"));
}
@@ -206,8 +206,8 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean {
}
@Override
- public MetricRegistry getMetricRegistry() {
- return registry;
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
}
// if you are looking for a client to use, it's probably this one.
@@ -259,6 +259,11 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean {
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
+ try {
+ SolrMetricProducer.super.close();
+ } catch (Exception e) {
+ // do nothing
+ }
IOUtils.closeQuietly(updateOnlyClient);
HttpClientUtil.close(recoveryOnlyClient);
HttpClientUtil.close(defaultClient);
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java
index d452502..c3bc3e5 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java
@@ -21,11 +21,10 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import org.apache.solr.client.solrj.impl.HttpListenerFactory;
-import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Result;
@@ -64,9 +63,7 @@ public class InstrumentedHttpListenerFactory implements SolrMetricProducer, Http
KNOWN_METRIC_NAME_STRATEGIES.put("methodOnly", METHOD_ONLY);
}
- protected MetricRegistry metricsRegistry;
- protected SolrMetricManager metricManager;
- protected String registryName;
+ protected SolrMetricsContext solrMetricsContext;
protected String scope;
protected NameStrategy nameStrategy;
@@ -85,7 +82,7 @@ public class InstrumentedHttpListenerFactory implements SolrMetricProducer, Http
@Override
public void onBegin(Request request) {
- if (metricsRegistry != null) {
+ if (solrMetricsContext != null) {
timerContext = timer(request).time();
}
}
@@ -100,14 +97,12 @@ public class InstrumentedHttpListenerFactory implements SolrMetricProducer, Http
}
private Timer timer(Request request) {
- return metricsRegistry.timer(nameStrategy.getNameFor(scope, request));
+ return solrMetricsContext.timer(null, nameStrategy.getNameFor(scope, request));
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- this.metricManager = manager;
- this.registryName = registry;
- this.metricsRegistry = manager.registry(registry);
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext;
this.scope = scope;
}
}
diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
index 398ab8b..c7397ba 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedPoolingHttpClientConnectionManager.java
@@ -22,6 +22,7 @@ import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
/**
* Sub-class of PoolingHttpClientConnectionManager which tracks metrics interesting to Solr.
@@ -29,25 +30,28 @@ import org.apache.solr.metrics.SolrMetricProducer;
*/
public class InstrumentedPoolingHttpClientConnectionManager extends PoolingHttpClientConnectionManager implements SolrMetricProducer {
- private SolrMetricManager metricManager;
- private String registryName;
+ private SolrMetricsContext solrMetricsContext;
public InstrumentedPoolingHttpClientConnectionManager(Registry<ConnectionSocketFactory> socketFactoryRegistry) {
super(socketFactoryRegistry);
}
@Override
- public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
- this.metricManager = manager;
- this.registryName = registry;
- manager.registerGauge(null, registry, () -> getTotalStats().getAvailable(),
- tag, true, SolrMetricManager.mkName("availableConnections", scope));
+ public SolrMetricsContext getSolrMetricsContext() {
+ return solrMetricsContext;
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ this.solrMetricsContext = parentContext.getChildContext(this);
+ parentContext.gauge(null, () -> getTotalStats().getAvailable(),
+ true, SolrMetricManager.mkName("availableConnections", scope));
// this acquires a lock on the connection pool; remove if contention sucks
- manager.registerGauge(null, registry, () -> getTotalStats().getLeased(),
- tag, true, SolrMetricManager.mkName("leasedConnections", scope));
- manager.registerGauge(null, registry, () -> getTotalStats().getMax(),
- tag, true, SolrMetricManager.mkName("maxConnections", scope));
- manager.registerGauge(null, registry, () -> getTotalStats().getPending(),
- tag, true, SolrMetricManager.mkName("pendingConnections", scope));
+ parentContext.gauge(null, () -> getTotalStats().getLeased(),
+ true, SolrMetricManager.mkName("leasedConnections", scope));
+ parentContext.gauge(null, () -> getTotalStats().getMax(),
+ true, SolrMetricManager.mkName("maxConnections", scope));
+ parentContext.gauge(null, () -> getTotalStats().getPending(),
+ true, SolrMetricManager.mkName("pendingConnections", scope));
}
}
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
index a6dbd9e..3b52568 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/MetricsHandlerTest.java
@@ -17,6 +17,7 @@
package org.apache.solr.handler.admin;
+import java.util.Arrays;
import java.util.Map;
import com.codahale.metrics.Counter;
@@ -24,6 +25,15 @@ import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.Utils;
+import org.apache.solr.core.PluginBag;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.metrics.MetricsMap;
+import org.apache.solr.metrics.SolrMetricsContext;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -53,12 +63,12 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
@AfterClass
public static void cleanupMetrics() throws Exception {
if (null != h) {
- h.getCoreContainer().getMetricManager().registry("solr.jvm" ).remove("solrtest_foo");
+ h.getCoreContainer().getMetricManager().registry("solr.jvm").remove("solrtest_foo");
h.getCoreContainer().getMetricManager().registry("solr.jetty").remove("solrtest_foo");
h.getCoreContainer().getMetricManager().registry("solr.jetty").remove("solrtest_foo:bar");
}
}
-
+
@Test
public void test() throws Exception {
MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
@@ -145,7 +155,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(1, values.size());
- assertEquals(13, ((NamedList)values.get("solr.node")).size());
+ assertEquals(13, ((NamedList) values.get("solr.node")).size());
assertNotNull(values.get("solr.node"));
values = (NamedList) values.get("solr.node");
assertNotNull(values.get("CONTAINER.cores.lazy")); // this is a gauge node
@@ -171,7 +181,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
assertNotNull(values.get("solr.core.collection1"));
values = (NamedList) values.get("solr.core.collection1");
assertEquals(1, values.size());
- Map m = (Map)values.get("CACHE.core.fieldCache");
+ Map m = (Map) values.get("CACHE.core.fieldCache");
assertNotNull(m);
assertNotNull(m.get("entries_count"));
@@ -223,7 +233,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
assertTrue(nl.size() > 0);
nl.forEach((k, v) -> {
assertTrue(v instanceof Map);
- Map map = (Map)v;
+ Map map = (Map) v;
assertTrue(map.size() > 2);
});
@@ -238,7 +248,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
assertTrue(nl.size() > 0);
nl.forEach((k, v) -> {
assertTrue(v instanceof Map);
- Map map = (Map)v;
+ Map map = (Map) v;
assertEquals(2, map.size());
assertNotNull(map.get("inserts"));
assertNotNull(map.get("size"));
@@ -257,7 +267,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
Object val = values.findRecursive("metrics", key1);
assertNotNull(val);
assertTrue(val instanceof Map);
- assertTrue(((Map)val).size() >= 2);
+ assertTrue(((Map) val).size() >= 2);
String key2 = "solr.core.collection1:CACHE.core.fieldCache:entries_count";
resp = new SolrQueryResponse();
@@ -276,7 +286,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
val = values.findRecursive("metrics", key3);
assertNotNull(val);
assertTrue(val instanceof Number);
- assertEquals(3, ((Number)val).intValue());
+ assertEquals(3, ((Number) val).intValue());
// test multiple keys
resp = new SolrQueryResponse();
@@ -306,7 +316,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "foo", MetricsHandler.KEY_PARAM, "foo:bar:baz:xyz"), resp);
values = resp.getValues();
- NamedList metrics = (NamedList)values.get("metrics");
+ NamedList metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "foo"));
assertNotNull(values.findRecursive("errors", "foo:bar:baz:xyz"));
@@ -316,7 +326,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "foo:bar:baz"), resp);
values = resp.getValues();
- metrics = (NamedList)values.get("metrics");
+ metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "foo:bar:baz"));
@@ -325,8 +335,122 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "solr.jetty:unknown:baz"), resp);
values = resp.getValues();
- metrics = (NamedList)values.get("metrics");
+ metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "solr.jetty:unknown:baz"));
}
+
+ @Test
+ public void testMetricsUnload() throws Exception {
+
+ SolrCore core = h.getCoreContainer().getCore("collection1");//;.getRequestHandlers().put("/dumphandler", new DumpRequestHandler());
+ RefreshablePluginHolder pluginHolder =null;
+ try {
+ PluginInfo info = new PluginInfo(SolrRequestHandler.TYPE, Utils.makeMap("name", "/dumphandler", "class", DumpRequestHandler.class.getName()));
+ DumpRequestHandler requestHandler = new DumpRequestHandler();
+ requestHandler.gaugevals = Utils.makeMap("d_k1","v1", "d_k2","v2");
+ pluginHolder = new RefreshablePluginHolder(info, requestHandler);
+ core.getRequestHandlers().put("/dumphandler",
+
+ pluginHolder);
+ } finally {
+ core.close();
+ }
+
+
+
+ MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
+
+ SolrQueryResponse resp = new SolrQueryResponse();
+ handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", MetricsHandler.COMPACT_PARAM, "true", "key", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge"),
+ resp);
+
+ assertEquals("v1", resp.getValues()._getStr(Arrays.asList("metrics", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k1"), null));
+ assertEquals("v2", resp.getValues()._getStr(Arrays.asList("metrics","solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k2"), null));
+ pluginHolder.closeHandler();
+ resp = new SolrQueryResponse();
+ handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", MetricsHandler.COMPACT_PARAM, "true", "key", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge"),
+ resp);
+
+ assertEquals(null, resp.getValues()._getStr(Arrays.asList("metrics", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k1"), null));
+ assertEquals(null, resp.getValues()._getStr(Arrays.asList("metrics","solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k2"), null));
+
+ DumpRequestHandler requestHandler = new DumpRequestHandler();
+ requestHandler.gaugevals = Utils.makeMap("d_k1","v1.1", "d_k2","v2.1");
+ pluginHolder.reset(requestHandler);
+ resp = new SolrQueryResponse();
+ handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", MetricsHandler.COMPACT_PARAM, "true", "key", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge"),
+ resp);
+
+ assertEquals("v1.1", resp.getValues()._getStr(Arrays.asList("metrics", "solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k1"), null));
+ assertEquals("v2.1", resp.getValues()._getStr(Arrays.asList("metrics","solr.core.collection1:QUERY./dumphandler.dumphandlergauge","d_k2"), null));
+
+
+ }
+
+ static class RefreshablePluginHolder extends PluginBag.PluginHolder<SolrRequestHandler> {
+
+ private DumpRequestHandler rh;
+ private SolrMetricsContext metricsInfo;
+
+ public RefreshablePluginHolder(PluginInfo info, DumpRequestHandler rh) {
+ super(info);
+ this.rh = rh;
+ }
+
+ @Override
+ public boolean isLoaded() {
+ return true;
+ }
+
+ void closeHandler() throws Exception {
+ this.metricsInfo = rh.getSolrMetricsContext();
+// if(metricsInfo.tag.contains(String.valueOf(rh.hashCode()))){
+// //this created a new child metrics
+// metricsInfo = metricsInfo.getParent();
+// }
+ this.rh.close();
+ }
+
+ void reset(DumpRequestHandler rh) throws Exception {
+ this.rh = rh;
+ if(metricsInfo != null)
+ this.rh.initializeMetrics(metricsInfo, "/dumphandler");
+ }
+
+
+ @Override
+ public SolrRequestHandler get() {
+ return rh;
+ }
+ }
+
+ public static class DumpRequestHandler extends RequestHandlerBase {
+
+ static String key = DumpRequestHandler.class.getName();
+ Map<String, Object> gaugevals ;
+ @Override
+ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
+ rsp.add("key", key);
+ }
+
+ @Override
+ public String getDescription() {
+ return "DO nothing";
+ }
+
+ @Override
+ public void initializeMetrics(SolrMetricsContext parentContext, String scope) {
+ super.initializeMetrics(parentContext, scope);
+ MetricsMap metrics = new MetricsMap((detailed, map) -> map.putAll(gaugevals));
+ solrMetricsContext.gauge(this,
+ metrics, true, "dumphandlergauge", getCategory().toString(), scope);
+
+ }
+
+ @Override
+ public Boolean registerV2() {
+ return Boolean.FALSE;
+ }
+ }
}
diff --git a/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java b/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java
index e1919b0..27ecf9c 100644
--- a/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestCaffeineCache.java
@@ -281,5 +281,6 @@ public class TestCaffeineCache extends SolrTestCase {
}
assertTrue("total ram bytes should be greater than 0", total > 0);
assertTrue("total ram bytes exceeded limit", total < 1024 * 1024);
+ cache.close();
}
}
diff --git a/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java b/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
index 35991ae..e3ee328 100644
--- a/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java
@@ -30,7 +30,6 @@ import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.util.ConcurrentLRUCache;
import org.apache.solr.util.RTimer;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
@@ -52,7 +51,7 @@ public class TestFastLRUCache extends SolrTestCase {
String registry = TestUtil.randomSimpleString(random(), 2, 10);
String scope = TestUtil.randomSimpleString(random(), 2, 10);
- public void testPercentageAutowarm() throws IOException {
+ public void testPercentageAutowarm() throws Exception {
FastLRUCache<Object, Object> fastCache = new FastLRUCache<>();
Map<String, String> params = new HashMap<>();
params.put("size", "100");
@@ -94,7 +93,7 @@ public class TestFastLRUCache extends SolrTestCase {
fastCacheNew.close();
}
- public void testPercentageAutowarmMultiple() throws IOException {
+ public void testPercentageAutowarmMultiple() throws Exception {
doTestPercentageAutowarm(100, 50, new int[]{51, 55, 60, 70, 80, 99, 100}, new int[]{1, 2, 3, 5, 10, 20, 30, 40, 50});
doTestPercentageAutowarm(100, 25, new int[]{76, 80, 99, 100}, new int[]{1, 2, 3, 5, 10, 20, 30, 40, 50, 51, 55, 60, 70});
doTestPercentageAutowarm(1000, 10, new int[]{901, 930, 950, 999, 1000}, new int[]{1, 5, 100, 200, 300, 400, 800, 899, 900});
@@ -102,7 +101,7 @@ public class TestFastLRUCache extends SolrTestCase {
doTestPercentageAutowarm(100, 0, new int[]{}, new int[]{1, 10, 25, 51, 55, 60, 70, 80, 99, 100, 200, 300});
}
- private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses) {
+ private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses) throws Exception {
FastLRUCache<Object, Object> fastCache = new FastLRUCache<>();
Map<String, String> params = new HashMap<>();
params.put("size", String.valueOf(limit));
@@ -136,7 +135,7 @@ public class TestFastLRUCache extends SolrTestCase {
fastCacheNew.close();
}
- public void testNoAutowarm() throws IOException {
+ public void testNoAutowarm() throws Exception {
FastLRUCache<Object, Object> fastCache = new FastLRUCache<>();
Map<String, String> params = new HashMap<>();
params.put("size", "100");
@@ -166,7 +165,7 @@ public class TestFastLRUCache extends SolrTestCase {
fastCacheNew.close();
}
- public void testFullAutowarm() throws IOException {
+ public void testFullAutowarm() throws Exception {
FastLRUCache<Object, Object> cache = new FastLRUCache<>();
Map<Object, Object> params = new HashMap<>();
params.put("size", "100");
@@ -196,7 +195,7 @@ public class TestFastLRUCache extends SolrTestCase {
cacheNew.close();
}
- public void testSimple() throws IOException {
+ public void testSimple() throws Exception {
FastLRUCache sc = new FastLRUCache();
Map l = new HashMap();
l.put("size", "100");
@@ -304,7 +303,7 @@ public class TestFastLRUCache extends SolrTestCase {
System.out.println("time=" + timer.getTime() + ", minSize="+minSize+",maxSize="+maxSize);
}
- public void testAccountable() {
+ public void testAccountable() throws Exception {
FastLRUCache<Query, DocSet> sc = new FastLRUCache<>();
try {
Map l = new HashMap();
diff --git a/solr/core/src/test/org/apache/solr/search/TestLFUCache.java b/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
index 289d3b8..9802a63 100644
--- a/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestLFUCache.java
@@ -134,7 +134,7 @@ public class TestLFUCache extends SolrTestCaseJ4 {
@Test
- public void testSimple() throws IOException {
+ public void testSimple() throws Exception {
SolrMetricManager metricManager = new SolrMetricManager();
Random r = random();
String registry = TestUtil.randomSimpleString(r, 2, 10);
diff --git a/solr/core/src/test/org/apache/solr/search/TestLRUCache.java b/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
index f5b15a0..297dfa2 100644
--- a/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
+++ b/solr/core/src/test/org/apache/solr/search/TestLRUCache.java
@@ -16,7 +16,6 @@
*/
package org.apache.solr.search;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -38,7 +37,7 @@ public class TestLRUCache extends SolrTestCase {
String registry = TestUtil.randomSimpleString(random(), 2, 10);
String scope = TestUtil.randomSimpleString(random(), 2, 10);
- public void testFullAutowarm() throws IOException {
+ public void testFullAutowarm() throws Exception {
LRUCache<Object, Object> lruCache = new LRUCache<>();
Map<String, String> params = new HashMap<>();
params.put("size", "100");
@@ -64,14 +63,14 @@ public class TestLRUCache extends SolrTestCase {
lruCacheNew.close();
}
- public void testPercentageAutowarm() throws IOException {
+ public void testPercentageAutowarm() throws Exception {
doTestPercentageAutowarm(100, 50, new int[]{51, 55, 60, 70, 80, 99, 100}, new int[]{1, 2, 3, 5, 10, 20, 30, 40, 50});
doTestPercentageAutowarm(100, 25, new int[]{76, 80, 99, 100}, new int[]{1, 2, 3, 5, 10, 20, 30, 40, 50, 51, 55, 60, 70});
doTestPercentageAutowarm(1000, 10, new int[]{901, 930, 950, 999, 1000}, new int[]{1, 5, 100, 200, 300, 400, 800, 899, 900});
doTestPercentageAutowarm(10, 10, new int[]{10}, new int[]{1, 5, 9, 100, 200, 300, 400, 800, 899, 900});
}
- private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses) {
+ private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses) throws Exception {
LRUCache<Object, Object> lruCache = new LRUCache<>();
Map<String, String> params = new HashMap<>();
params.put("size", String.valueOf(limit));
@@ -101,7 +100,7 @@ public class TestLRUCache extends SolrTestCase {
}
@SuppressWarnings("unchecked")
- public void testNoAutowarm() throws IOException {
+ public void testNoAutowarm() throws Exception {
LRUCache<Object, Object> lruCache = new LRUCache<>();
lruCache.initializeMetrics(metricManager, registry, "foo", scope);
Map<String, String> params = new HashMap<>();
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java b/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java
index a053a18..e5bad27 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java
@@ -72,6 +72,7 @@ public class ExecutorUtil {
}
public static void shutdownAndAwaitTermination(ExecutorService pool) {
+ if(pool == null) return;
pool.shutdown(); // Disable new tasks from being submitted
awaitTermination(pool);
}