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/16 16:10:11 UTC

[lucene-solr] branch jira/solr-13677-final updated (44cfc02 -> b541fa3)

This is an automated email from the ASF dual-hosted git repository.

ab pushed a change to branch jira/solr-13677-final
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


    from 44cfc02  Compilation errors.
     add 81f598c  LUCENE-8920: Disable direct addressing of arcs. (#950)
     add e0b20f0  LUCENE-9001: Fix race condition in SetOnce (#931)
     add 0478624  LUCENE-8979: Code Cleanup: Use entryset for map iteration wherever possible. - part 2
     add 0efd5e3  LUCENE-8979: Move CHANGES entry to 8.4.
     add 5e286e4  LUCENE-9001: Add CHANGES entry.
     add e7e6cfa  LUCENE-8994: Code Cleanup - Pass values to list constructor instead of empty constructor followed by addAll(). (#919)
     add a40c0a2  LUCENE-8994: Move CHANGES entry to 8.4.
     add a4ac3fe  LUCENE-9003: Compute numDocs() lazily. (#939)
     add 68a3886  LUCENE-8746: Refactor EdgeTree  (#878)
     add 1d97e25  LUCENE-8928: Check that point is inside an edge bounding box when checking if the point belongs to the edge
     add 8ad7594  Ref Guide: Fix errant & empty style block throwing errors
     add 64fb42c  SOLR-13665: Added missing netty dependencies to solrJ (#938)
     add b8648c6  SOLR-13793: Limiting number of forwards to total replicas in collection to avoid deadly forwarding loops
     add e2b160b  SOLR-13834: ZkController#getSolrCloudManager() now uses the same ZkStateReader instance instead of instantiating a new one
     add afcf3e2  LUCENE-8746: Disable testRandomLineEncoding for now.
     add 3deff52  Ref Guide: Upgrade Notes for 8.2 (neglected to do earlier)
     add 96cf2d1  Ref Guide: first pass at 8.3 upgrade notes
     add 8dd2ab5  Ref Guide: fix headline case, e.g & i.e, random spaces
     add 939b336  SOLR-13846: workaround - elliminate use of problematic PreemptiveBasicAuthClientBuilderFactory in tests that don't need it
     add 39fcd90  LUCENE-8746: Call relate line with points in the same order as they come from the original tessellation.
     add f7f6a37  SOLR-13849: Ignore events created by running triggers.
     new fb1218a  Merge branch 'master' into jira/solr-13677-final
     new b541fa3  SOLR-13677: API refactoring, cleanup.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lucene/CHANGES.txt                                 |  22 +-
 .../analysis/query/QueryAutoStopWordAnalyzer.java  |   8 +-
 .../analysis/ja/dict/TokenInfoDictionary$fst.dat   | Bin 1698570 -> 1698570 bytes
 .../analysis/ko/dict/TokenInfoDictionary$fst.dat   | Bin 5641400 -> 5640903 bytes
 .../lucene/benchmark/byTask/utils/Config.java      |  19 +-
 .../blocktreeords/OrdsBlockTreeTermsReader.java    |   3 +-
 .../codecs/bloom/BloomFilteringPostingsFormat.java |   3 +-
 .../lucene/codecs/memory/FSTOrdTermsReader.java    |   3 +-
 .../lucene/codecs/memory/FSTTermsReader.java       |   3 +-
 .../codecs/blocktree/BlockTreeTermsReader.java     |   3 +-
 .../LatLonDocValuesPointInPolygonQuery.java        |   5 +-
 .../lucene/document/LatLonPointInPolygonQuery.java |  21 +-
 .../java/org/apache/lucene/geo/Component2D.java    |  96 ++++
 .../java/org/apache/lucene/geo/ComponentTree.java  | 206 +++++++++
 .../src/java/org/apache/lucene/geo/EdgeTree.java   | 503 ++++++++-------------
 .../org/apache/lucene/geo/GeoEncodingUtils.java    |  17 +-
 .../src/java/org/apache/lucene/geo/Polygon2D.java  | 224 +++++----
 .../apache/lucene/index/BaseCompositeReader.java   |  24 +-
 .../java/org/apache/lucene/index/IndexReader.java  |   7 +-
 .../org/apache/lucene/search/BooleanQuery.java     |  11 +-
 .../src/java/org/apache/lucene/util/SetOnce.java   |  36 +-
 .../java/org/apache/lucene/util/fst/Builder.java   |   3 -
 .../src/java/org/apache/lucene/util/fst/FST.java   | 106 +----
 .../test/org/apache/lucene/geo/TestPolygon2D.java  |  88 ++--
 .../lucene/index/TestFilterDirectoryReader.java    |  72 +++
 .../test/org/apache/lucene/util/TestSetOnce.java   |   9 +
 lucene/ivy-versions.properties                     |  12 +-
 .../monitor/MultipassTermFilteredPresearcher.java  |   4 +-
 .../lucene/monitor/TermFilteredPresearcher.java    |   4 +-
 .../builders/MultiPhraseQueryNodeBuilder.java      |  10 +-
 .../lucene/replicator/IndexReplicationHandler.java |   3 +-
 .../idversion/VersionBlockTreeTermsReader.java     |   3 +-
 .../lucene/document/LatLonShapeLineQuery.java      |   5 +-
 .../lucene/document/LatLonShapePolygonQuery.java   |   5 +-
 .../apache/lucene/document/XYShapeLineQuery.java   |  13 +-
 .../lucene/document/XYShapePolygonQuery.java       |   6 +-
 .../src/java/org/apache/lucene/geo/Line2D.java     | 134 ++++--
 .../java/org/apache/lucene/geo/XYPolygon2D.java    |  10 +-
 .../lucene/document/BaseLatLonShapeTestCase.java   |   5 +-
 .../lucene/document/BaseShapeEncodingTestCase.java |   6 +-
 .../apache/lucene/document/BaseShapeTestCase.java  |  17 +-
 .../lucene/document/BaseXYShapeTestCase.java       |   5 +-
 .../document/TestLatLonLineShapeQueries.java       |  19 +-
 .../document/TestLatLonMultiLineShapeQueries.java  |  22 +-
 .../document/TestLatLonMultiPointShapeQueries.java |  22 +-
 .../TestLatLonMultiPolygonShapeQueries.java        |  22 +-
 .../document/TestLatLonPointShapeQueries.java      |  18 +-
 .../document/TestLatLonPolygonShapeQueries.java    |  18 +-
 .../apache/lucene/document/TestLatLonShape.java    |  11 +-
 .../lucene/document/TestLatLonShapeEncoding.java   |   3 +-
 .../lucene/document/TestXYLineShapeQueries.java    |  19 +-
 .../document/TestXYMultiLineShapeQueries.java      |  22 +-
 .../document/TestXYMultiPointShapeQueries.java     |  22 +-
 .../document/TestXYMultiPolygonShapeQueries.java   |  22 +-
 .../lucene/document/TestXYPointShapeQueries.java   |  18 +-
 .../lucene/document/TestXYPolygonShapeQueries.java |  18 +-
 .../lucene/document/TestXYShapeEncoding.java       |   3 +-
 .../src/test/org/apache/lucene/geo/TestLine2D.java |  18 +-
 .../lucene/spatial3d/geom/StandardObjects.java     |   4 +-
 .../search/suggest/document/ContextQuery.java      |   6 +-
 .../dependencies/GetMavenDependenciesTask.java     |  22 +-
 solr/CHANGES.txt                                   |   9 +
 .../solr/analytics/AnalyticsRequestManager.java    |   6 +-
 .../solr/handler/dataimport/DataImportHandler.java |   6 +-
 .../solr/handler/dataimport/RegexTransformer.java  |   3 +-
 .../solr/prometheus/collector/MetricSamples.java   |   7 +-
 .../solr/response/VelocityResponseWriter.java      |   5 +-
 .../client/solrj/embedded/JettySolrRunner.java     |  10 +-
 .../apache/solr/cloud/OverseerTaskProcessor.java   |   6 +-
 .../java/org/apache/solr/cloud/ZkController.java   |   7 +-
 .../java/org/apache/solr/cloud/ZkShardTerms.java   |   5 +-
 .../solr/cloud/api/collections/CreateShardCmd.java |  10 +-
 .../cloud/api/collections/DeleteReplicaCmd.java    |   5 +-
 .../OverseerCollectionMessageHandler.java          |   8 +-
 .../api/collections/ReindexCollectionCmd.java      |   3 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |   7 +-
 .../autoscaling/sim/SimNodeStateProvider.java      |   3 +-
 .../java/org/apache/solr/core/CoreContainer.java   |  77 ++--
 .../org/apache/solr/core/HdfsDirectoryFactory.java |  14 +-
 .../src/java/org/apache/solr/core/SolrCore.java    |  70 +--
 .../src/java/org/apache/solr/core/SolrCores.java   |  11 +-
 .../apache/solr/handler/ReplicationHandler.java    |  24 +-
 .../apache/solr/handler/RequestHandlerBase.java    |  24 +-
 .../solr/handler/admin/CoreAdminHandler.java       |  14 +-
 .../handler/admin/SegmentsInfoRequestHandler.java  |   3 +-
 .../solr/handler/component/SearchHandler.java      |   3 +-
 .../solr/handler/component/SuggestComponent.java   |   6 +-
 .../solr/handler/component/TermsComponent.java     |  16 +-
 .../apache/solr/handler/loader/CSVLoaderBase.java  |   6 +-
 .../apache/solr/metrics/SolrCoreMetricManager.java |  47 +-
 .../org/apache/solr/metrics/SolrMetricManager.java |   4 +-
 .../apache/solr/metrics/SolrMetricProducer.java    |  33 +-
 .../apache/solr/metrics/SolrMetricsContext.java    |  30 +-
 .../solr/response/PHPSerializedResponseWriter.java |  11 +-
 .../src/java/org/apache/solr/rest/RestManager.java |   5 +-
 .../analysis/ManagedSynonymFilterFactory.java      |  23 +-
 .../analysis/ManagedSynonymGraphFilterFactory.java |   6 +-
 .../solr/schema/FileExchangeRateProvider.java      |   6 +-
 .../java/org/apache/solr/search/CaffeineCache.java |  16 +-
 .../java/org/apache/solr/search/FastLRUCache.java  |  14 +-
 .../src/java/org/apache/solr/search/LFUCache.java  |  13 +-
 .../src/java/org/apache/solr/search/LRUCache.java  |  11 +-
 .../org/apache/solr/search/SolrCacheHolder.java    |   4 +-
 .../org/apache/solr/search/SolrFieldCacheBean.java |  16 +-
 .../org/apache/solr/search/SolrIndexSearcher.java  |  53 ++-
 .../TopGroupsShardRequestFactory.java              |   3 +-
 .../SearchGroupShardResponseProcessor.java         |  10 +-
 .../TopGroupsShardResponseProcessor.java           |  18 +-
 .../apache/solr/security/AuthenticationPlugin.java |  24 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |  29 +-
 .../apache/solr/servlet/SolrDispatchFilter.java    |   2 +-
 .../org/apache/solr/store/blockcache/Metrics.java  |  19 +-
 .../solr/store/hdfs/HdfsLocalityReporter.java      |  20 +-
 .../org/apache/solr/update/SolrIndexWriter.java    |  38 +-
 .../org/apache/solr/update/UpdateShardHandler.java |   9 +-
 .../AddSchemaFieldsUpdateProcessorFactory.java     |  14 +-
 .../CloneFieldUpdateProcessorFactory.java          |   4 +-
 .../java/org/apache/solr/util/SimplePostTool.java  |   6 +-
 .../src/java/org/apache/solr/util/SolrCLI.java     |   3 +-
 .../java/org/apache/solr/util/SolrPluginUtils.java |   8 +-
 .../stats/InstrumentedHttpListenerFactory.java     |  15 +-
 ...rumentedPoolingHttpClientConnectionManager.java |  30 +-
 .../solr/cloud/TestQueryingOnDownCollection.java   | 151 +++++++
 .../autoscaling/sim/TestSnapshotCloudManager.java  |  10 +-
 .../solr/handler/admin/MetricsHandlerTest.java     |   8 +-
 .../solr/security/BasicAuthOnSingleNodeTest.java   |  12 +-
 solr/licenses/netty-all-4.0.52.Final.jar.sha1      |   1 -
 solr/licenses/netty-all-4.1.29.Final.jar.sha1      |   1 +
 solr/licenses/netty-buffer-4.1.29.Final.jar.sha1   |   1 +
 .../netty-buffer-LICENSE-ASL.txt}                  |   0
 ...etty-all-NOTICE.txt => netty-buffer-NOTICE.txt} |   0
 solr/licenses/netty-codec-4.1.29.Final.jar.sha1    |   1 +
 .../netty-codec-LICENSE-ASL.txt}                   |   0
 ...netty-all-NOTICE.txt => netty-codec-NOTICE.txt} |   0
 solr/licenses/netty-common-4.1.29.Final.jar.sha1   |   1 +
 .../netty-common-LICENSE-ASL.txt}                  |   0
 ...etty-all-NOTICE.txt => netty-common-NOTICE.txt} |   0
 solr/licenses/netty-handler-4.1.29.Final.jar.sha1  |   1 +
 .../netty-handler-LICENSE-ASL.txt}                 |   0
 ...tty-all-NOTICE.txt => netty-handler-NOTICE.txt} |   0
 solr/licenses/netty-resolver-4.1.29.Final.jar.sha1 |   1 +
 .../netty-resolver-LICENSE-ASL.txt}                |   0
 ...ty-all-NOTICE.txt => netty-resolver-NOTICE.txt} |   0
 .../licenses/netty-transport-4.1.29.Final.jar.sha1 |   1 +
 .../netty-transport-LICENSE-ASL.txt}               |   0
 ...y-all-NOTICE.txt => netty-transport-NOTICE.txt} |   0
 ...ty-transport-native-epoll-4.1.29.Final.jar.sha1 |   1 +
 .../netty-transport-native-epoll-LICENSE-ASL.txt}  |   0
 ...txt => netty-transport-native-epoll-NOTICE.txt} |   0
 ...nsport-native-unix-common-4.1.29.Final.jar.sha1 |   1 +
 ...y-transport-native-unix-common-LICENSE-ASL.txt} |   0
 ... netty-transport-native-unix-common-NOTICE.txt} |   0
 .../adding-custom-plugins-in-solrcloud-mode.adoc   |  13 +-
 solr/solr-ref-guide/src/aliases.adoc               |   6 +-
 .../authentication-and-authorization-plugins.adoc  |  10 +-
 .../src/cluster-node-management.adoc               |   2 +-
 solr/solr-ref-guide/src/json-facet-api.adoc        |   1 -
 .../src/jwt-authentication-plugin.adoc             |   2 +-
 ...onitoring-solr-with-prometheus-and-grafana.adoc |   2 +-
 .../src/query-settings-in-solrconfig.adoc          |   3 +-
 .../src/rule-based-authorization-plugin.adoc       |   2 +-
 .../src/solr-control-script-reference.adoc         |  10 +-
 solr/solr-ref-guide/src/solr-tracing.adoc          |   2 +-
 solr/solr-ref-guide/src/solr-upgrade-notes.adoc    |  65 +++
 .../src/solrcloud-autoscaling-api.adoc             |   8 +-
 .../solrcloud-autoscaling-policy-preferences.adoc  |   3 +-
 .../src/taking-solr-to-production.adoc             |  18 +-
 .../src/updating-parts-of-documents.adoc           |   2 +-
 solr/solrj/ivy.xml                                 |   9 +
 .../client/solrj/impl/BaseCloudSolrClient.java     |   7 +-
 .../solr/client/solrj/impl/CloudSolrClient.java    |   9 +-
 .../org/apache/solr/client/solrj/io/Tuple.java     |   3 +-
 .../client/solrj/io/eval/SetValueEvaluator.java    |   3 +-
 .../client/solrj/io/eval/TermVectorsEvaluator.java |   3 +-
 .../client/solrj/io/graph/ShortestPathStream.java  |   3 +-
 .../solr/client/solrj/io/ops/GroupOperation.java   |   6 +-
 .../client/solrj/io/stream/CloudSolrStream.java    |   6 +-
 .../client/solrj/io/stream/DeepRandomStream.java   |   6 +-
 .../solrj/io/stream/FeaturesSelectionStream.java   |   4 +-
 .../solrj/io/stream/SignificantTermsStream.java    |  10 +-
 .../solr/client/solrj/io/stream/StatsStream.java   |   6 +-
 .../client/solrj/io/stream/TextLogitStream.java    |   4 +-
 .../solr/client/solrj/io/stream/ZplotStream.java   |   6 +-
 .../solrj/response/schema/SchemaResponse.java      |   9 +-
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |   3 +-
 185 files changed, 1892 insertions(+), 1500 deletions(-)
 create mode 100644 lucene/core/src/java/org/apache/lucene/geo/Component2D.java
 create mode 100644 lucene/core/src/java/org/apache/lucene/geo/ComponentTree.java
 create mode 100644 solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java
 delete mode 100644 solr/licenses/netty-all-4.0.52.Final.jar.sha1
 create mode 100644 solr/licenses/netty-all-4.1.29.Final.jar.sha1
 create mode 100644 solr/licenses/netty-buffer-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-buffer-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-buffer-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-codec-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-codec-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-codec-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-common-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-common-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-common-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-handler-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-handler-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-handler-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-resolver-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-resolver-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-resolver-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-transport-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-transport-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-transport-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-transport-native-epoll-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-transport-native-epoll-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-transport-native-epoll-NOTICE.txt} (100%)
 create mode 100644 solr/licenses/netty-transport-native-unix-common-4.1.29.Final.jar.sha1
 copy solr/{solr-ref-guide/src/fonts/Noto_Sans/LICENSE.txt => licenses/netty-transport-native-unix-common-LICENSE-ASL.txt} (100%)
 mode change 100755 => 100644
 copy solr/licenses/{netty-all-NOTICE.txt => netty-transport-native-unix-common-NOTICE.txt} (100%)


