From commits-return-99994-archive-asf-public=cust-asf.ponee.io@lucene.apache.org Tue Apr 3 11:41:01 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 192A2180675 for ; Tue, 3 Apr 2018 11:40:58 +0200 (CEST) Received: (qmail 39685 invoked by uid 500); 3 Apr 2018 09:40:58 -0000 Mailing-List: contact commits-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@lucene.apache.org Delivered-To: mailing list commits@lucene.apache.org Received: (qmail 39675 invoked by uid 99); 3 Apr 2018 09:40:58 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 03 Apr 2018 09:40:58 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 82F67F4E5E; Tue, 3 Apr 2018 09:40:57 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: ab@apache.org To: commits@lucene.apache.org Date: Tue, 03 Apr 2018 09:40:58 -0000 Message-Id: In-Reply-To: <166798d83ceb4b6f901f3b6a7ecd018f@git.apache.org> References: <166798d83ceb4b6f901f3b6a7ecd018f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/2] lucene-solr:branch_7x: SOLR-11882: SolrMetric registries retained references to SolrCores when closed. SOLR-11882: SolrMetric registries retained references to SolrCores when closed. Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/483914b6 Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/483914b6 Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/483914b6 Branch: refs/heads/branch_7x Commit: 483914b6a4c5aaa163625169066e8c6bb3942566 Parents: 974c03a Author: Andrzej Bialecki Authored: Tue Apr 3 10:40:52 2018 +0200 Committer: Andrzej Bialecki Committed: Tue Apr 3 10:41:38 2018 +0200 ---------------------------------------------------------------------- solr/CHANGES.txt | 6 ++ .../handler/dataimport/DataImportHandler.java | 6 +- .../org/apache/solr/core/CoreContainer.java | 45 ++++++++------- .../apache/solr/core/HdfsDirectoryFactory.java | 8 +-- .../src/java/org/apache/solr/core/SolrCore.java | 41 ++++++++------ .../java/org/apache/solr/core/SolrInfoBean.java | 2 +- .../apache/solr/handler/ReplicationHandler.java | 44 +++++++-------- .../apache/solr/handler/RequestHandlerBase.java | 12 ++-- .../solr/handler/admin/CoreAdminHandler.java | 4 +- .../component/HttpShardHandlerFactory.java | 9 ++- .../solr/handler/component/SearchComponent.java | 2 +- .../handler/component/SuggestComponent.java | 11 +++- .../solr/highlight/HighlightingPluginBase.java | 6 +- .../solr/metrics/SolrCoreMetricManager.java | 7 ++- .../apache/solr/metrics/SolrMetricManager.java | 58 ++++++++++++++++++-- .../apache/solr/metrics/SolrMetricProducer.java | 29 +++++++++- .../metrics/reporters/solr/SolrReporter.java | 2 +- .../org/apache/solr/search/FastLRUCache.java | 9 ++- .../java/org/apache/solr/search/LFUCache.java | 8 ++- .../java/org/apache/solr/search/LRUCache.java | 10 +++- .../apache/solr/search/SolrFieldCacheBean.java | 4 +- .../apache/solr/search/SolrIndexSearcher.java | 37 +++++++------ .../apache/solr/servlet/SolrDispatchFilter.java | 26 ++++++--- .../apache/solr/store/blockcache/Metrics.java | 8 ++- .../solr/store/hdfs/HdfsLocalityReporter.java | 8 ++- .../solr/update/DirectUpdateHandler2.java | 28 ++++++---- .../java/org/apache/solr/update/PeerSync.java | 2 +- .../org/apache/solr/update/SolrIndexWriter.java | 34 +++++++----- .../java/org/apache/solr/update/UpdateLog.java | 14 +++-- .../apache/solr/update/UpdateShardHandler.java | 6 +- .../stats/InstrumentedHttpRequestExecutor.java | 7 ++- ...entedPoolingHttpClientConnectionManager.java | 19 +++++-- .../test/org/apache/solr/CursorPagingTest.java | 5 +- .../test/org/apache/solr/SolrInfoBeanTest.java | 2 +- .../solr/core/ExitableDirectoryReaderTest.java | 7 ++- .../solr/core/HdfsDirectoryFactoryTest.java | 4 +- .../test/org/apache/solr/core/MockInfoBean.java | 8 ++- .../core/MockQuerySenderListenerReqHandler.java | 6 +- .../apache/solr/core/TestJmxIntegration.java | 4 +- .../org/apache/solr/metrics/JvmMetricsTest.java | 2 +- .../solr/metrics/SolrCoreMetricManagerTest.java | 2 +- .../solr/metrics/SolrMetricManagerTest.java | 10 ++-- .../solr/metrics/SolrMetricTestUtils.java | 2 +- .../apache/solr/search/TestFastLRUCache.java | 14 ++--- .../org/apache/solr/search/TestLFUCache.java | 6 +- .../org/apache/solr/search/TestLRUCache.java | 4 +- .../solr/search/TestReRankQParserPlugin.java | 3 +- .../apache/solr/search/TestSolr4Spatial2.java | 3 +- .../solr/search/TestSolrFieldCacheBean.java | 8 +-- .../apache/solr/search/TestSolrQueryParser.java | 9 +-- .../apache/solr/search/join/BJQParserTest.java | 9 +-- .../solr/search/join/TestScoreJoinQPScore.java | 3 +- .../solr/store/blockcache/BufferStoreTest.java | 4 +- 53 files changed, 401 insertions(+), 226 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/CHANGES.txt ---------------------------------------------------------------------- diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index ea895c5..503a9e4 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -83,6 +83,12 @@ Bug Fixes * SOLR-12172: Fixed race condition that could cause an invalid set of collection properties to be kept in memory when multiple collection property changes are done in a short period of time. (Tomás Fernández Löbbe) +* SOLR-11882: SolrMetric registries retained references to SolrCores when closed. A + change of SolrMetricMAnager.registerGauge and SolrMetricProducer.initializeMetrics + method signatures was required to fix it. Third party components may continue to use the old API + but should be updated to avoid this bug (Eros Taborelli, Erick Erickson, ab) + + Optimizations ---------------------- http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImportHandler.java ---------------------------------------------------------------------- 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 faea3ba..046901a 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 @@ -265,8 +265,8 @@ public class DataImportHandler extends RequestHandlerBase implements } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { - super.initializeMetrics(manager, registryName, scope); + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + super.initializeMetrics(manager, registryName, tag, scope); metrics = new MetricsMap((detailed, map) -> { if (importer != null) { DocBuilder.Statistics cumulative = importer.cumulativeStatistics; @@ -289,7 +289,7 @@ public class DataImportHandler extends RequestHandlerBase implements map.put(DataImporter.MSG.TOTAL_DOCS_SKIPPED, cumulative.skipDocCount); } }); - manager.registerGauge(this, registryName, metrics, true, "importer", getCategory().toString(), scope); + manager.registerGauge(this, registryName, metrics, tag, true, "importer", getCategory().toString(), scope); } // //////////////////////SolrInfoMBeans methods ////////////////////// http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/core/CoreContainer.java ---------------------------------------------------------------------- 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 39e6a99..78247a0 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -183,6 +183,8 @@ public class CoreContainer { protected SolrMetricManager metricManager; + protected String metricTag = Integer.toHexString(hashCode()); + protected MetricsHandler metricsHandler; protected MetricsCollectorHandler metricsCollectorHandler; @@ -503,11 +505,11 @@ public class CoreContainer { shardHandlerFactory = ShardHandlerFactory.newInstance(cfg.getShardHandlerFactoryPluginInfo(), loader); if (shardHandlerFactory instanceof SolrMetricProducer) { SolrMetricProducer metricProducer = (SolrMetricProducer) shardHandlerFactory; - metricProducer.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), "httpShardHandler"); + metricProducer.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, "httpShardHandler"); } updateShardHandler = new UpdateShardHandler(cfg.getUpdateShardHandlerConfig()); - updateShardHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), "updateShardHandler"); + updateShardHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, "updateShardHandler"); solrCores.load(loader); @@ -537,7 +539,7 @@ public class CoreContainer { metricsCollectorHandler.init(null); containerHandlers.put(AUTHZ_PATH, securityConfHandler); - securityConfHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), AUTHZ_PATH); + securityConfHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, AUTHZ_PATH); containerHandlers.put(AUTHC_PATH, securityConfHandler); if(pkiAuthenticationPlugin != null) containerHandlers.put(PKIAuthenticationPlugin.PATH, pkiAuthenticationPlugin.getRequestHandler()); @@ -554,19 +556,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(), - true, "loaded", SolrInfoBean.Category.CONTAINER.toString(), "cores"); + metricTag,true, "loaded", SolrInfoBean.Category.CONTAINER.toString(), "cores"); metricManager.registerGauge(null, registryName, () -> solrCores.getLoadedCoreNames().size() - solrCores.getCores().size(), - true, "lazy", SolrInfoBean.Category.CONTAINER.toString(), "cores"); + metricTag,true, "lazy", SolrInfoBean.Category.CONTAINER.toString(), "cores"); metricManager.registerGauge(null, registryName, () -> solrCores.getAllCoreNames().size() - solrCores.getLoadedCoreNames().size(), - true, "unloaded", SolrInfoBean.Category.CONTAINER.toString(), "cores"); + metricTag,true, "unloaded", SolrInfoBean.Category.CONTAINER.toString(), "cores"); Path dataHome = cfg.getSolrDataHome() != null ? cfg.getSolrDataHome() : cfg.getCoreRootDirectory(); metricManager.registerGauge(null, registryName, () -> dataHome.toFile().getTotalSpace(), - true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs"); + metricTag,true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs"); metricManager.registerGauge(null, registryName, () -> dataHome.toFile().getUsableSpace(), - true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs"); + metricTag,true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs"); metricManager.registerGauge(null, registryName, () -> dataHome.toAbsolutePath().toString(), - true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs"); + metricTag,true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs"); metricManager.registerGauge(null, registryName, () -> { try { return org.apache.lucene.util.IOUtils.spins(dataHome.toAbsolutePath()); @@ -575,13 +578,13 @@ public class CoreContainer { return true; } }, - true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs"); + metricTag,true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs"); metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toFile().getTotalSpace(), - true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); + metricTag,true, "totalSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toFile().getUsableSpace(), - true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); + metricTag,true, "usableSpace", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); metricManager.registerGauge(null, registryName, () -> cfg.getCoreRootDirectory().toAbsolutePath().toString(), - true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); + metricTag,true, "path", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); metricManager.registerGauge(null, registryName, () -> { try { return org.apache.lucene.util.IOUtils.spins(cfg.getCoreRootDirectory().toAbsolutePath()); @@ -590,15 +593,15 @@ public class CoreContainer { return true; } }, - true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); + metricTag,true, "spins", SolrInfoBean.Category.CONTAINER.toString(), "fs", "coreRoot"); // add version information metricManager.registerGauge(null, registryName, () -> this.getClass().getPackage().getSpecificationVersion(), - true, "specification", SolrInfoBean.Category.CONTAINER.toString(), "version"); + metricTag,true, "specification", SolrInfoBean.Category.CONTAINER.toString(), "version"); metricManager.registerGauge(null, registryName, () -> this.getClass().getPackage().getImplementationVersion(), - true, "implementation", SolrInfoBean.Category.CONTAINER.toString(), "version"); + metricTag,true, "implementation", SolrInfoBean.Category.CONTAINER.toString(), "version"); SolrFieldCacheBean fieldCacheBean = new SolrFieldCacheBean(); - fieldCacheBean.initializeMetrics(metricManager, registryName, null); + fieldCacheBean.initializeMetrics(metricManager, registryName, metricTag, null); if (isZooKeeperAware()) { metricManager.loadClusterReporters(metricReporters, this); @@ -687,7 +690,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(), AutoScalingHandler.HANDLER_PATH); + autoScalingHandler.initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, 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; @@ -740,6 +743,10 @@ public class CoreContainer { metricManager.closeReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node)); metricManager.closeReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm)); metricManager.closeReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jetty)); + + metricManager.unregisterGauges(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node), metricTag); + metricManager.unregisterGauges(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm), metricTag); + metricManager.unregisterGauges(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jetty), metricTag); } if (isZooKeeperAware()) { @@ -1549,7 +1556,7 @@ public class CoreContainer { containerHandlers.put(path, (SolrRequestHandler)handler); } if (handler instanceof SolrMetricProducer) { - ((SolrMetricProducer)handler).initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), path); + ((SolrMetricProducer)handler).initializeMetrics(metricManager, SolrInfoBean.Group.node.toString(), metricTag, path); } return handler; } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java ---------------------------------------------------------------------- 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 4938689..e4b06b7 100644 --- a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java +++ b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java @@ -114,7 +114,7 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol public static Metrics metrics; private static Boolean kerberosInit; - + // we use this cache for FileSystem instances when we don't have access to a long lived instance private com.google.common.cache.Cache tmpFsCache = CacheBuilder.newBuilder() .concurrencyLevel(10) @@ -489,9 +489,9 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { - MetricsHolder.metrics.initializeMetrics(manager, registry, scope); - LocalityHolder.reporter.initializeMetrics(manager, registry, scope); + 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); } @Override http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/core/SolrCore.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java index f1bae42..83dd2df 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -225,6 +225,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab private final CoreContainer coreContainer; private Set metricNames = ConcurrentHashMap.newKeySet(); + private String metricTag = Integer.toHexString(hashCode()); public Set getMetricNames() { return metricNames; @@ -925,12 +926,12 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab SolrMetricManager metricManager = coreContainer.getMetricManager(); // initialize searcher-related metrics - initializeMetrics(metricManager, coreMetricManager.getRegistryName(), null); + initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, 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(), "core"); + solrFieldCacheBean.initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, "core"); infoRegistry.put("fieldCache", solrFieldCacheBean); @@ -1023,7 +1024,7 @@ 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(), "directoryFactory"); + ((SolrMetricProducer)directoryFactory).initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, "directoryFactory"); } // seed version buckets with max from index during core initialization ... requires a searcher! @@ -1142,22 +1143,22 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + 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, true, "coreName", Category.CORE.toString()); - manager.registerGauge(this, registry, () -> startTime, true, "startTime", Category.CORE.toString()); - manager.registerGauge(this, registry, () -> getOpenCount(), true, "refCount", Category.CORE.toString()); - manager.registerGauge(this, registry, () -> resourceLoader.getInstancePath().toString(), true, "instanceDir", Category.CORE.toString()); - manager.registerGauge(this, registry, () -> isClosed() ? "(closed)" : getIndexDir(), true, "indexDir", Category.CORE.toString()); - manager.registerGauge(this, registry, () -> isClosed() ? 0 : getIndexSize(), true, "sizeInBytes", Category.INDEX.toString()); - manager.registerGauge(this, registry, () -> isClosed() ? "(closed)" : NumberUtils.readableSize(getIndexSize()), true, "size", Category.INDEX.toString()); + 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()); if (coreContainer != null) { - manager.registerGauge(this, registry, () -> coreContainer.getNamesForCore(this), true, "aliases", Category.CORE.toString()); + manager.registerGauge(this, registry, () -> coreContainer.getNamesForCore(this), getMetricTag(), true, "aliases", Category.CORE.toString()); final CloudDescriptor cd = getCoreDescriptor().getCloudDescriptor(); if (cd != null) { manager.registerGauge(this, registry, () -> { @@ -1166,7 +1167,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab } else { return "_notset_"; } - }, true, "collection", Category.CORE.toString()); + }, getMetricTag(), true, "collection", Category.CORE.toString()); manager.registerGauge(this, registry, () -> { if (cd.getShardId() != null) { @@ -1174,15 +1175,15 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab } else { return "_auto_"; } - }, true, "shard", Category.CORE.toString()); + }, getMetricTag(), 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(), true, "totalSpace", Category.CORE.toString(), "fs"); - manager.registerGauge(this, registry, () -> dataDirFile.getUsableSpace(), true, "usableSpace", Category.CORE.toString(), "fs"); - manager.registerGauge(this, registry, () -> dataDirPath.toAbsolutePath().toString(), true, "path", Category.CORE.toString(), "fs"); + 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, () -> { try { return org.apache.lucene.util.IOUtils.spins(dataDirPath.toAbsolutePath()); @@ -1190,7 +1191,11 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab // default to spinning return true; } - }, true, "spins", Category.CORE.toString(), "fs"); + }, getMetricTag(), true, "spins", Category.CORE.toString(), "fs"); + } + + public String getMetricTag() { + return metricTag; } private void checkVersionFieldExistsInSchema(IndexSchema schema, CoreDescriptor coreDescriptor) { http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java ---------------------------------------------------------------------- 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 edded0e..38ffc99 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java +++ b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java @@ -83,7 +83,7 @@ public interface SolrInfoBean { /** Register a metric name that this component reports. This method is called by various * metric registration methods in {@link org.apache.solr.metrics.SolrMetricManager} in order * to capture what metric names are reported from this component (which in turn is called - * from {@link org.apache.solr.metrics.SolrMetricProducer#initializeMetrics(SolrMetricManager, String, String)}). + * from {@link org.apache.solr.metrics.SolrMetricProducer#initializeMetrics(SolrMetricManager, String, String, String)}). *