[lucene-solr] 02/02: SOLR-13677: API refactoring, cleanup.

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13677-final
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit b541fa373720369e6c038ed261ce6e1575022bf2
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Oct 16 17:59:58 2019 +0200

    SOLR-13677: API refactoring, cleanup.
---
 .../solr/handler/dataimport/DataImportHandler.java |  6 +-
 .../java/org/apache/solr/core/CoreContainer.java   | 77 ++++++++++++----------
 .../org/apache/solr/core/HdfsDirectoryFactory.java | 14 +++-
 .../src/java/org/apache/solr/core/SolrCore.java    | 70 +++++++++++---------
 .../apache/solr/handler/ReplicationHandler.java    | 24 +++----
 .../apache/solr/handler/RequestHandlerBase.java    | 24 +++----
 .../solr/handler/admin/CoreAdminHandler.java       |  8 +--
 .../solr/handler/component/SuggestComponent.java   |  6 +-
 .../apache/solr/metrics/SolrCoreMetricManager.java | 47 +++++++------
 .../org/apache/solr/metrics/SolrMetricManager.java |  4 +-
 .../apache/solr/metrics/SolrMetricProducer.java    | 33 +++++++---
 .../apache/solr/metrics/SolrMetricsContext.java    | 30 +++------
 .../java/org/apache/solr/search/CaffeineCache.java | 16 +++--
 .../java/org/apache/solr/search/FastLRUCache.java  | 14 ++--
 .../src/java/org/apache/solr/search/LFUCache.java  | 13 ++--
 .../src/java/org/apache/solr/search/LRUCache.java  | 11 ++--
 .../org/apache/solr/search/SolrCacheHolder.java    |  4 +-
 .../org/apache/solr/search/SolrFieldCacheBean.java | 16 +++--
 .../org/apache/solr/search/SolrIndexSearcher.java  | 53 ++++++++-------
 .../apache/solr/security/AuthenticationPlugin.java | 24 ++++---
 .../apache/solr/servlet/SolrDispatchFilter.java    |  2 +-
 .../org/apache/solr/store/blockcache/Metrics.java  | 19 +++---
 .../solr/store/hdfs/HdfsLocalityReporter.java      | 20 +++---
 .../org/apache/solr/update/SolrIndexWriter.java    | 38 ++++++-----
 .../org/apache/solr/update/UpdateShardHandler.java |  9 +--
 .../stats/InstrumentedHttpListenerFactory.java     | 15 ++---
 ...rumentedPoolingHttpClientConnectionManager.java | 30 +++++----
 .../solr/handler/admin/MetricsHandlerTest.java     |  8 +--
 28 files changed, 340 insertions(+), 295 deletions(-)

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 3d5c4d5..8e1b8aa 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
@@ -275,8 +275,8 @@ public class DataImportHandler extends RequestHandlerBase implements
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext m) {
-    super.initializeMetrics(m);
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    super.initializeMetrics(m, 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);
       }
     });
-    solrMetricsContext.gauge(this, metrics, true, "importer", getCategory().toString());
+    solrMetricsContext.gauge(this, metrics, true, "importer", getCategory().toString(), scope);
   }
 
   // //////////////////////SolrInfoMBeans methods //////////////////////
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 054bd67..d4ac97a 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 = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
+
+  protected volatile SolrMetricsContext solrMetricsContext;
 
   protected MetricsHandler metricsHandler;
 
@@ -612,6 +615,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,
@@ -625,7 +630,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);
 
@@ -638,7 +643,7 @@ 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");
+      pkiAuthenticationPlugin.initializeMetrics(solrMetricsContext, "/authentication/pki");
       TracerConfigurator.loadTracer(loader, cfg.getTracerConfiguratorPluginInfo(), getZkController().getZkStateReader());
     }
 
@@ -668,7 +673,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);
 
 
@@ -683,22 +688,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) {
@@ -706,14 +709,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) {
@@ -721,15 +724,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);
@@ -818,7 +821,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;
@@ -866,7 +869,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() {
@@ -1788,7 +1791,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..32010ba 100644
--- a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
+++ b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java
@@ -55,6 +55,7 @@ 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 +142,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 +505,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 solrMetricsContext, String scope) {
+    MetricsHolder.metrics.initializeMetrics(solrMetricsContext, scope);
+    LocalityHolder.reporter.initializeMetrics(solrMetricsContext, scope);
   }
 
   @Override
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 9bfade2..4889f1a 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -110,6 +110,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.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.response.BinaryResponseWriter;
@@ -231,7 +232,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
   private final CoreContainer coreContainer;
 
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
-  private final String metricTag = getUniqueMetricTag(null);
+  private final String metricTag = SolrMetricProducer.getUniqueMetricTag(this, null);
+  private final SolrMetricsContext solrMetricsContext;
 
   public volatile boolean searchEnabled = true;
   public volatile boolean indexEnabled = true;
@@ -687,6 +689,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
   }
 
   private DirectoryFactory initDirectoryFactory() {
+    // XXX some factory implementations are also SolrMetricProducer-s
     return DirectoryFactory.loadDirectoryFactory(solrConfig, coreContainer, coreMetricManager.getRegistryName());
   }
 