Default implementation registers all metrics added by a component. Implementations may * override this to avoid reporting some or all metrics returned by {@link #getMetricsSnapshot()}

*/ http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java ---------------------------------------------------------------------- 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 43ec573..1707c80 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -837,21 +837,21 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { - super.initializeMetrics(manager, registry, scope); - - manager.registerGauge(this, registry, () -> core != null ? NumberUtils.readableSize(core.getIndexSize()) : "", true, - "indexSize", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? getIndexVersion().toString() : ""), true, - "indexVersion", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> (core != null && !core.isClosed() ? getIndexVersion().generation : 0), true, - GENERATION, getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> core != null ? core.getIndexDir() : "", true, - "indexPath", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> isMaster, true, - "isMaster", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> isSlave, true, - "isSlave", getCategory().toString(), scope); + public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { + super.initializeMetrics(manager, registry, tag, scope); + + manager.registerGauge(this, registry, () -> core != null ? 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.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); final MetricsMap fetcherMap = new MetricsMap((detailed, map) -> { IndexFetcher fetcher = currentIndexFetcher; if (fetcher != null) { @@ -880,13 +880,13 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw addVal(map, IndexFetcher.CONF_FILES_REPLICATED, props, String.class); } }); - manager.registerGauge(this, registry, fetcherMap, true, "fetcher", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> isMaster && includeConfFiles != null ? includeConfFiles : "", true, - "confFilesToReplicate", getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> isMaster ? getReplicateAfterStrings() : Collections.emptyList(), true, - REPLICATE_AFTER, getCategory().toString(), scope); - manager.registerGauge(this, registry, () -> isMaster && replicationEnabled.get(), true, - "replicationEnabled", getCategory().toString(), scope); + 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.emptyList(), + tag, true, REPLICATE_AFTER, getCategory().toString(), scope); + manager.registerGauge(this, registry, () -> isMaster && replicationEnabled.get(), + tag, true, "replicationEnabled", getCategory().toString(), scope); } /** http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java ---------------------------------------------------------------------- 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 808e557..d4cfd99 100644 --- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java +++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java @@ -80,6 +80,8 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo private Set metricNames = ConcurrentHashMap.newKeySet(); private MetricRegistry registry; + protected String registryName; + protected SolrMetricManager metricManager; @SuppressForbidden(reason = "Need currentTimeMillis, used only for stats output") @@ -144,8 +146,10 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, final String scope) { - registry = manager.registry(registryName); + 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); @@ -153,10 +157,10 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo requests = manager.counter(this, registryName, "requests", getCategory().toString(), scope); MetricsMap metricsMap = new MetricsMap((detail, map) -> shardPurposes.forEach((k, v) -> map.put(k, v.getCount()))); - manager.register(this, registryName, metricsMap, true, "shardRequests", getCategory().toString(), scope); + 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, true, "handlerStart", getCategory().toString(), scope); + manager.registerGauge(this, registryName, () -> handlerStart, tag, true, "handlerStart", getCategory().toString(), scope); } public static SolrParams getSolrParamsFromNamedList(NamedList args, String key) { http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java ---------------------------------------------------------------------- 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 40099ea..8932c21 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 @@ -119,8 +119,8 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { - super.initializeMetrics(manager, registryName, scope); + 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")); } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java index 6bfd36a..8cff025 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java @@ -105,6 +105,8 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org. private HttpClientMetricNameStrategy metricNameStrategy; + private String metricTag; + protected final Random r = new Random(); private final ReplicaListTransformer shufflingReplicaListTransformer = new ShufflingReplicaListTransformer(r); @@ -398,10 +400,11 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org. } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { + this.metricTag = tag; String expandedScope = SolrMetricManager.mkName(scope, SolrInfoBean.Category.QUERY.name()); - clientConnectionManager.initializeMetrics(manager, registry, expandedScope); - httpRequestExecutor.initializeMetrics(manager, registry, expandedScope); + clientConnectionManager.initializeMetrics(manager, registry, tag, expandedScope); + httpRequestExecutor.initializeMetrics(manager, registry, tag, expandedScope); commExecutor = MetricUtils.instrumentedExecutorService(commExecutor, null, manager.registry(registry), SolrMetricManager.mkName("httpShardExecutor", expandedScope, "threadPool")); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java index 78a62fa..d923306 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SearchComponent.java @@ -99,7 +99,7 @@ public abstract class SearchComponent implements SolrInfoBean, NamedListInitiali { // By default do nothing } - + //////////////////////// SolrInfoMBeans methods ////////////////////// @Override http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/handler/component/SuggestComponent.java ---------------------------------------------------------------------- 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 4ca6ce4..cba7e93 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 @@ -87,6 +87,9 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware, @SuppressWarnings("unchecked") protected NamedList initParams; + + protected SolrMetricManager metricManager; + protected String registryName; /** * Key is the dictionary name used in SolrConfig, value is the corresponding {@link SolrSuggester} @@ -348,16 +351,18 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware, } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + 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(), true, "totalSizeInBytes", getCategory().toString(), scope); + manager.registerGauge(this, registryName, () -> ramBytesUsed(), tag, true, "totalSizeInBytes", getCategory().toString(), scope); MetricsMap suggestersMap = new MetricsMap((detailed, map) -> { for (Map.Entry entry : suggesters.entrySet()) { SolrSuggester suggester = entry.getValue(); map.put(entry.getKey(), suggester.toString()); } }); - manager.registerGauge(this, registryName, suggestersMap, true, "suggesters", getCategory().toString(), scope); + manager.registerGauge(this, registryName, suggestersMap, tag, true, "suggesters", getCategory().toString(), scope); } @Override http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java index 2620ec7e..bed4a1d 100644 --- a/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java +++ b/solr/core/src/java/org/apache/solr/highlight/HighlightingPluginBase.java @@ -37,6 +37,8 @@ public abstract class HighlightingPluginBase implements SolrInfoBean, SolrMetric protected SolrParams defaults; protected Set metricNames = ConcurrentHashMap.newKeySet(1); protected MetricRegistry registry; + protected SolrMetricManager metricManager; + protected String registryName; public void init(NamedList args) { if( args != null ) { @@ -74,7 +76,9 @@ public abstract class HighlightingPluginBase implements SolrInfoBean, SolrMetric } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.registryName = registryName; + this.metricManager = manager; registry = manager.registry(registryName); numRequests = manager.counter(this, registryName, "requests", getCategory().toString(), scope); } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java index 74c9596..c57a704 100644 --- a/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java +++ b/solr/core/src/java/org/apache/solr/metrics/SolrCoreMetricManager.java @@ -56,7 +56,7 @@ public class SolrCoreMetricManager implements Closeable { */ public SolrCoreMetricManager(SolrCore core) { this.core = core; - this.tag = String.valueOf(core.hashCode()); + this.tag = core.getMetricTag(); this.metricManager = core.getCoreContainer().getMetricManager(); initCloudMode(); registryName = createRegistryName(cloudMode, collectionName, shardName, replicaName, core.getName()); @@ -127,7 +127,7 @@ public class SolrCoreMetricManager implements Closeable { throw new IllegalArgumentException("registerMetricProducer() called with illegal arguments: " + "scope = " + scope + ", producer = " + producer); } - producer.initializeMetrics(metricManager, getRegistryName(), scope); + producer.initializeMetrics(metricManager, getRegistryName(), tag, scope); } /** @@ -142,7 +142,7 @@ public class SolrCoreMetricManager implements Closeable { } /** - * Closes reporters specific to this core. + * Closes reporters specific to this core and unregisters gauges with this core's instance tag. */ @Override public void close() throws IOException { @@ -150,6 +150,7 @@ public class SolrCoreMetricManager implements Closeable { if (getLeaderRegistryName() != null) { metricManager.closeReporters(getLeaderRegistryName(), tag); } + metricManager.unregisterGauges(getRegistryName(), tag); } public SolrCore getCore() { http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java index 4223675..d5b8864 100644 --- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java +++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java @@ -31,6 +31,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; @@ -645,7 +646,7 @@ public class SolrMetricManager { * using dotted notation * @param metricPath (optional) additional top-most metric name path elements */ - public void register(SolrInfoBean info, String registry, Metric metric, boolean force, String metricName, String... metricPath) { + public void registerMetric(SolrInfoBean info, String registry, Metric metric, boolean force, String metricName, String... metricPath) { MetricRegistry metricRegistry = registry(registry); String fullName = mkName(metricName, metricPath); if (info != null) { @@ -659,8 +660,56 @@ public class SolrMetricManager { } } - public void registerGauge(SolrInfoBean info, String registry, Gauge gauge, boolean force, String metricName, String... metricPath) { - register(info, registry, gauge, force, metricName, metricPath); + /** + * This is a wrapper for {@link Gauge} metrics, which are usually implemented as + * lambdas that often keep a reference to their parent instance. In order to make sure that + * all such metrics are removed when their parent instance is removed / closed the + * metric is associated with an instance tag, which can be used then to remove + * wrappers with the matching tag using {@link #unregisterGauges(String, String)}. + */ + public static class GaugeWrapper implements Gauge { + private final Gauge gauge; + private final String tag; + + public GaugeWrapper(Gauge gauge, String tag) { + this.gauge = gauge; + this.tag = tag; + } + + @Override + public T getValue() { + return gauge.getValue(); + } + + public String getTag() { + return tag; + } + + public Gauge getGauge() { + return gauge; + } + } + + public void registerGauge(SolrInfoBean info, String registry, Gauge gauge, String tag, boolean force, String metricName, String... metricPath) { + registerMetric(info, registry, new GaugeWrapper(gauge, tag), force, metricName, metricPath); + } + + public int unregisterGauges(String registryName, String tag) { + if (tag == null) { + return 0; + } + MetricRegistry registry = registry(registryName); + AtomicInteger removed = new AtomicInteger(); + registry.removeMatching((name, metric) -> { + if (metric instanceof GaugeWrapper && + tag.equals(((GaugeWrapper)metric).getTag())) { + removed.incrementAndGet(); + return true; + } else { + return false; + } + }); + return removed.get(); } /** @@ -1110,8 +1159,7 @@ public class SolrMetricManager { attrs, initArgs); for (PluginInfo info : infos) { try { - loadReporter(registryName, core, info, - String.valueOf(core.hashCode())); + loadReporter(registryName, core, info, core.getMetricTag()); } catch (Exception e) { log.warn("Could not load shard reporter, pluginInfo=" + info, e); } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java ---------------------------------------------------------------------- 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 73abab1..ef78b3c 100644 --- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java +++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java @@ -17,16 +17,39 @@ package org.apache.solr.metrics; /** - * Used by objects that expose metrics through {@link SolrCoreMetricManager}. + * Used by objects that expose metrics through {@link SolrMetricManager}. */ public interface SolrMetricProducer { /** - * Initializes metrics specific to this producer + * Initializes metrics specific to this producer. + *

Note: for back-compatibility this method by default calls {@link #initializeMetrics(SolrMetricManager, String, String)}.

* @param manager an instance of {@link SolrMetricManager} * @param registry registry name where metrics are registered + * @param tag symbolic tag that represents a group of related instances that + * have the same life-cycle. Parent component can use the tag when + * calling {@link SolrMetricManager#unregisterGauges(String, String)} + * to unregister metrics created by this instance of the producer. * @param scope scope of the metrics (eg. handler name) to separate metrics of * instances of the same component executing in different contexts */ - void initializeMetrics(SolrMetricManager manager, String registry, String scope); + default void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { + initializeMetrics(manager, registry, scope); + } + + /** + * Initializes metrics specific to this producer. + *

Note: for back-compatibility this method has a default no-op implementation.

+ * @param manager an instance of {@link SolrMetricManager} + * @param registry registry name where metrics are registered + * @param scope scope of the metrics (eg. handler name) to separate metrics of + * instances of the same component executing in different contexts + * @deprecated this method doesn't provide enough context to properly manage + * life-cycle of some metrics (see SOLR-11882). + * Instead use {@link #initializeMetrics(SolrMetricManager, String, String, String)}. + */ + @Deprecated + default void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + + } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java index 8d36cef..7055f52 100644 --- a/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java +++ b/solr/core/src/java/org/apache/solr/metrics/reporters/solr/SolrReporter.java @@ -303,7 +303,7 @@ public class SolrReporter extends ScheduledReporter { String reporterId, TimeUnit rateUnit, TimeUnit durationUnit, SolrParams params, boolean skipHistograms, boolean skipAggregateValues, boolean cloudClient, boolean compact) { - super(null, "solr-reporter", MetricFilter.ALL, rateUnit, durationUnit); + super(null, "solr-reporter", MetricFilter.ALL, rateUnit, durationUnit, null, true); this.metricManager = metricManager; this.urlProvider = urlProvider; this.reporterId = reporterId; http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/search/FastLRUCache.java ---------------------------------------------------------------------- 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 a73a65a..75fef10 100644 --- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java +++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java @@ -62,6 +62,8 @@ public class FastLRUCache extends SolrCacheBase implements SolrCache private MetricsMap cacheMap; private Set metricNames = ConcurrentHashMap.newKeySet(); private MetricRegistry registry; + private SolrMetricManager metricManager; + private String registryName; @Override public Object init(Map args, Object persistence, CacheRegenerator regenerator) { @@ -226,7 +228,9 @@ public class FastLRUCache extends SolrCacheBase implements SolrCache } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.metricManager = manager; + this.registryName = registryName; registry = manager.registry(registryName); cacheMap = new MetricsMap((detailed, map) -> { if (cache != null) { @@ -277,9 +281,10 @@ public class FastLRUCache extends SolrCacheBase implements SolrCache } } }); - manager.registerGauge(this, registryName, cacheMap, true, scope, getCategory().toString()); + manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString()); } + // for unit tests only MetricsMap getMetricsMap() { return cacheMap; http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/search/LFUCache.java ---------------------------------------------------------------------- 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 7d41ae3..e593c1b 100644 --- a/solr/core/src/java/org/apache/solr/search/LFUCache.java +++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java @@ -67,6 +67,8 @@ public class LFUCache implements SolrCache { private MetricsMap cacheMap; private Set metricNames = ConcurrentHashMap.newKeySet(); private MetricRegistry registry; + private SolrMetricManager metricManager; + private String registryName; @Override public Object init(Map args, Object persistence, CacheRegenerator regenerator) { @@ -234,7 +236,9 @@ public class LFUCache implements SolrCache { } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.metricManager = manager; + this.registryName = registryName; registry = manager.registry(registryName); cacheMap = new MetricsMap((detailed, map) -> { if (cache != null) { @@ -288,7 +292,7 @@ public class LFUCache implements SolrCache { } }); - manager.registerGauge(this, registryName, cacheMap, true, scope, getCategory().toString()); + manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString()); } // for unit tests only http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/search/LRUCache.java ---------------------------------------------------------------------- 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 af05dad..8f53b45 100644 --- a/solr/core/src/java/org/apache/solr/search/LRUCache.java +++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java @@ -89,6 +89,8 @@ public class LRUCache extends SolrCacheBase implements SolrCache, Acco private MetricsMap cacheMap; private Set metricNames = ConcurrentHashMap.newKeySet(); private MetricRegistry registry; + private SolrMetricManager metricManager; + private String registryName; private long maxRamBytes = Long.MAX_VALUE; // The synchronization used for the map will be used to update this, @@ -306,9 +308,9 @@ public class LRUCache extends SolrCacheBase implements SolrCache, Acco warmupTime = TimeUnit.MILLISECONDS.convert(System.nanoTime() - warmingStartTime, TimeUnit.NANOSECONDS); } - @Override public void close() { + } @@ -331,7 +333,9 @@ public class LRUCache extends SolrCacheBase implements SolrCache, Acco } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.metricManager = manager; + this.registryName = registryName; registry = manager.registry(registryName); cacheMap = new MetricsMap((detailed, res) -> { synchronized (map) { @@ -360,7 +364,7 @@ public class LRUCache extends SolrCacheBase implements SolrCache, Acco res.put("cumulative_evictionsRamUsage", stats.evictionsRamUsage.longValue()); } }); - manager.registerGauge(this, registryName, cacheMap, true, scope, getCategory().toString()); + manager.registerGauge(this, registryName, cacheMap, tag, true, scope, getCategory().toString()); } // for unit tests only http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java ---------------------------------------------------------------------- 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 82787d1..b2647cd 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java +++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java @@ -56,7 +56,7 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer { } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { registry = manager.registry(registryName); MetricsMap metricsMap = new MetricsMap((detailed, map) -> { if (detailed && !disableEntryList && !disableJmxEntryList) { @@ -72,6 +72,6 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer { map.put("entries_count", UninvertingReader.getUninvertedStatsSize()); } }); - manager.register(this, registryName, metricsMap, true, "fieldCache", Category.CACHE.toString(), scope); + manager.registerGauge(this, registryName, metricsMap, tag, true, "fieldCache", Category.CACHE.toString(), scope); } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java ---------------------------------------------------------------------- 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 e989732..14927ca 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -138,6 +138,8 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI private boolean releaseDirectory; private Set metricNames = ConcurrentHashMap.newKeySet(); + private SolrMetricManager metricManager; + private String registryName; private static DirectoryReader getReader(SolrCore core, SolrIndexConfig config, DirectoryFactory directoryFactory, String path) throws IOException { @@ -439,12 +441,12 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI cache.setState(SolrCache.State.LIVE); infoRegistry.put(cache.name(), cache); } - SolrMetricManager manager = core.getCoreContainer().getMetricManager(); - String registry = core.getCoreMetricManager().getRegistryName(); + metricManager = core.getCoreContainer().getMetricManager(); + registryName = core.getCoreMetricManager().getRegistryName(); for (SolrCache cache : cacheList) { - cache.initializeMetrics(manager, registry, SolrMetricManager.mkName(cache.name(), STATISTICS_KEY)); + cache.initializeMetrics(metricManager, registryName, core.getMetricTag(), SolrMetricManager.mkName(cache.name(), STATISTICS_KEY)); } - initializeMetrics(manager, registry, STATISTICS_KEY); + initializeMetrics(metricManager, registryName, core.getMetricTag(), STATISTICS_KEY); registerTime = new Date(); } @@ -2249,20 +2251,21 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { - - manager.registerGauge(this, registry, () -> name, true, "searcherName", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> cachingEnabled, true, "caching", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> openTime, true, "openedAt", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> warmupTime, true, "warmupTime", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> registerTime, true, "registeredAt", Category.SEARCHER.toString(), scope); + 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); // reader stats - manager.registerGauge(this, registry, () -> reader.numDocs(), true, "numDocs", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> reader.maxDoc(), true, "maxDoc", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> reader.maxDoc() - reader.numDocs(), true, "deletedDocs", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> reader.toString(), true, "reader", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> reader.directory().toString(), true, "readerDir", Category.SEARCHER.toString(), scope); - manager.registerGauge(this, registry, () -> reader.getVersion(), true, "indexVersion", Category.SEARCHER.toString(), scope); + 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); } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java ---------------------------------------------------------------------- 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 a70e2b8..fc0c28f 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -102,6 +102,10 @@ public class SolrDispatchFilter extends BaseSolrFilter { private Boolean testMode = null; private boolean isV2Enabled = !"true".equals(System.getProperty("disable.v2.api", "false")); + private final String metricTag = Integer.toHexString(hashCode()); + private SolrMetricManager metricManager; + private String registryName; + /** * Enum to define action that needs to be processed. * PASSTHROUGH: Pass through to Restlet via webapp. @@ -204,16 +208,16 @@ public class SolrDispatchFilter extends BaseSolrFilter { } private void setupJvmMetrics(CoreContainer coresInit) { - SolrMetricManager metricManager = coresInit.getMetricManager(); + metricManager = coresInit.getMetricManager(); + registryName = SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm); final Set hiddenSysProps = coresInit.getConfig().getMetricsConfig().getHiddenSysProps(); try { - String registry = SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm); - metricManager.registerAll(registry, new AltBufferPoolMetricSet(), true, "buffers"); - metricManager.registerAll(registry, new ClassLoadingGaugeSet(), true, "classes"); - metricManager.registerAll(registry, new OperatingSystemMetricSet(), true, "os"); - metricManager.registerAll(registry, new GarbageCollectorMetricSet(), true, "gc"); - metricManager.registerAll(registry, new MemoryUsageGaugeSet(), true, "memory"); - metricManager.registerAll(registry, new ThreadStatesGaugeSet(), true, "threads"); // todo should we use CachedThreadStatesGaugeSet instead? + metricManager.registerAll(registryName, new AltBufferPoolMetricSet(), true, "buffers"); + metricManager.registerAll(registryName, new ClassLoadingGaugeSet(), true, "classes"); + metricManager.registerAll(registryName, new OperatingSystemMetricSet(), true, "os"); + metricManager.registerAll(registryName, new GarbageCollectorMetricSet(), true, "gc"); + metricManager.registerAll(registryName, new MemoryUsageGaugeSet(), true, "memory"); + metricManager.registerAll(registryName, new ThreadStatesGaugeSet(), true, "threads"); // todo should we use CachedThreadStatesGaugeSet instead? MetricsMap sysprops = new MetricsMap((detailed, map) -> { System.getProperties().forEach((k, v) -> { if (!hiddenSysProps.contains(k)) { @@ -221,7 +225,7 @@ public class SolrDispatchFilter extends BaseSolrFilter { } }); }); - metricManager.registerGauge(null, registry, sysprops, true, "properties", "system"); + metricManager.registerGauge(null, registryName, sysprops, metricTag, true, "properties", "system"); } catch (Exception e) { log.warn("Error registering JVM metrics", e); } @@ -317,6 +321,10 @@ public class SolrDispatchFilter extends BaseSolrFilter { SolrRequestParsers.fileCleaningTracker = null; } + if (metricManager != null) { + metricManager.unregisterGauges(registryName, metricTag); + } + if (cores != null) { try { cores.shutdown(); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java ---------------------------------------------------------------------- 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 cc7ae4b..6d9e9ea 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 @@ -56,10 +56,14 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr private MetricsMap metricsMap; private MetricRegistry registry; private Set metricNames = ConcurrentHashMap.newKeySet(); + private SolrMetricManager metricManager; + private String registryName; private long previous = System.nanoTime(); @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.metricManager = manager; + this.registryName = registryName; registry = manager.registry(registryName); metricsMap = new MetricsMap((detailed, map) -> { long now = System.nanoTime(); @@ -104,7 +108,7 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr previous = now; }); - manager.registerGauge(this, registryName, metricsMap, true, getName(), getCategory().toString(), scope); + manager.registerGauge(this, registryName, metricsMap, tag, true, getName(), getCategory().toString(), scope); } private float getPerSecond(long value, double seconds) { http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/store/hdfs/HdfsLocalityReporter.java ---------------------------------------------------------------------- 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 3474d3c..d10216b 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 @@ -52,6 +52,8 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer { private final Set metricNames = ConcurrentHashMap.newKeySet(); private MetricRegistry registry; + private SolrMetricManager metricManager; + private String registryName; public HdfsLocalityReporter() { cache = new ConcurrentHashMap<>(); @@ -94,7 +96,9 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer { * Provide statistics on HDFS block locality, both in terms of bytes and block counts. */ @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { + this.metricManager = manager; + this.registryName = registryName; registry = manager.registry(registryName); MetricsMap metricsMap = new MetricsMap((detailed, map) -> { long totalBytes = 0; @@ -145,7 +149,7 @@ public class HdfsLocalityReporter implements SolrInfoBean, SolrMetricProducer { map.put(LOCALITY_BLOCKS_RATIO, localCount / (double) totalCount); } }); - manager.registerGauge(this, registryName, metricsMap, true, "hdfsLocality", getCategory().toString(), scope); + manager.registerGauge(this, registryName, metricsMap, tag, true, "hdfsLocality", getCategory().toString(), scope); } /** http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java ---------------------------------------------------------------------- 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 d51c970..75453e1 100644 --- a/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java +++ b/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java @@ -91,6 +91,8 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState LongAdder numDocsPending = new LongAdder(); LongAdder numErrors = new LongAdder(); Meter numErrorsCumulative; + SolrMetricManager metricManager; + String registryName; // tracks when auto-commit should occur protected final CommitTracker commitTracker; @@ -161,25 +163,27 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + 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(), true, "autoCommits", getCategory().toString(), scope); - manager.registerGauge(this, registryName, () -> softCommitTracker.getCommitCount(), true, "softAutoCommits", 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); if (commitTracker.getDocsUpperBound() > 0) { - manager.registerGauge(this, registryName, () -> commitTracker.getDocsUpperBound(), true, "autoCommitMaxDocs", + manager.registerGauge(this, registryName, () -> commitTracker.getDocsUpperBound(), tag, true, "autoCommitMaxDocs", getCategory().toString(), scope); } if (commitTracker.getTimeUpperBound() > 0) { - manager.registerGauge(this, registryName, () -> "" + commitTracker.getTimeUpperBound() + "ms", true, "autoCommitMaxTime", + manager.registerGauge(this, registryName, () -> "" + commitTracker.getTimeUpperBound() + "ms", tag, true, "autoCommitMaxTime", getCategory().toString(), scope); } if (softCommitTracker.getDocsUpperBound() > 0) { - manager.registerGauge(this, registryName, () -> softCommitTracker.getDocsUpperBound(), true, "softAutoCommitMaxDocs", + manager.registerGauge(this, registryName, () -> softCommitTracker.getDocsUpperBound(), tag, true, "softAutoCommitMaxDocs", getCategory().toString(), scope); } if (softCommitTracker.getTimeUpperBound() > 0) { - manager.registerGauge(this, registryName, () -> "" + softCommitTracker.getTimeUpperBound() + "ms", true, "softAutoCommitMaxTime", + manager.registerGauge(this, registryName, () -> "" + softCommitTracker.getTimeUpperBound() + "ms", tag, true, "softAutoCommitMaxTime", getCategory().toString(), scope); } optimizeCommands = manager.meter(this, registryName, "optimizes", getCategory().toString(), scope); @@ -187,11 +191,11 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState 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(), true, "docsPending", getCategory().toString(), scope); - manager.registerGauge(this, registryName, () -> addCommands.longValue(), true, "adds", getCategory().toString(), scope); - manager.registerGauge(this, registryName, () -> deleteByIdCommands.longValue(), true, "deletesById", getCategory().toString(), scope); - manager.registerGauge(this, registryName, () -> deleteByQueryCommands.longValue(), true, "deletesByQuery", getCategory().toString(), scope); - manager.registerGauge(this, registryName, () -> numErrors.longValue(), true, "errors", 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); addCommandsCumulative = manager.meter(this, registryName, "cumulativeAdds", getCategory().toString(), scope); deleteByIdCommandsCumulative = manager.meter(this, registryName, "cumulativeDeletesById", getCategory().toString(), scope); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/update/PeerSync.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/update/PeerSync.java b/solr/core/src/java/org/apache/solr/update/PeerSync.java index 426e0f7..10b3ea1 100644 --- a/solr/core/src/java/org/apache/solr/update/PeerSync.java +++ b/solr/core/src/java/org/apache/solr/update/PeerSync.java @@ -171,7 +171,7 @@ public class PeerSync implements SolrMetricProducer { public static final String METRIC_SCOPE = "peerSync"; @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { syncTime = manager.timer(null, registry, "time", scope, METRIC_SCOPE); syncErrors = manager.counter(null, registry, "errors", scope, METRIC_SCOPE); syncSkipped = manager.counter(null, registry, "skipped", scope, METRIC_SCOPE); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java ---------------------------------------------------------------------- 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 049d228..fda5fa5 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java +++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java @@ -86,6 +86,9 @@ 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; + public static SolrIndexWriter create(SolrCore core, String name, String path, DirectoryFactory directoryFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, Codec codec) throws IOException { SolrIndexWriter w = null; @@ -113,6 +116,8 @@ public class SolrIndexWriter extends IndexWriter { // no metrics mergeTotals = false; mergeDetails = false; + metricManager = null; + registryName = null; } private SolrIndexWriter(SolrCore core, String name, String path, Directory directory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, Codec codec) throws IOException { @@ -126,8 +131,8 @@ public class SolrIndexWriter extends IndexWriter { infoStream = getConfig().getInfoStream(); this.directory = directory; numOpens.incrementAndGet(); - SolrMetricManager metricManager = core.getCoreContainer().getMetricManager(); - String registry = core.getCoreMetricManager().getRegistryName(); + metricManager = core.getCoreContainer().getMetricManager(); + registryName = core.getCoreMetricManager().getRegistryName(); if (config.metricsInfo != null && config.metricsInfo.initArgs != null) { Object v = config.metricsInfo.initArgs.get("majorMergeDocs"); if (v != null) { @@ -151,20 +156,21 @@ public class SolrIndexWriter extends IndexWriter { } if (mergeDetails) { mergeTotals = true; // override - majorMergedDocs = metricManager.meter(null, registry, "docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); - majorDeletedDocs = metricManager.meter(null, registry, "deletedDocs", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); + majorMergedDocs = metricManager.meter(null, registryName, "docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); + majorDeletedDocs = metricManager.meter(null, registryName, "deletedDocs", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); } if (mergeTotals) { - minorMerge = metricManager.timer(null, registry, "minor", SolrInfoBean.Category.INDEX.toString(), "merge"); - majorMerge = metricManager.timer(null, registry, "major", SolrInfoBean.Category.INDEX.toString(), "merge"); - mergeErrors = metricManager.counter(null, registry, "errors", SolrInfoBean.Category.INDEX.toString(), "merge"); - metricManager.registerGauge(null, registry, () -> runningMajorMerges.get(), true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); - metricManager.registerGauge(null, registry, () -> runningMinorMerges.get(), true, "running", SolrInfoBean.Category.INDEX.toString(), "merge", "minor"); - metricManager.registerGauge(null, registry, () -> runningMajorMergesDocs.get(), true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); - metricManager.registerGauge(null, registry, () -> runningMinorMergesDocs.get(), true, "running.docs", SolrInfoBean.Category.INDEX.toString(), "merge", "minor"); - metricManager.registerGauge(null, registry, () -> runningMajorMergesSegments.get(), true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "major"); - metricManager.registerGauge(null, registry, () -> runningMinorMergesSegments.get(), true, "running.segments", SolrInfoBean.Category.INDEX.toString(), "merge", "minor"); - flushMeter = metricManager.meter(null, registry, "flush", SolrInfoBean.Category.INDEX.toString()); + 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"); + 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()); } } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/update/UpdateLog.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java b/solr/core/src/java/org/apache/solr/update/UpdateLog.java index 2d6fd98..4ca4bf2 100644 --- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java +++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java @@ -245,6 +245,8 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer { protected Meter applyingBufferedOpsMeter; protected Meter replayOpsMeter; protected Meter copyOverOldUpdatesMeter; + protected SolrMetricManager metricManager; + protected String registryName; public static class LogPtr { final long pointer; @@ -416,7 +418,9 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer { } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { + this.metricManager = manager; + this.registryName = registry; bufferedOpsGauge = () -> { if (tlog == null) { return 0; @@ -431,13 +435,13 @@ public class UpdateLog implements PluginInfoInitialized, SolrMetricProducer { } }; - manager.registerGauge(null, registry, bufferedOpsGauge, true, "ops", scope, "buffered"); - manager.registerGauge(null, registry, () -> logs.size(), true, "logs", scope, "replay", "remaining"); - manager.registerGauge(null, registry, () -> getTotalLogsSize(), true, "bytes", scope, "replay", "remaining"); + manager.registerGauge(null, registry, bufferedOpsGauge, tag, true, "ops", scope, "buffered"); + manager.registerGauge(null, registry, () -> logs.size(), tag, true, "logs", scope, "replay", "remaining"); + manager.registerGauge(null, registry, () -> getTotalLogsSize(), tag, true, "bytes", scope, "replay", "remaining"); applyingBufferedOpsMeter = manager.meter(null, registry, "ops", scope, "applyingBuffered"); replayOpsMeter = manager.meter(null, registry, "ops", scope, "replay"); copyOverOldUpdatesMeter = manager.meter(null, registry, "ops", scope, "copyOverOldUpdates"); - manager.registerGauge(null, registry, () -> state.getValue(), true, "state", scope); + manager.registerGauge(null, registry, () -> state.getValue(), tag, true, "state", scope); } /** http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java ---------------------------------------------------------------------- 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 4ad5106..fa752a0 100644 --- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java +++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java @@ -117,11 +117,11 @@ public class UpdateShardHandler implements SolrMetricProducer, SolrInfoBean { } @Override - public void initializeMetrics(SolrMetricManager manager, String registryName, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registryName, String tag, String scope) { registry = manager.registry(registryName); String expandedScope = SolrMetricManager.mkName(scope, getCategory().name()); - clientConnectionManager.initializeMetrics(manager, registryName, expandedScope); - httpRequestExecutor.initializeMetrics(manager, registryName, expandedScope); + clientConnectionManager.initializeMetrics(manager, registryName, tag, expandedScope); + httpRequestExecutor.initializeMetrics(manager, registryName, tag, expandedScope); updateExecutor = MetricUtils.instrumentedExecutorService(updateExecutor, this, registry, SolrMetricManager.mkName("updateExecutor", expandedScope, "threadPool")); recoveryExecutor = MetricUtils.instrumentedExecutorService(recoveryExecutor, this, registry, http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/483914b6/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java index bd8d368..246777c 100644 --- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java +++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpRequestExecutor.java @@ -92,6 +92,8 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme } protected MetricRegistry metricsRegistry; + protected SolrMetricManager metricManager; + protected String registryName; protected String scope; protected HttpClientMetricNameStrategy nameStrategy; @@ -128,9 +130,10 @@ public class InstrumentedHttpRequestExecutor extends HttpRequestExecutor impleme } @Override - public void initializeMetrics(SolrMetricManager manager, String registry, String scope) { + public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) { + this.metricManager = manager; + this.registryName = registry; this.metricsRegistry = manager.registry(registry); this.scope = scope; } - }