@@ -919,6 +922,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 +944,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 +1017,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 +1166,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 m, String scope) {
+    newSearcherCounter = m.counter(this, "new", Category.SEARCHER.toString());
+    newSearcherTimer = m.timer(this, "time", Category.SEARCHER.toString(), "new");
+    newSearcherWarmupTimer = m.timer(this, "warmup", Category.SEARCHER.toString(), "new");
+    newSearcherMaxReachedCounter = m.counter(this, "maxReached", Category.SEARCHER.toString(), "new");
+    newSearcherOtherErrorsCounter = m.counter(this, "errors", Category.SEARCHER.toString(), "new");
+
+    m.gauge(this, () -> name == null ? "(null)" : name, true, "coreName", Category.CORE.toString());
+    m.gauge(this, () -> startTime, true, "startTime", Category.CORE.toString());
+    m.gauge(this, () -> getOpenCount(), true, "refCount", Category.CORE.toString());
+    m.gauge(this, () -> resourceLoader.getInstancePath().toString(), true, "instanceDir", Category.CORE.toString());
+    m.gauge(this, () -> isClosed() ? "(closed)" : getIndexDir(), true, "indexDir", Category.CORE.toString());
+    m.gauge(this, () -> isClosed() ? 0 : getIndexSize(), true, "sizeInBytes", Category.INDEX.toString());
+    m.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());
+      m.gauge(this, () -> coreContainer.getNamesForCore(this), true, "aliases", Category.CORE.toString());
       final CloudDescriptor cd = getCoreDescriptor().getCloudDescriptor();
       if (cd != null) {
-        manager.registerGauge(this, registry, () -> {
+        m.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, () -> {
+        m.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, () -> {
+    m.gauge(this, () -> dataDirFile.getTotalSpace(), true, "totalSpace", Category.CORE.toString(), "fs");
+    m.gauge(this, () -> dataDirFile.getUsableSpace(), true, "usableSpace", Category.CORE.toString(), "fs");
+    m.gauge(this, () -> dataDirPath.toAbsolutePath().toString(), true, "path", Category.CORE.toString(), "fs");
+    m.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/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index d78490a..69bc27e 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -863,20 +863,20 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext m) {
-    super.initializeMetrics(m);
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    super.initializeMetrics(m, scope);
     solrMetricsContext.gauge(this,  () -> (core != null && !core.isClosed() ? NumberUtils.readableSize(core.getIndexSize()) : ""),
-        true, "indexSize", getCategory().toString());
+        true, "indexSize", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? getIndexVersion().toString() : ""),
-         true, "indexVersion", getCategory().toString());
+         true, "indexVersion", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? getIndexVersion().generation : 0),
-        true, GENERATION, getCategory().toString());
+        true, GENERATION, getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> (core != null && !core.isClosed() ? core.getIndexDir() : ""),
-        true, "indexPath", getCategory().toString());
+        true, "indexPath", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> isMaster,
-         true, "isMaster", getCategory().toString());
+         true, "isMaster", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> isSlave,
-         true, "isSlave", getCategory().toString());
+         true, "isSlave", getCategory().toString(), scope);
     final MetricsMap fetcherMap = new MetricsMap((detailed, map) -> {
       IndexFetcher fetcher = currentIndexFetcher;
       if (fetcher != null) {
@@ -905,13 +905,13 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
         addVal(map, IndexFetcher.CONF_FILES_REPLICATED, props, String.class);
       }
     });
-    solrMetricsContext.gauge(this , fetcherMap, true, "fetcher", getCategory().toString());
+    solrMetricsContext.gauge(this , fetcherMap, true, "fetcher", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> isMaster && includeConfFiles != null ? includeConfFiles : "",
-         true, "confFilesToReplicate", getCategory().toString());
+         true, "confFilesToReplicate", getCategory().toString(), scope);
     solrMetricsContext.gauge(this, () -> isMaster ? getReplicateAfterStrings() : Collections.<String>emptyList(),
-        true, REPLICATE_AFTER, getCategory().toString());
+        true, REPLICATE_AFTER, getCategory().toString(), scope);
     solrMetricsContext.gauge(this,  () -> isMaster && replicationEnabled.get(),
-        true, "replicationEnabled", getCategory().toString());
+        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?
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 9ea64b9..b744abf 100644
--- a/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/RequestHandlerBase.java
@@ -148,19 +148,19 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext m) {
-    this.solrMetricsContext = m.getChildInfo(this);
-    numErrors = solrMetricsContext.meter(this, "errors", getCategory().toString());
-    numServerErrors = solrMetricsContext.meter(this, "serverErrors", getCategory().toString());
-    numClientErrors = solrMetricsContext.meter(this, "clientErrors", getCategory().toString());
-    numTimeouts = solrMetricsContext.meter(this, "timeouts", getCategory().toString());
-    requests = solrMetricsContext.counter(this, "requests", getCategory().toString());
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    this.solrMetricsContext = m.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())));
-    solrMetricsContext.gauge(this, metricsMap, true, "shardRequests", getCategory().toString());
-    requestTimes = solrMetricsContext.timer(this,"requestTimes", getCategory().toString());
-    totalTime = solrMetricsContext.counter(this, "totalTime", getCategory().toString());
-    solrMetricsContext.gauge(this, () -> handlerStart, true, "handlerStart", getCategory().toString());
+    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) {
@@ -276,7 +276,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return solrMetricsContext != null ? solrMetricsContext.getRegistry() : null;
+    return solrMetricsContext != null ? solrMetricsContext.getMetricRegistry() : null;
   }
 
   @Override
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 3808b91..5925cdb 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
@@ -121,10 +121,10 @@ public class CoreAdminHandler extends RequestHandlerBase implements PermissionNa
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext m) {
-    super.initializeMetrics(m);
-    parallelExecutor = MetricUtils.instrumentedExecutorService(parallelExecutor, this, solrMetricsContext.getRegistry(),
-        SolrMetricManager.mkName("parallelCoreAdminExecutor", getCategory().name(), solrMetricsContext.scope, "threadPool"));
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    super.initializeMetrics(m, 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 ca02867..e1cbe1b 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
@@ -355,8 +355,8 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext metricsContext) {
-    this.metricsContext = metricsContext.getChildInfo(this);
+  public void initializeMetrics(SolrMetricsContext metricsContext, String scope) {
+    this.metricsContext = metricsContext.getChildContext(this);
 
     this.metricsContext.gauge(this, () -> ramBytesUsed(), true, "totalSizeInBytes", getCategory().toString());
     MetricsMap suggestersMap = new MetricsMap((detailed, map) -> {
@@ -365,7 +365,7 @@ public class SuggestComponent extends SearchComponent implements SolrCoreAware,
         map.put(entry.getKey(), suggester.toString());
       }
     });
-    this.metricsContext.gauge(this, suggestersMap, true, "suggesters", getCategory().toString());
+    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 201dc08..977b0ca 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricManager.java
@@ -735,7 +735,9 @@ public class SolrMetricManager {
       if (metric instanceof GaugeWrapper) {
         GaugeWrapper wrapper = (GaugeWrapper) metric;
         boolean toRemove = wrapper.getTag().contains(tagSegment);
-        if (toRemove) removed.incrementAndGet();
+        if (toRemove) {
+          removed.incrementAndGet();
+        }
         return toRemove;
       }
       return false;
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 369cff6..77e2f60 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricProducer.java
@@ -27,9 +27,11 @@ public interface SolrMetricProducer extends AutoCloseable {
    * 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
    */
-  default String getUniqueMetricTag(String parentName) {
-    String name = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
+  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);
     }
@@ -50,15 +52,22 @@ public interface SolrMetricProducer extends AutoCloseable {
    *                 {@link #initializeMetrics(SolrMetricManager, String, String, String)} is called.
    * @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)} instead
+   * @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));
+    initializeMetrics(new SolrMetricsContext(manager, registry, tag), scope);
 
   }
 
-  default void initializeMetrics(SolrMetricsContext context) {
-    throw new RuntimeException("You must implement either initializeMetrics(SolrMetricsContext) or " +
+  /**
+   * Initialize metrics specific to this producer.
+   * @param context
+   * @param scope
+   */
+  default void initializeMetrics(SolrMetricsContext context, String scope) {
+    throw new RuntimeException("In class " + getClass().getName() +
+        " you must implement either initializeMetrics(SolrMetricsContext, String) or " +
         "initializeMetrics(SolrMetricManager, String, String, String)");
 
   }
@@ -69,9 +78,13 @@ public interface SolrMetricProducer extends AutoCloseable {
 
   @Override
   default void close() throws Exception {
-    SolrMetricsContext info = getSolrMetricsContext();
-    if (info == null || info.tag.indexOf(':') == -1) return;//this will end up unregistering the root itself
-    info.unregister();
+    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
index 3cb2554..8c3eb97 100644
--- a/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
+++ b/solr/core/src/java/org/apache/solr/metrics/SolrMetricsContext.java
@@ -33,13 +33,11 @@ public class SolrMetricsContext {
   public final String registry;
   public final SolrMetricManager metricManager;
   public final String tag;
-  public final String scope;
 
-  public SolrMetricsContext(SolrMetricManager metricManager, String registry, String tag, String scope) {
+  public SolrMetricsContext(SolrMetricManager metricManager, String registry, String tag) {
     this.registry = registry;
     this.metricManager = metricManager;
     this.tag = tag;
-    this.scope = scope;
   }
 
   public String getTag() {
@@ -50,40 +48,30 @@ public class SolrMetricsContext {
     metricManager.unregisterGauges(registry, tag);
   }
 
-  public SolrMetricsContext getChildInfo(SolrMetricProducer producer) {
-    SolrMetricsContext metricsInfo = new SolrMetricsContext(metricManager, registry, producer.getUniqueMetricTag(tag), scope);
-    return metricsInfo;
+  public SolrMetricsContext getChildContext(Object child) {
+    SolrMetricsContext childContext = new SolrMetricsContext(metricManager, registry, SolrMetricProducer.getUniqueMetricTag(child, tag));
+    return childContext;
   }
 
   public Meter meter(SolrInfoBean info, String metricName, String... metricpath) {
-    return metricManager.meter(info, registry, createName(metricName, metricpath));
-  }
-
-  // adds the scope
-  private String createName(String metricName, String... metricpath) {
-    ArrayList<String> l = new ArrayList<>();
-    if(metricpath != null ) {
-      Collections.addAll(l, metricpath);
-    }
-    l.add(scope);
-    return makeName(l, metricName);
+    return metricManager.meter(info, registry, metricName, metricpath);
   }
 
   public Counter counter(SolrInfoBean info, String metricName, String... metricpath) {
-    return metricManager.counter(info, registry, createName(metricName, metricpath));
+    return metricManager.counter(info, registry, metricName, metricpath);
 
   }
 
   public void gauge(SolrInfoBean info, Gauge<?> gauge, boolean force, String metricName, String... metricpath) {
-    metricManager.registerGauge(info, registry, gauge, tag, force, createName(metricName, metricpath));
+    metricManager.registerGauge(info, registry, gauge, tag, force, metricName, metricpath);
   }
 
   public Timer timer(SolrInfoBean info, String metricName, String... metricpath) {
-    return metricManager.timer(info, registry, createName(metricName, metricpath));
+    return metricManager.timer(info, registry, metricName, metricpath);
 
   }
 
-  public MetricRegistry getRegistry() {
+  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 8e66eb8..bbcb93f 100644
--- a/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
+++ b/solr/core/src/java/org/apache/solr/search/CaffeineCache.java
@@ -39,6 +39,7 @@ 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 +89,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();
@@ -324,7 +325,12 @@ public class CaffeineCache<K, V> extends SolrCacheBase implements SolrCache<K, V
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return registry;
+    return solrMetricsContext != null ? solrMetricsContext.getMetricRegistry() : null;
+  }
+
+  @Override
+  public SolrMetricsContext getSolrMetricsContext() {
+    return solrMetricsContext;
   }
 
   @Override
@@ -338,8 +344,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 m, String scope) {
+    solrMetricsContext = m.getChildContext(this);
     cacheMap = new MetricsMap((detailed, map) -> {
       if (cache != null) {
         CacheStats stats = cache.stats();
@@ -363,6 +369,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 414389b..35b8dd1 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -29,7 +29,6 @@ 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.SolrMetricProducer;
 import org.apache.solr.metrics.SolrMetricsContext;
 import org.apache.solr.util.ConcurrentLRUCache;
 import org.slf4j.Logger;
@@ -75,6 +74,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K, V>
 
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
+  private SolrMetricsContext solrMetricsContext;
 
   @Override
   public Object init(Map args, Object persistence, CacheRegenerator regenerator) {
@@ -310,17 +310,15 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K, V>
   }
 
 
-  SolrMetricsContext metricsInfo;
-
   @Override
   public SolrMetricsContext getSolrMetricsContext() {
-    return metricsInfo;
+    return solrMetricsContext;
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext metricsInfo) {
-    this.metricsInfo = metricsInfo;
-    metricsInfo.metricManager.registerGauge(this, metricsInfo.registry, cacheMap, metricsInfo.tag, true, metricsInfo.scope, getCategory().toString());
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    this.solrMetricsContext = m.getChildContext(this);
+    this.solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
   }
 
   // for unit tests only
@@ -330,7 +328,7 @@ public class FastLRUCache<K, V> extends SolrCacheBase implements SolrCache<K, V>
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return metricsInfo == null ? null : metricsInfo.getRegistry();
+    return solrMetricsContext == null ? null : solrMetricsContext.getMetricRegistry();
   }
 
   @Override
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 13e02e4..f3800da 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -79,6 +79,8 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
   private int maxIdleTimeSec;
   private MetricsMap cacheMap;
   private Set<String> metricNames = ConcurrentHashMap.newKeySet();
+  private SolrMetricsContext solrMetricsContext;
+
 
   private int maxSize;
   private int minSizeLimit;
@@ -262,17 +264,14 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
     return "0." + hundredths;
   }
 
-
-  private SolrMetricsContext solrMetricsContext;
-
   @Override
   public SolrMetricsContext getSolrMetricsContext() {
     return solrMetricsContext;
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext info) {
-    solrMetricsContext = info.getChildInfo(this);
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    solrMetricsContext = m.getChildContext(this);
     cacheMap = new MetricsMap((detailed, map) -> {
       if (cache != null) {
         ConcurrentLFUCache.Stats stats = cache.getStats();
@@ -338,7 +337,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
 
       }
     });
-    solrMetricsContext.metricManager.registerGauge(this, solrMetricsContext.registry, cacheMap, solrMetricsContext.getTag(), true, solrMetricsContext.scope, getCategory().toString());
+    solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
   }
 
   // for unit tests only
@@ -353,7 +352,7 @@ public class LFUCache<K, V> implements SolrCache<K, V>, Accountable {
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return solrMetricsContext == null ? null : solrMetricsContext.getRegistry();
+    return solrMetricsContext == null ? null : solrMetricsContext.getMetricRegistry();
 
   }
 
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 c8c5cdd..5755fdb 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -77,6 +77,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 SolrMetricsContext solrMetricsContext;
   private int maxSize;
   private int initialSize;
 
@@ -395,16 +396,14 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
     return metricNames;
   }
 
-  SolrMetricsContext solrMetricsContext;
-
   @Override
   public SolrMetricsContext getSolrMetricsContext() {
     return solrMetricsContext;
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext m) {
-    solrMetricsContext = m.getChildInfo(this);
+  public void initializeMetrics(SolrMetricsContext m, String scope) {
+    solrMetricsContext = m.getChildContext(this);
     cacheMap = new MetricsMap((detailed, res) -> {
       synchronized (map) {
         res.put(LOOKUPS_PARAM, lookups);
@@ -433,7 +432,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());
     });
-    solrMetricsContext.metricManager.registerGauge(this, solrMetricsContext.registry, cacheMap, solrMetricsContext.tag, true, solrMetricsContext.scope, getCategory().toString());
+    solrMetricsContext.gauge(this, cacheMap, true, scope, getCategory().toString());
   }
 
   // for unit tests only
@@ -443,7 +442,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return solrMetricsContext ==null ?null: solrMetricsContext.getRegistry();
+    return solrMetricsContext ==null ?null: solrMetricsContext.getMetricRegistry();
   }
 
   @Override
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 d0d9293..149c9ef 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrCacheHolder.java
@@ -141,8 +141,8 @@ public class SolrCacheHolder<K, V> implements SolrCache<K,V> {
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext info) {
-    delegate.initializeMetrics(info);
+  public void initializeMetrics(SolrMetricsContext context, String scope) {
+    delegate.initializeMetrics(context, 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..0db6e88 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
@@ -24,6 +24,7 @@ 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 +36,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
@@ -52,12 +53,17 @@ public class SolrFieldCacheBean implements SolrInfoBean, SolrMetricProducer {
   }
   @Override
   public MetricRegistry getMetricRegistry() {
-    return registry;
+    return solrMetricsContext != null ? solrMetricsContext.getMetricRegistry() : null;
   }
 
   @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 m, String scope) {
+    this.solrMetricsContext = m;
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       if (detailed && !disableEntryList && !disableJmxEntryList) {
         UninvertingReader.FieldCacheStats fieldCacheStats = UninvertingReader.getUninvertedStats();
@@ -72,6 +78,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 fe33095..4a5c194 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -70,6 +70,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;
@@ -141,8 +142,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 {
@@ -432,12 +432,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();
   }
 
@@ -2280,23 +2281,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 solrMetricsContext, String scope) {
+    solrMetricsContext.gauge(this, () -> name, true, "searcherName", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> cachingEnabled, true, "caching", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> openTime, true, "openedAt", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> warmupTime, true, "warmupTime", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.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);
+    solrMetricsContext.gauge(this, () -> reader.numDocs(), true, "numDocs", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> reader.maxDoc(), true, "maxDoc", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> reader.maxDoc() - reader.numDocs(), true, "deletedDocs", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> reader.toString(), true, "reader", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> reader.directory().toString(), true, "readerDir", Category.SEARCHER.toString(), scope);
+    solrMetricsContext.gauge(this, () -> reader.getVersion(), true, "indexVersion", Category.SEARCHER.toString(), scope);
     // size of the currently opened commit
-    manager.registerGauge(this, registry, () -> {
+    solrMetricsContext.gauge(this, () -> {
       try {
         Collection<String> files = reader.getIndexCommit().getFileNames();
         long total = 0;
@@ -2307,14 +2311,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,
+    solrMetricsContext.gauge(this,
         new MetricsMap((detailed, map) -> {
           statsCache.getCacheMetrics().getSnapshot(map::put);
           map.put("statsCacheImpl", statsCache.getClass().getSimpleName());
-        }),
-        tag, true, "statsCache", Category.CACHE.toString(), scope);
+        }), true, "statsCache", Category.CACHE.toString(), scope);
   }
 
   @Override
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 cf30a2e..688c3c0 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
@@ -146,19 +146,17 @@ public abstract class AuthenticationPlugin implements SolrInfoBean, SolrMetricPr
   }
 
   @Override
-  public void initializeMetrics(SolrMetricsContext metrics) {
-    this.metrics = metrics.getChildInfo(this);
+  public void initializeMetrics(SolrMetricsContext metrics, String scope) {
+    this.metrics = metrics.getChildContext(this);
     // Metrics
-    numErrors = this.metrics.meter(this, "errors", getCategory().toString());
-    requests = this.metrics.counter(this, "requests", getCategory().toString());
-    numAuthenticated = this.metrics.counter(this, "authenticated",getCategory().toString());
-    numPassThrough = this.metrics.counter(this, "passThrough",  getCategory().toString());
-    numWrongCredentials = this.metrics.counter(this, "failWrongCredentials",getCategory().toString());
-    numMissingCredentials = this.metrics.counter(this,  "failMissingCredentials",getCategory().toString());
-    requestTimes = this.metrics.timer(this,"requestTimes", getCategory().toString());
-    totalTime = this.metrics.counter(this,"totalTime", getCategory().toString());
-    metricNames.addAll(Arrays.asList("errors", "requests", "authenticated", "passThrough",
-        "failWrongCredentials", "failMissingCredentials", "requestTimes", "totalTime"));
+    numErrors = this.metrics.meter(this, "errors", getCategory().toString(), scope);
+    requests = this.metrics.counter(this, "requests", getCategory().toString(), scope);
+    numAuthenticated = this.metrics.counter(this, "authenticated",getCategory().toString(), scope);
+    numPassThrough = this.metrics.counter(this, "passThrough",  getCategory().toString(), scope);
+    numWrongCredentials = this.metrics.counter(this, "failWrongCredentials",getCategory().toString(), scope);
+    numMissingCredentials = this.metrics.counter(this,  "failMissingCredentials",getCategory().toString(), scope);
+    requestTimes = this.metrics.timer(this,"requestTimes", getCategory().toString(), scope);
+    totalTime = this.metrics.counter(this,"totalTime", getCategory().toString(), scope);
   }
 
   @Override
@@ -183,7 +181,7 @@ public abstract class AuthenticationPlugin implements SolrInfoBean, SolrMetricPr
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return metrics == null ? null : metrics.getRegistry();
+    return metrics == null ? null : metrics.getMetricRegistry();
   }
 
 }
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..717ff01 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
@@ -108,7 +108,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 = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
   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..8790ba4 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
@@ -25,6 +25,7 @@ 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 +55,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 m, String scope) {
+    solrMetricsContext = m.getChildContext(this);
     metricsMap = new MetricsMap((detailed, map) -> {
       long now = System.nanoTime();
       long delta = Math.max(now - previous, 1);
@@ -108,7 +105,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) {
@@ -134,7 +131,11 @@ public class Metrics extends SolrCacheBase implements SolrInfoBean, SolrMetricPr
 
   @Override
   public MetricRegistry getMetricRegistry() {
-    return registry;
+    return solrMetricsContext != null ? solrMetricsContext.getMetricRegistry() : null;
   }
 
+  @Override
+  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..e51fa3c 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
@@ -34,6 +34,7 @@ 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 +52,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 +88,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 m, String scope) {
+    solrMetricsContext = m.getChildContext(this);
     MetricsMap metricsMap = new MetricsMap((detailed, map) -> {
       long totalBytes = 0;
       long localBytes = 0;
@@ -149,7 +151,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/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 538a983..b377561 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -43,6 +43,8 @@ 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.SolrMetricProducer;
+import org.apache.solr.metrics.SolrMetricsContext;
 import org.apache.solr.schema.IndexSchema;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -88,8 +90,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 +121,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 +135,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 +159,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 +344,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/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index 8e3486b..f41102c 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -40,6 +40,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;
@@ -179,11 +180,11 @@ 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 m, String scope) {
+    registry = m.getMetricRegistry();
     String expandedScope = SolrMetricManager.mkName(scope, getCategory().name());
-    updateHttpListenerFactory.initializeMetrics(manager, registryName, tag, expandedScope);
-    defaultConnectionManager.initializeMetrics(manager, registryName, tag, expandedScope);
+    updateHttpListenerFactory.initializeMetrics(m, expandedScope);
+    defaultConnectionManager.initializeMetrics(m, expandedScope);
     updateExecutor = MetricUtils.instrumentedExecutorService(updateExecutor, this, registry,
         SolrMetricManager.mkName("updateOnlyExecutor", expandedScope, "threadPool"));
     recoveryExecutor = MetricUtils.instrumentedExecutorService(recoveryExecutor, this, registry,
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..f57cb25 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
@@ -26,6 +26,7 @@ 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 +65,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 +84,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 +99,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 solrMetricsContext, String scope) {
+    this.solrMetricsContext = solrMetricsContext;
     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..cf67181 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 solrMetricsContext, String scope) {
+    this.solrMetricsContext = solrMetricsContext.getChildContext(this);
+    solrMetricsContext.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));
+    solrMetricsContext.gauge(null, () -> getTotalStats().getLeased(),
+        true, SolrMetricManager.mkName("leasedConnections", scope));
+    solrMetricsContext.gauge(null, () -> getTotalStats().getMax(),
+        true, SolrMetricManager.mkName("maxConnections", scope));
+    solrMetricsContext.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 9a3856d..f4e9d52 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
@@ -416,7 +416,7 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
     void reset(DumpRequestHandler rh) throws Exception {
         this.rh = rh;
         if(metricsInfo != null)
-        this.rh.initializeMetrics(metricsInfo);
+        this.rh.initializeMetrics(metricsInfo, "/dumphandler");
     }
 
 
@@ -441,11 +441,11 @@ public class MetricsHandlerTest extends SolrTestCaseJ4 {
     }
 
     @Override
-    public void initializeMetrics(SolrMetricsContext m) {
-      super.initializeMetrics(m);
+    public void initializeMetrics(SolrMetricsContext m, String scope) {
+      super.initializeMetrics(m, scope);
       MetricsMap metrics = new MetricsMap((detailed, map) -> map.putAll(gaugevals));
       solrMetricsContext.gauge(this,
-           metrics,  true, "dumphandlergauge", getCategory().toString());
+           metrics,  true, "dumphandlergauge", getCategory().toString(), scope);
 
     }
 


[lucene-solr] 01/02: Merge branch 'master' into jira/solr-13677-final

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ab pushed a commit to branch jira/solr-13677-final
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit fb1218a5cf6960f961cc59fcf0636e07c9f84ad6
Merge: 44cfc02 f7f6a37
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Wed Oct 16 10:36:38 2019 +0200

    Merge branch 'master' into jira/solr-13677-final

 lucene/CHANGES.txt                                 |  22 +-
 .../analysis/query/QueryAutoStopWordAnalyzer.java  |   8 +-
 .../analysis/ja/dict/TokenInfoDictionary$fst.dat   | Bin 1698570 -> 1698570 bytes
 .../analysis/ko/dict/TokenInfoDictionary$fst.dat   | Bin 5641400 -> 5640903 bytes
 .../lucene/benchmark/byTask/utils/Config.java      |  19 +-
 .../blocktreeords/OrdsBlockTreeTermsReader.java    |   3 +-
 .../codecs/bloom/BloomFilteringPostingsFormat.java |   3 +-
 .../lucene/codecs/memory/FSTOrdTermsReader.java    |   3 +-
 .../lucene/codecs/memory/FSTTermsReader.java       |   3 +-
 .../codecs/blocktree/BlockTreeTermsReader.java     |   3 +-
 .../LatLonDocValuesPointInPolygonQuery.java        |   5 +-
 .../lucene/document/LatLonPointInPolygonQuery.java |  21 +-
 .../java/org/apache/lucene/geo/Component2D.java    |  96 ++++
 .../java/org/apache/lucene/geo/ComponentTree.java  | 206 +++++++++
 .../src/java/org/apache/lucene/geo/EdgeTree.java   | 503 ++++++++-------------
 .../org/apache/lucene/geo/GeoEncodingUtils.java    |  17 +-
 .../src/java/org/apache/lucene/geo/Polygon2D.java  | 224 +++++----
 .../apache/lucene/index/BaseCompositeReader.java   |  24 +-
 .../java/org/apache/lucene/index/IndexReader.java  |   7 +-
 .../org/apache/lucene/search/BooleanQuery.java     |  11 +-
 .../src/java/org/apache/lucene/util/SetOnce.java   |  36 +-
 .../java/org/apache/lucene/util/fst/Builder.java   |   3 -
 .../src/java/org/apache/lucene/util/fst/FST.java   | 106 +----
 .../test/org/apache/lucene/geo/TestPolygon2D.java  |  88 ++--
 .../lucene/index/TestFilterDirectoryReader.java    |  72 +++
 .../test/org/apache/lucene/util/TestSetOnce.java   |   9 +
 lucene/ivy-versions.properties                     |  12 +-
 .../monitor/MultipassTermFilteredPresearcher.java  |   4 +-
 .../lucene/monitor/TermFilteredPresearcher.java    |   4 +-
 .../builders/MultiPhraseQueryNodeBuilder.java      |  10 +-
 .../lucene/replicator/IndexReplicationHandler.java |   3 +-
 .../idversion/VersionBlockTreeTermsReader.java     |   3 +-
 .../lucene/document/LatLonShapeLineQuery.java      |   5 +-
 .../lucene/document/LatLonShapePolygonQuery.java   |   5 +-
 .../apache/lucene/document/XYShapeLineQuery.java   |  13 +-
 .../lucene/document/XYShapePolygonQuery.java       |   6 +-
 .../src/java/org/apache/lucene/geo/Line2D.java     | 134 ++++--
 .../java/org/apache/lucene/geo/XYPolygon2D.java    |  10 +-
 .../lucene/document/BaseLatLonShapeTestCase.java   |   5 +-
 .../lucene/document/BaseShapeEncodingTestCase.java |   6 +-
 .../apache/lucene/document/BaseShapeTestCase.java  |  17 +-
 .../lucene/document/BaseXYShapeTestCase.java       |   5 +-
 .../document/TestLatLonLineShapeQueries.java       |  19 +-
 .../document/TestLatLonMultiLineShapeQueries.java  |  22 +-
 .../document/TestLatLonMultiPointShapeQueries.java |  22 +-
 .../TestLatLonMultiPolygonShapeQueries.java        |  22 +-
 .../document/TestLatLonPointShapeQueries.java      |  18 +-
 .../document/TestLatLonPolygonShapeQueries.java    |  18 +-
 .../apache/lucene/document/TestLatLonShape.java    |  11 +-
 .../lucene/document/TestLatLonShapeEncoding.java   |   3 +-
 .../lucene/document/TestXYLineShapeQueries.java    |  19 +-
 .../document/TestXYMultiLineShapeQueries.java      |  22 +-
 .../document/TestXYMultiPointShapeQueries.java     |  22 +-
 .../document/TestXYMultiPolygonShapeQueries.java   |  22 +-
 .../lucene/document/TestXYPointShapeQueries.java   |  18 +-
 .../lucene/document/TestXYPolygonShapeQueries.java |  18 +-
 .../lucene/document/TestXYShapeEncoding.java       |   3 +-
 .../src/test/org/apache/lucene/geo/TestLine2D.java |  18 +-
 .../lucene/spatial3d/geom/StandardObjects.java     |   4 +-
 .../search/suggest/document/ContextQuery.java      |   6 +-
 .../dependencies/GetMavenDependenciesTask.java     |  22 +-
 solr/CHANGES.txt                                   |   9 +
 .../solr/analytics/AnalyticsRequestManager.java    |   6 +-
 .../solr/handler/dataimport/RegexTransformer.java  |   3 +-
 .../solr/prometheus/collector/MetricSamples.java   |   7 +-
 .../solr/response/VelocityResponseWriter.java      |   5 +-
 .../client/solrj/embedded/JettySolrRunner.java     |  10 +-
 .../apache/solr/cloud/OverseerTaskProcessor.java   |   6 +-
 .../java/org/apache/solr/cloud/ZkController.java   |   7 +-
 .../java/org/apache/solr/cloud/ZkShardTerms.java   |   5 +-
 .../solr/cloud/api/collections/CreateShardCmd.java |  10 +-
 .../cloud/api/collections/DeleteReplicaCmd.java    |   5 +-
 .../OverseerCollectionMessageHandler.java          |   8 +-
 .../api/collections/ReindexCollectionCmd.java      |   3 +-
 .../solr/cloud/api/collections/SplitShardCmd.java  |   7 +-
 .../autoscaling/sim/SimNodeStateProvider.java      |   3 +-
 .../src/java/org/apache/solr/core/SolrCores.java   |  11 +-
 .../solr/handler/admin/CoreAdminHandler.java       |   6 +-
 .../handler/admin/SegmentsInfoRequestHandler.java  |   3 +-
 .../solr/handler/component/SearchHandler.java      |   3 +-
 .../solr/handler/component/TermsComponent.java     |  16 +-
 .../apache/solr/handler/loader/CSVLoaderBase.java  |   6 +-
 .../solr/response/PHPSerializedResponseWriter.java |  11 +-
 .../src/java/org/apache/solr/rest/RestManager.java |   5 +-
 .../analysis/ManagedSynonymFilterFactory.java      |  23 +-
 .../analysis/ManagedSynonymGraphFilterFactory.java |   6 +-
 .../solr/schema/FileExchangeRateProvider.java      |   6 +-
 .../TopGroupsShardRequestFactory.java              |   3 +-
 .../SearchGroupShardResponseProcessor.java         |  10 +-
 .../TopGroupsShardResponseProcessor.java           |  18 +-
 .../java/org/apache/solr/servlet/HttpSolrCall.java |  29 +-
 .../AddSchemaFieldsUpdateProcessorFactory.java     |  14 +-
 .../CloneFieldUpdateProcessorFactory.java          |   4 +-
 .../java/org/apache/solr/util/SimplePostTool.java  |   6 +-
 .../src/java/org/apache/solr/util/SolrCLI.java     |   3 +-
 .../java/org/apache/solr/util/SolrPluginUtils.java |   8 +-
 .../solr/cloud/TestQueryingOnDownCollection.java   | 151 +++++++
 .../autoscaling/sim/TestSnapshotCloudManager.java  |  10 +-
 .../solr/security/BasicAuthOnSingleNodeTest.java   |  12 +-
 solr/licenses/netty-all-4.0.52.Final.jar.sha1      |   1 -
 solr/licenses/netty-all-4.1.29.Final.jar.sha1      |   1 +
 solr/licenses/netty-buffer-4.1.29.Final.jar.sha1   |   1 +
 solr/licenses/netty-buffer-LICENSE-ASL.txt         | 202 +++++++++
 solr/licenses/netty-buffer-NOTICE.txt              | 223 +++++++++
 solr/licenses/netty-codec-4.1.29.Final.jar.sha1    |   1 +
 solr/licenses/netty-codec-LICENSE-ASL.txt          | 202 +++++++++
 solr/licenses/netty-codec-NOTICE.txt               | 223 +++++++++
 solr/licenses/netty-common-4.1.29.Final.jar.sha1   |   1 +
 solr/licenses/netty-common-LICENSE-ASL.txt         | 202 +++++++++
 solr/licenses/netty-common-NOTICE.txt              | 223 +++++++++
 solr/licenses/netty-handler-4.1.29.Final.jar.sha1  |   1 +
 solr/licenses/netty-handler-LICENSE-ASL.txt        | 202 +++++++++
 solr/licenses/netty-handler-NOTICE.txt             | 223 +++++++++
 solr/licenses/netty-resolver-4.1.29.Final.jar.sha1 |   1 +
 solr/licenses/netty-resolver-LICENSE-ASL.txt       | 202 +++++++++
 solr/licenses/netty-resolver-NOTICE.txt            | 223 +++++++++
 .../licenses/netty-transport-4.1.29.Final.jar.sha1 |   1 +
 solr/licenses/netty-transport-LICENSE-ASL.txt      | 202 +++++++++
 solr/licenses/netty-transport-NOTICE.txt           | 223 +++++++++
 ...ty-transport-native-epoll-4.1.29.Final.jar.sha1 |   1 +
 .../netty-transport-native-epoll-LICENSE-ASL.txt   | 202 +++++++++
 .../netty-transport-native-epoll-NOTICE.txt        | 223 +++++++++
 ...nsport-native-unix-common-4.1.29.Final.jar.sha1 |   1 +
 ...ty-transport-native-unix-common-LICENSE-ASL.txt | 202 +++++++++
 .../netty-transport-native-unix-common-NOTICE.txt  | 223 +++++++++
 .../adding-custom-plugins-in-solrcloud-mode.adoc   |  13 +-
 solr/solr-ref-guide/src/aliases.adoc               |   6 +-
 .../authentication-and-authorization-plugins.adoc  |  10 +-
 .../src/cluster-node-management.adoc               |   2 +-
 solr/solr-ref-guide/src/json-facet-api.adoc        |   1 -
 .../src/jwt-authentication-plugin.adoc             |   2 +-
 ...onitoring-solr-with-prometheus-and-grafana.adoc |   2 +-
 .../src/query-settings-in-solrconfig.adoc          |   3 +-
 .../src/rule-based-authorization-plugin.adoc       |   2 +-
 .../src/solr-control-script-reference.adoc         |  10 +-
 solr/solr-ref-guide/src/solr-tracing.adoc          |   2 +-
 solr/solr-ref-guide/src/solr-upgrade-notes.adoc    |  65 +++
 .../src/solrcloud-autoscaling-api.adoc             |   8 +-
 .../solrcloud-autoscaling-policy-preferences.adoc  |   3 +-
 .../src/taking-solr-to-production.adoc             |  18 +-
 .../src/updating-parts-of-documents.adoc           |   2 +-
 solr/solrj/ivy.xml                                 |   9 +
 .../client/solrj/impl/BaseCloudSolrClient.java     |   7 +-
 .../solr/client/solrj/impl/CloudSolrClient.java    |   9 +-
 .../org/apache/solr/client/solrj/io/Tuple.java     |   3 +-
 .../client/solrj/io/eval/SetValueEvaluator.java    |   3 +-
 .../client/solrj/io/eval/TermVectorsEvaluator.java |   3 +-
 .../client/solrj/io/graph/ShortestPathStream.java  |   3 +-
 .../solr/client/solrj/io/ops/GroupOperation.java   |   6 +-
 .../client/solrj/io/stream/CloudSolrStream.java    |   6 +-
 .../client/solrj/io/stream/DeepRandomStream.java   |   6 +-
 .../solrj/io/stream/FeaturesSelectionStream.java   |   4 +-
 .../solrj/io/stream/SignificantTermsStream.java    |  10 +-
 .../solr/client/solrj/io/stream/StatsStream.java   |   6 +-
 .../client/solrj/io/stream/TextLogitStream.java    |   4 +-
 .../solr/client/solrj/io/stream/ZplotStream.java   |   6 +-
 .../solrj/response/schema/SchemaResponse.java      |   9 +-
 .../solr/cloud/AbstractFullDistribZkTestBase.java  |   3 +-
 158 files changed, 4952 insertions(+), 1205 deletions(-)