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

mlbiscoc pushed a commit to branch feature/SOLR-17458
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/feature/SOLR-17458 by this 
push:
     new fdf3038c3ff SOLR-17827: Remove JXM, SLF4J and Graphite reporters 
(#3443)
fdf3038c3ff is described below

commit fdf3038c3ffc1f162925bd81d966f4bc2fba9e9e
Author: Matthew Biscocho <[email protected]>
AuthorDate: Wed Aug 6 17:35:10 2025 -0400

    SOLR-17827: Remove JXM, SLF4J and Graphite reporters (#3443)
    
    * Deprecate JMX, SLF4J and Graphite reporters
    
    * Bring back client reporter cache
    
    * Add note to Solr 10 changes
---
 .../java/org/apache/solr/core/SolrXmlConfig.java   |  37 +-
 .../metrics/reporters/SolrGraphiteReporter.java    | 117 ----
 .../solr/metrics/reporters/SolrJmxReporter.java    | 254 -------
 .../solr/metrics/reporters/SolrSlf4jReporter.java  | 189 -----
 .../metrics/reporters/jmx/JmxMetricsReporter.java  | 777 ---------------------
 .../reporters/jmx/JmxObjectNameFactory.java        | 169 -----
 .../solr/metrics/reporters/jmx/package-info.java   |  22 -
 .../org/apache/solr/core/TestJmxIntegration.java   | 279 --------
 .../apache/solr/metrics/SolrMetricManagerTest.java |  71 --
 .../solr/metrics/SolrMetricsIntegrationTest.java   |  64 --
 .../reporters/SolrGraphiteReporterTest.java        | 123 ----
 .../reporters/SolrJmxReporterCloudTest.java        | 128 ----
 .../metrics/reporters/SolrJmxReporterTest.java     | 316 ---------
 .../metrics/reporters/SolrSlf4jReporterTest.java   | 115 ---
 .../pages/major-changes-in-solr-10.adoc            |   2 +
 .../src/java/org/apache/solr/util/TestHarness.java |  12 +-
 16 files changed, 4 insertions(+), 2671 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java 
b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
index 18fdcf8be57..20b16b53726 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
@@ -27,7 +27,6 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -37,7 +36,6 @@ import java.util.Set;
 import java.util.function.Consumer;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import javax.management.MBeanServer;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.cloud.ClusterSingleton;
 import org.apache.solr.cluster.placement.PlacementPluginFactory;
@@ -49,13 +47,11 @@ import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.logging.LogWatcherConfig;
-import org.apache.solr.metrics.reporters.SolrJmxReporter;
 import org.apache.solr.search.CacheConfig;
 import org.apache.solr.servlet.SolrDispatchFilter;
 import org.apache.solr.update.UpdateShardHandlerConfig;
 import org.apache.solr.util.DOMConfigNode;
 import org.apache.solr.util.DataConfigNode;
-import org.apache.solr.util.JmxUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.InputSource;
@@ -742,8 +738,7 @@ public class SolrXmlConfig {
                   : 
Integer.parseInt(threadsCachingIntervalSeconds.toString())));
     }
 
-    PluginInfo[] reporterPlugins = getMetricReporterPluginInfos(metrics);
-    return builder.setMetricReporterPlugins(reporterPlugins).build();
+    return builder.build();
   }
 
   private static Map<String, CacheConfig> getCachesConfig(
@@ -773,36 +768,6 @@ public class SolrXmlConfig {
     return o;
   }
 
-  private static PluginInfo[] getMetricReporterPluginInfos(ConfigNode metrics) 
{
-    List<PluginInfo> configs = new ArrayList<>();
-    boolean hasJmxReporter = false;
-    for (ConfigNode node : metrics.getAll("reporter")) {
-      PluginInfo info = getPluginInfo(node);
-      if (info == null) {
-        continue;
-      }
-      String clazz = info.className;
-      if (clazz != null && clazz.equals(SolrJmxReporter.class.getName())) {
-        hasJmxReporter = true;
-      }
-      configs.add(info);
-    }
-
-    // if there's an MBean server running but there was no JMX reporter then 
add a default one
-    MBeanServer mBeanServer = JmxUtil.findFirstMBeanServer();
-    if (mBeanServer != null && !hasJmxReporter) {
-      log.debug(
-          "MBean server found: {}, but no JMX reporters were configured - 
adding default JMX reporter.",
-          mBeanServer);
-      Map<String, Object> attributes = new HashMap<>();
-      attributes.put("name", "default");
-      attributes.put("class", SolrJmxReporter.class.getName());
-      PluginInfo defaultPlugin = new PluginInfo("reporter", attributes);
-      configs.add(defaultPlugin);
-    }
-    return configs.toArray(new PluginInfo[0]);
-  }
-
   /**
    * Deprecated as of 9.3, will be removed in 10.0
    *
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
 
b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
deleted file mode 100644
index b63fbbcd28b..00000000000
--- 
a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrGraphiteReporter.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters;
-
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.graphite.Graphite;
-import com.codahale.metrics.graphite.GraphiteReporter;
-import com.codahale.metrics.graphite.GraphiteSender;
-import com.codahale.metrics.graphite.PickledGraphite;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-import org.apache.solr.metrics.FilteringSolrMetricReporter;
-import org.apache.solr.metrics.SolrMetricManager;
-
-/** Metrics reporter that wraps {@link 
com.codahale.metrics.graphite.GraphiteReporter}. */
-public class SolrGraphiteReporter extends FilteringSolrMetricReporter {
-
-  private String host = null;
-  private int port = -1;
-  private boolean pickled = false;
-  private String instancePrefix = null;
-  private GraphiteReporter reporter = null;
-
-  private static final ReporterClientCache<GraphiteSender> serviceRegistry =
-      new ReporterClientCache<>();
-
-  /**
-   * Create a Graphite reporter for metrics managed in a named registry.
-   *
-   * @param metricManager metric manager instance that manages the selected 
registry
-   * @param registryName registry to use, one of registries managed by {@link 
SolrMetricManager}
-   */
-  public SolrGraphiteReporter(SolrMetricManager metricManager, String 
registryName) {
-    super(metricManager, registryName);
-  }
-
-  public void setHost(String host) {
-    this.host = host;
-  }
-
-  public void setPort(int port) {
-    this.port = port;
-  }
-
-  public void setPrefix(String prefix) {
-    this.instancePrefix = prefix;
-  }
-
-  public void setPickled(boolean pickled) {
-    this.pickled = pickled;
-  }
-
-  @Override
-  protected void doInit() {
-    if (reporter != null) {
-      throw new IllegalStateException("Already started once?");
-    }
-    GraphiteSender graphite;
-    String id = host + ":" + port + ":" + pickled;
-    if (pickled) {
-      graphite = new PickledGraphite(host, port);
-    } else {
-      graphite = new Graphite(host, port);
-    }
-    if (instancePrefix == null) {
-      instancePrefix = registryName;
-    } else {
-      instancePrefix = instancePrefix + "." + registryName;
-    }
-    GraphiteReporter.Builder builder =
-        GraphiteReporter.forRegistry(metricManager.registry(registryName))
-            .prefixedWith(instancePrefix)
-            .convertRatesTo(TimeUnit.SECONDS)
-            .convertDurationsTo(TimeUnit.MILLISECONDS);
-    final MetricFilter filter = newMetricFilter();
-    builder = builder.filter(filter);
-    reporter = builder.build(graphite);
-    reporter.start(period, TimeUnit.SECONDS);
-  }
-
-  @Override
-  protected void validate() throws IllegalStateException {
-    if (host == null) {
-      throw new IllegalStateException(
-          "Init argument 'host' must be set to a valid Graphite server name.");
-    }
-    if (port == -1) {
-      throw new IllegalStateException(
-          "Init argument 'port' must be set to a valid Graphite server port.");
-    }
-    if (period < 1) {
-      throw new IllegalStateException(
-          "Init argument 'period' is in time unit 'seconds' and must be at 
least 1.");
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    if (reporter != null) {
-      reporter.close();
-    }
-  }
-}
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java 
b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
deleted file mode 100644
index bbcaa8a494a..00000000000
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters;
-
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.MetricRegistry;
-import java.lang.invoke.MethodHandles;
-import java.util.Locale;
-import javax.management.MBeanServer;
-import org.apache.solr.metrics.FilteringSolrMetricReporter;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.metrics.reporters.jmx.JmxMetricsReporter;
-import org.apache.solr.metrics.reporters.jmx.JmxObjectNameFactory;
-import org.apache.solr.util.JmxUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A {@link SolrMetricReporter} that finds (or creates) a MBeanServer from the 
given configuration
- * and registers metrics to it with JMX.
- *
- * <p>NOTE: {@link com.codahale.metrics.jmx.JmxReporter} that this class uses 
exports only newly
- * added metrics (it doesn't process already existing metrics in a registry)
- */
-// NOCOMMIT: This JMX reporter looks to be wrapped over a Dropwizard registry. 
We need to migrate
-// this to OTEL. Maybe we can look at available otel shims for JMX?
-public class SolrJmxReporter extends FilteringSolrMetricReporter {
-
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private static final ReporterClientCache<MBeanServer> serviceRegistry =
-      new ReporterClientCache<>();
-
-  private String domain;
-  private String agentId;
-  private String serviceUrl;
-  private String rootName;
-
-  private MetricRegistry registry;
-  private MBeanServer mBeanServer;
-  private JmxMetricsReporter reporter;
-  private String instanceTag;
-  private boolean started;
-
-  /**
-   * Creates a new instance of {@link SolrJmxReporter}.
-   *
-   * @param registryName name of the registry to report
-   */
-  public SolrJmxReporter(SolrMetricManager metricManager, String registryName) 
{
-    super(metricManager, registryName);
-    period = 0; // setting to zero to indicate not applicable
-    setDomain(registryName);
-  }
-
-  @Override
-  protected synchronized void doInit() {
-    if (serviceUrl != null && agentId != null) {
-      mBeanServer = JmxUtil.findFirstMBeanServer();
-      log.warn(
-          "No more than one of serviceUrl({}) and agentId({}) should be 
configured, using first MBeanServer {} instead of configuration.",
-          serviceUrl,
-          agentId,
-          mBeanServer);
-    } else if (serviceUrl != null) {
-      // reuse existing services
-      mBeanServer =
-          serviceRegistry.getOrCreate(
-              serviceUrl, () -> 
JmxUtil.findMBeanServerForServiceUrl(serviceUrl));
-    } else if (agentId != null) {
-      mBeanServer = JmxUtil.findMBeanServerForAgentId(agentId);
-    } else {
-      mBeanServer = JmxUtil.findFirstMBeanServer();
-      log.debug(
-          "No serviceUrl or agentId was configured, using first MBeanServer: 
{}", mBeanServer);
-    }
-
-    if (mBeanServer == null) {
-      log.warn("No JMX server found. Not exposing Solr metrics via JMX.");
-      return;
-    }
-
-    if (domain == null || domain.isEmpty()) {
-      domain = registryName;
-    }
-    String fullDomain = domain;
-    if (rootName != null && !rootName.isEmpty()) {
-      fullDomain = rootName + "." + domain;
-    }
-    JmxObjectNameFactory jmxObjectNameFactory =
-        new JmxObjectNameFactory(pluginInfo.name, fullDomain);
-    registry = metricManager.registry(registryName);
-
-    final MetricFilter filter = newMetricFilter();
-    instanceTag = Integer.toHexString(this.hashCode());
-    reporter =
-        JmxMetricsReporter.forRegistry(registry)
-            .registerWith(mBeanServer)
-            .inDomain(fullDomain)
-            .filter(filter)
-            .createsObjectNamesWith(jmxObjectNameFactory)
-            .withTag(instanceTag)
-            .build();
-    reporter.start();
-    started = true;
-    log.debug(
-        "JMX monitoring for '{}' (registry '{}') enabled at server: {}",
-        fullDomain,
-        registryName,
-        mBeanServer);
-  }
-
-  /** For unit tests. */
-  public String getInstanceTag() {
-    return instanceTag;
-  }
-
-  /** Stops the reporter from publishing metrics. */
-  @Override
-  public synchronized void close() {
-    log.debug("Closing reporter {} for registry {}/{}", this, registryName, 
registry);
-    started = false;
-    if (reporter != null) {
-      reporter.close();
-      reporter = null;
-    }
-  }
-
-  /**
-   * Validates that the reporter has been correctly configured. Note that all 
configurable arguments
-   * are currently optional.
-   *
-   * @throws IllegalStateException if the reporter is not properly configured
-   */
-  @Override
-  protected void validate() throws IllegalStateException {
-    if (period != 0) {
-      throw new IllegalStateException(
-          "Init argument 'period' is not supported for " + 
getClass().getCanonicalName());
-    }
-  }
-
-  /**
-   * Set root name of the JMX hierarchy for this reporter. Default (null or 
empty) is none, ie. the
-   * hierarchy will start from the domain name.
-   *
-   * @param rootName root name of the JMX name hierarchy, or null or empty for 
default.
-   */
-  public void setRootName(String rootName) {
-    this.rootName = rootName;
-  }
-
-  /**
-   * Sets the domain with which MBeans are published. If none is set, the 
domain defaults to the
-   * name of the registry.
-   *
-   * @param domain the domain
-   */
-  public void setDomain(String domain) {
-    if (domain != null) {
-      this.domain = domain;
-    } else {
-      this.domain = registryName;
-    }
-  }
-
-  /**
-   * Sets the service url for a JMX server. Note that this configuration is 
optional.
-   *
-   * @param serviceUrl the service url
-   */
-  public void setServiceUrl(String serviceUrl) {
-    this.serviceUrl = serviceUrl;
-  }
-
-  /**
-   * Sets the agent id for a JMX server. Note that this configuration is 
optional.
-   *
-   * @param agentId the agent id
-   */
-  public void setAgentId(String agentId) {
-    this.agentId = agentId;
-  }
-
-  /** Return configured agentId or null. */
-  public String getAgentId() {
-    return agentId;
-  }
-
-  /** Return configured serviceUrl or null. */
-  public String getServiceUrl() {
-    return serviceUrl;
-  }
-
-  /** Return configured domain or null. */
-  public String getDomain() {
-    return domain;
-  }
-
-  /**
-   * Return the reporter's MBeanServer.
-   *
-   * @return the reporter's MBeanServer
-   */
-  public MBeanServer getMBeanServer() {
-    return mBeanServer;
-  }
-
-  /**
-   * For unit tests.
-   *
-   * @return true if this reporter is going to report metrics to JMX.
-   */
-  public boolean isActive() {
-    return reporter != null;
-  }
-
-  /**
-   * For unit tests.
-   *
-   * @return true if this reporter has been started and is reporting metrics 
to JMX.
-   */
-  public boolean isStarted() {
-    return started;
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        Locale.ENGLISH,
-        "[%s@%s: rootName = %s, domain = %s, service url = %s, agent id = %s]",
-        getClass().getName(),
-        Integer.toHexString(hashCode()),
-        rootName,
-        domain,
-        serviceUrl,
-        agentId);
-  }
-}
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java 
b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
deleted file mode 100644
index 117d414085f..00000000000
--- 
a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrSlf4jReporter.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters;
-
-import com.codahale.metrics.Counter;
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.Meter;
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.ScheduledReporter;
-import com.codahale.metrics.Slf4jReporter;
-import com.codahale.metrics.Timer;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.concurrent.TimeUnit;
-import org.apache.solr.metrics.FilteringSolrMetricReporter;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-
-/**
- * Metrics reporter that wraps {@link com.codahale.metrics.Slf4jReporter}. The 
following init
- * arguments are supported:
- *
- * <ul>
- *   <li><code>period</code>: (optional, int) number of seconds between 
reports, default is 60,
- *   <li><code>prefix</code>: (optional, str) prefix for metric names, in 
addition to registry name.
- *       Default is none, ie. just registry name.
- *   <li><code>filter</code>: (optional, str) if not empty only metric names 
that start with this
- *       value will be reported, default is all metrics from a registry,
- *   <li><code>logger</code>: (optional, str) logger name to use. Default is 
the metrics group, eg.
- *       <code>solr.jvm</code>, <code>solr.core</code>, etc
- * </ul>
- */
-// NOCOMMIT: Will we still be supporting this? Need to understand how Slf4j 
works and if it is even
-// possible to wrap OTEL into this like dropwizard.
-public class SolrSlf4jReporter extends FilteringSolrMetricReporter {
-
-  @SuppressWarnings("unused") // we need this to pass validate-source-patterns
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private String instancePrefix = null;
-  private String logger = null;
-  private Map<String, String> mdcContext;
-  private Slf4jReporterWrapper reporter;
-  private boolean active;
-
-  // this wrapper allows us to set MDC context - unfortunately it's not 
possible to
-  // simply override {@link Slf4jReporter#report()} because its constructor is 
private
-  private class Slf4jReporterWrapper extends ScheduledReporter {
-    final Slf4jReporter delegate;
-    final Map<String, String> mdcContext;
-
-    Slf4jReporterWrapper(
-        String logger,
-        Map<String, String> mdcContext,
-        Slf4jReporter delegate,
-        TimeUnit rateUnit,
-        TimeUnit durationUnit) {
-      super(metricManager.registry(registryName), logger, null, rateUnit, 
durationUnit);
-      this.delegate = delegate;
-      this.mdcContext = mdcContext;
-    }
-
-    @Override
-    public void report() {
-      // set up MDC
-      MDC.setContextMap(mdcContext);
-      try {
-        delegate.report();
-      } finally {
-        // clear MDC
-        MDC.clear();
-      }
-    }
-
-    @Override
-    @SuppressWarnings(
-        "rawtypes") // super uses raw Gauge, so we're stuck with it until 
DropWizard 5.0
-    public void report(
-        SortedMap<String, Gauge> gauges,
-        SortedMap<String, Counter> counters,
-        SortedMap<String, Histogram> histograms,
-        SortedMap<String, Meter> meters,
-        SortedMap<String, Timer> timers) {
-      throw new UnsupportedOperationException("this method should never be 
called here!");
-    }
-
-    @Override
-    public void close() {
-      super.close();
-      delegate.close();
-    }
-  }
-
-  /**
-   * Create a SLF4J reporter for metrics managed in a named registry.
-   *
-   * @param metricManager metric manager instance that manages the selected 
registry
-   * @param registryName registry to use, one of registries managed by {@link 
SolrMetricManager}
-   */
-  public SolrSlf4jReporter(SolrMetricManager metricManager, String 
registryName) {
-    super(metricManager, registryName);
-  }
-
-  public void setPrefix(String prefix) {
-    this.instancePrefix = prefix;
-  }
-
-  public void setLogger(String logger) {
-    this.logger = logger;
-  }
-
-  @Override
-  protected void doInit() {
-    mdcContext = MDC.getCopyOfContextMap();
-    mdcContext.put("registry", "m:" + registryName);
-    Slf4jReporter.Builder builder =
-        Slf4jReporter.forRegistry(metricManager.registry(registryName))
-            .convertRatesTo(TimeUnit.SECONDS)
-            .convertDurationsTo(TimeUnit.MILLISECONDS);
-
-    final MetricFilter filter = newMetricFilter();
-    builder = builder.filter(filter);
-    if (instancePrefix != null) {
-      builder = builder.prefixedWith(instancePrefix);
-    }
-    if (logger == null || logger.isEmpty()) {
-      // construct logger name from Group
-      if (pluginInfo.attributes.containsKey("group")) {
-        logger = 
SolrMetricManager.enforcePrefix(pluginInfo.attributes.get("group"));
-      } else if (pluginInfo.attributes.containsKey("registry")) {
-        String reg = 
SolrMetricManager.enforcePrefix(pluginInfo.attributes.get("registry"));
-        String[] names = reg.split("\\.");
-        if (names.length < 2) {
-          logger = reg;
-        } else {
-          logger = names[0] + "." + names[1];
-        }
-      }
-    }
-    builder = builder.outputTo(LoggerFactory.getLogger(logger));
-    // build BUT don't start - scheduled execution is handled by the wrapper
-    Slf4jReporter delegate = builder.build();
-    reporter =
-        new Slf4jReporterWrapper(
-            logger, mdcContext, delegate, TimeUnit.SECONDS, 
TimeUnit.MILLISECONDS);
-    reporter.start(period, TimeUnit.SECONDS);
-    active = true;
-  }
-
-  @Override
-  protected void validate() throws IllegalStateException {
-    if (period < 1) {
-      throw new IllegalStateException(
-          "Init argument 'period' is in time unit 'seconds' and must be at 
least 1.");
-    }
-  }
-
-  @Override
-  public void close() throws IOException {
-    if (reporter != null) {
-      reporter.close();
-    }
-    active = false;
-  }
-
-  // for unit tests
-  boolean isActive() {
-    return active;
-  }
-}
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxMetricsReporter.java
 
b/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxMetricsReporter.java
deleted file mode 100644
index bd9eb1b2b21..00000000000
--- 
a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxMetricsReporter.java
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters.jmx;
-
-import com.codahale.metrics.Counter;
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.Meter;
-import com.codahale.metrics.Metered;
-import com.codahale.metrics.Metric;
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.MetricRegistryListener;
-import com.codahale.metrics.Reporter;
-import com.codahale.metrics.Timer;
-import com.codahale.metrics.jmx.DefaultObjectNameFactory;
-import com.codahale.metrics.jmx.ObjectNameFactory;
-import java.io.Closeable;
-import java.lang.invoke.MethodHandles;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryExp;
-import org.apache.solr.metrics.MetricsMap;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is a modified copy of Dropwizard's {@link 
com.codahale.metrics.jmx.JmxReporter} and classes
- * that it internally uses, with a few important differences:
- *
- * <ul>
- *   <li>this class knows that it can directly use {@link MetricsMap} as a 
dynamic MBean.
- *   <li>this class allows us to "tag" MBean instances so that we can later 
unregister only
- *       instances registered with the same tag.
- *   <li>this class processes all metrics already existing in the registry at 
the time when reporter
- *       is started.
- * </ul>
- */
-public class JmxMetricsReporter implements Reporter, Closeable {
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  public static final String INSTANCE_TAG = "_instanceTag";
-
-  public static Builder forRegistry(MetricRegistry registry) {
-    return new Builder(registry);
-  }
-
-  /** Builder for the {@link JmxMetricsReporter} class. */
-  public static class Builder {
-    private final MetricRegistry registry;
-    private MBeanServer mBeanServer;
-    private TimeUnit rateUnit;
-    private TimeUnit durationUnit;
-    private ObjectNameFactory objectNameFactory;
-    private MetricFilter filter = MetricFilter.ALL;
-    private String domain;
-    private String tag;
-
-    private Builder(MetricRegistry registry) {
-      this.registry = registry;
-      this.rateUnit = TimeUnit.SECONDS;
-      this.durationUnit = TimeUnit.MILLISECONDS;
-      this.domain = "metrics";
-      this.objectNameFactory = new DefaultObjectNameFactory();
-    }
-
-    /**
-     * Register MBeans with the given {@link MBeanServer}.
-     *
-     * @param mBeanServer an {@link MBeanServer}
-     * @return {@code this}
-     */
-    public Builder registerWith(MBeanServer mBeanServer) {
-      this.mBeanServer = mBeanServer;
-      return this;
-    }
-
-    /**
-     * Convert rates to the given time unit.
-     *
-     * @param rateUnit a unit of time
-     * @return {@code this}
-     */
-    public Builder convertRatesTo(TimeUnit rateUnit) {
-      this.rateUnit = rateUnit;
-      return this;
-    }
-
-    public Builder createsObjectNamesWith(ObjectNameFactory onFactory) {
-      if (onFactory == null) {
-        throw new IllegalArgumentException("null objectNameFactory");
-      }
-      this.objectNameFactory = onFactory;
-      return this;
-    }
-
-    /**
-     * Convert durations to the given time unit.
-     *
-     * @param durationUnit a unit of time
-     * @return {@code this}
-     */
-    public Builder convertDurationsTo(TimeUnit durationUnit) {
-      this.durationUnit = durationUnit;
-      return this;
-    }
-
-    /**
-     * Only report metrics which match the given filter.
-     *
-     * @param filter a {@link MetricFilter}
-     * @return {@code this}
-     */
-    public Builder filter(MetricFilter filter) {
-      this.filter = filter;
-      return this;
-    }
-
-    public Builder inDomain(String domain) {
-      this.domain = domain;
-      return this;
-    }
-
-    public Builder withTag(String tag) {
-      this.tag = tag;
-      return this;
-    }
-
-    public JmxMetricsReporter build() {
-      if (tag == null) {
-        tag = Integer.toHexString(this.hashCode());
-      }
-      return new JmxMetricsReporter(
-          mBeanServer, domain, registry, filter, rateUnit, durationUnit, 
objectNameFactory, tag);
-    }
-  }
-
-  // MBean interfaces and base classes
-  public interface MetricMBean {
-    ObjectName objectName();
-
-    // this strange-looking method name is used for producing "_instanceTag" 
attribute name
-    String get_instanceTag();
-  }
-
-  private abstract static class AbstractBean implements MetricMBean {
-    private final ObjectName objectName;
-    private final String instanceTag;
-
-    AbstractBean(ObjectName objectName, String instanceTag) {
-      this.objectName = objectName;
-      this.instanceTag = instanceTag;
-    }
-
-    @Override
-    public String get_instanceTag() {
-      return instanceTag;
-    }
-
-    @Override
-    public ObjectName objectName() {
-      return objectName;
-    }
-  }
-
-  public interface JmxGaugeMBean extends MetricMBean {
-    Object getValue();
-  }
-
-  private static class JmxGauge extends AbstractBean implements JmxGaugeMBean {
-    private final Gauge<?> metric;
-
-    private JmxGauge(Gauge<?> metric, ObjectName objectName, String tag) {
-      super(objectName, tag);
-      this.metric = metric;
-    }
-
-    @Override
-    public Object getValue() {
-      return metric.getValue();
-    }
-  }
-
-  public interface JmxCounterMBean extends MetricMBean {
-    long getCount();
-  }
-
-  private static class JmxCounter extends AbstractBean implements 
JmxCounterMBean {
-    private final Counter metric;
-
-    private JmxCounter(Counter metric, ObjectName objectName, String tag) {
-      super(objectName, tag);
-      this.metric = metric;
-    }
-
-    @Override
-    public long getCount() {
-      return metric.getCount();
-    }
-  }
-
-  public interface JmxHistogramMBean extends MetricMBean {
-    long getCount();
-
-    long getMin();
-
-    long getMax();
-
-    double getMean();
-
-    double getStdDev();
-
-    double get50thPercentile();
-
-    double get75thPercentile();
-
-    double get95thPercentile();
-
-    double get98thPercentile();
-
-    double get99thPercentile();
-
-    double get999thPercentile();
-
-    long[] values();
-
-    long getSnapshotSize();
-  }
-
-  private static class JmxHistogram extends AbstractBean implements 
JmxHistogramMBean {
-    private final Histogram metric;
-
-    private JmxHistogram(Histogram metric, ObjectName objectName, String tag) {
-      super(objectName, tag);
-      this.metric = metric;
-    }
-
-    @Override
-    public double get50thPercentile() {
-      return metric.getSnapshot().getMedian();
-    }
-
-    @Override
-    public long getCount() {
-      return metric.getCount();
-    }
-
-    @Override
-    public long getMin() {
-      return metric.getSnapshot().getMin();
-    }
-
-    @Override
-    public long getMax() {
-      return metric.getSnapshot().getMax();
-    }
-
-    @Override
-    public double getMean() {
-      return metric.getSnapshot().getMean();
-    }
-
-    @Override
-    public double getStdDev() {
-      return metric.getSnapshot().getStdDev();
-    }
-
-    @Override
-    public double get75thPercentile() {
-      return metric.getSnapshot().get75thPercentile();
-    }
-
-    @Override
-    public double get95thPercentile() {
-      return metric.getSnapshot().get95thPercentile();
-    }
-
-    @Override
-    public double get98thPercentile() {
-      return metric.getSnapshot().get98thPercentile();
-    }
-
-    @Override
-    public double get99thPercentile() {
-      return metric.getSnapshot().get99thPercentile();
-    }
-
-    @Override
-    public double get999thPercentile() {
-      return metric.getSnapshot().get999thPercentile();
-    }
-
-    @Override
-    public long[] values() {
-      return metric.getSnapshot().getValues();
-    }
-
-    @Override
-    public long getSnapshotSize() {
-      return metric.getSnapshot().size();
-    }
-  }
-
-  public interface JmxMeterMBean extends MetricMBean {
-    long getCount();
-
-    double getMeanRate();
-
-    double getOneMinuteRate();
-
-    double getFiveMinuteRate();
-
-    double getFifteenMinuteRate();
-
-    String getRateUnit();
-  }
-
-  private static class JmxMeter extends AbstractBean implements JmxMeterMBean {
-    private final Metered metric;
-    private final double rateFactor;
-    private final String rateUnit;
-
-    private JmxMeter(Metered metric, ObjectName objectName, TimeUnit rateUnit, 
String tag) {
-      super(objectName, tag);
-      this.metric = metric;
-      this.rateFactor = rateUnit.toSeconds(1);
-      this.rateUnit = ("events/" + calculateRateUnit(rateUnit)).intern();
-    }
-
-    @Override
-    public long getCount() {
-      return metric.getCount();
-    }
-
-    @Override
-    public double getMeanRate() {
-      return metric.getMeanRate() * rateFactor;
-    }
-
-    @Override
-    public double getOneMinuteRate() {
-      return metric.getOneMinuteRate() * rateFactor;
-    }
-
-    @Override
-    public double getFiveMinuteRate() {
-      return metric.getFiveMinuteRate() * rateFactor;
-    }
-
-    @Override
-    public double getFifteenMinuteRate() {
-      return metric.getFifteenMinuteRate() * rateFactor;
-    }
-
-    @Override
-    public String getRateUnit() {
-      return rateUnit;
-    }
-
-    private String calculateRateUnit(TimeUnit unit) {
-      final String s = unit.toString().toLowerCase(Locale.US);
-      return s.substring(0, s.length() - 1);
-    }
-  }
-
-  public interface JmxTimerMBean extends JmxMeterMBean {
-    double getMin();
-
-    double getMax();
-
-    double getMean();
-
-    double getStdDev();
-
-    double get50thPercentile();
-
-    double get75thPercentile();
-
-    double get95thPercentile();
-
-    double get98thPercentile();
-
-    double get99thPercentile();
-
-    double get999thPercentile();
-
-    long[] values();
-
-    String getDurationUnit();
-  }
-
-  private static class JmxTimer extends JmxMeter implements JmxTimerMBean {
-    private final Timer metric;
-    private final double durationFactor;
-    private final String durationUnit;
-
-    private JmxTimer(
-        Timer metric, ObjectName objectName, TimeUnit rateUnit, TimeUnit 
durationUnit, String tag) {
-      super(metric, objectName, rateUnit, tag);
-      this.metric = metric;
-      this.durationFactor = 1.0 / durationUnit.toNanos(1);
-      this.durationUnit = durationUnit.toString().toLowerCase(Locale.US);
-    }
-
-    @Override
-    public double get50thPercentile() {
-      return metric.getSnapshot().getMedian() * durationFactor;
-    }
-
-    @Override
-    public double getMin() {
-      return metric.getSnapshot().getMin() * durationFactor;
-    }
-
-    @Override
-    public double getMax() {
-      return metric.getSnapshot().getMax() * durationFactor;
-    }
-
-    @Override
-    public double getMean() {
-      return metric.getSnapshot().getMean() * durationFactor;
-    }
-
-    @Override
-    public double getStdDev() {
-      return metric.getSnapshot().getStdDev() * durationFactor;
-    }
-
-    @Override
-    public double get75thPercentile() {
-      return metric.getSnapshot().get75thPercentile() * durationFactor;
-    }
-
-    @Override
-    public double get95thPercentile() {
-      return metric.getSnapshot().get95thPercentile() * durationFactor;
-    }
-
-    @Override
-    public double get98thPercentile() {
-      return metric.getSnapshot().get98thPercentile() * durationFactor;
-    }
-
-    @Override
-    public double get99thPercentile() {
-      return metric.getSnapshot().get99thPercentile() * durationFactor;
-    }
-
-    @Override
-    public double get999thPercentile() {
-      return metric.getSnapshot().get999thPercentile() * durationFactor;
-    }
-
-    @Override
-    public long[] values() {
-      return metric.getSnapshot().getValues();
-    }
-
-    @Override
-    public String getDurationUnit() {
-      return durationUnit;
-    }
-  }
-
-  private static class JmxListener implements MetricRegistryListener {
-
-    private final String name;
-    private final MBeanServer mBeanServer;
-    private final MetricFilter filter;
-    private final TimeUnit rateUnit;
-    private final TimeUnit durationUnit;
-    private final Map<ObjectName, ObjectName> registered;
-    private final ObjectNameFactory objectNameFactory;
-    private final String tag;
-    private final QueryExp exp;
-
-    private JmxListener(
-        MBeanServer mBeanServer,
-        String name,
-        MetricFilter filter,
-        TimeUnit rateUnit,
-        TimeUnit durationUnit,
-        ObjectNameFactory objectNameFactory,
-        String tag) {
-      this.mBeanServer = mBeanServer;
-      this.name = name;
-      this.filter = filter;
-      this.rateUnit = rateUnit;
-      this.durationUnit = durationUnit;
-      this.registered = new ConcurrentHashMap<>();
-      this.objectNameFactory = objectNameFactory;
-      this.tag = tag;
-      this.exp = Query.eq(Query.attr(INSTANCE_TAG), Query.value(tag));
-    }
-
-    private void registerMBean(Object mBean, ObjectName objectName)
-        throws InstanceAlreadyExistsException, JMException {
-      // remove previous bean if exists
-      if (mBeanServer.isRegistered(objectName)) {
-        if (log.isDebugEnabled()) {
-          Set<ObjectInstance> objects = mBeanServer.queryMBeans(objectName, 
null);
-          if (log.isDebugEnabled()) {
-            log.debug(
-                "## removing existing {} bean(s) for {}, current tag={}:",
-                objects.size(),
-                objectName.getCanonicalName(),
-                tag);
-          }
-          for (ObjectInstance inst : objects) {
-            if (log.isDebugEnabled()) {
-              log.debug(
-                  "## - tag={}", 
mBeanServer.getAttribute(inst.getObjectName(), INSTANCE_TAG));
-            }
-          }
-        }
-        mBeanServer.unregisterMBean(objectName);
-      }
-      ObjectInstance objectInstance = mBeanServer.registerMBean(mBean, 
objectName);
-      if (objectInstance != null) {
-        // the websphere mbeanserver rewrites the objectname to include
-        // cell, node & server info
-        // make sure we capture the new objectName for unregistration
-        registered.put(objectName, objectInstance.getObjectName());
-      } else {
-        registered.put(objectName, objectName);
-      }
-      if (log.isDebugEnabled()) {
-        log.debug(
-            "## registered {}, tag={}", 
objectInstance.getObjectName().getCanonicalName(), tag);
-      }
-    }
-
-    private void unregisterMBean(ObjectName originalObjectName)
-        throws InstanceNotFoundException, MBeanRegistrationException {
-      ObjectName objectName = registered.remove(originalObjectName);
-      if (objectName == null) {
-        objectName = originalObjectName;
-      }
-      Set<ObjectInstance> objects = mBeanServer.queryMBeans(objectName, exp);
-      for (ObjectInstance o : objects) {
-        if (log.isDebugEnabled()) {
-          log.debug("## Unregistered {}, tag={}", 
o.getObjectName().getCanonicalName(), tag);
-        }
-        mBeanServer.unregisterMBean(o.getObjectName());
-      }
-    }
-
-    @Override
-    public void onGaugeAdded(String name, Gauge<?> gauge) {
-      try {
-        if (filter.matches(name, gauge)) {
-          final ObjectName objectName = createName("gauges", name);
-          if (gauge instanceof SolrMetricManager.GaugeWrapper
-              && ((SolrMetricManager.GaugeWrapper<?>) gauge).getGauge() 
instanceof MetricsMap mm) {
-            mm.setAttribute(new Attribute(INSTANCE_TAG, tag));
-            // don't wrap it in a JmxGauge, it already supports all necessary 
JMX attributes
-            registerMBean(mm, objectName);
-          } else {
-            registerMBean(new JmxGauge(gauge, objectName, tag), objectName);
-          }
-        }
-      } catch (InstanceAlreadyExistsException e) {
-        log.debug("Unable to register gauge", e);
-      } catch (JMException e) {
-        log.warn("Unable to register gauge", e);
-      }
-    }
-
-    @Override
-    public void onGaugeRemoved(String name) {
-      try {
-        final ObjectName objectName = createName("gauges", name);
-        unregisterMBean(objectName);
-      } catch (InstanceNotFoundException e) {
-        log.debug("Unable to unregister gauge", e);
-      } catch (MBeanRegistrationException e) {
-        log.warn("Unable to unregister gauge", e);
-      }
-    }
-
-    @Override
-    public void onCounterAdded(String name, Counter counter) {
-      try {
-        if (filter.matches(name, counter)) {
-          final ObjectName objectName = createName("counters", name);
-          registerMBean(new JmxCounter(counter, objectName, tag), objectName);
-        }
-      } catch (InstanceAlreadyExistsException e) {
-        log.debug("Unable to register counter", e);
-      } catch (JMException e) {
-        log.warn("Unable to register counter", e);
-      }
-    }
-
-    @Override
-    public void onCounterRemoved(String name) {
-      try {
-        final ObjectName objectName = createName("counters", name);
-        unregisterMBean(objectName);
-      } catch (InstanceNotFoundException e) {
-        log.debug("Unable to unregister counter", e);
-      } catch (MBeanRegistrationException e) {
-        log.warn("Unable to unregister counter", e);
-      }
-    }
-
-    @Override
-    public void onHistogramAdded(String name, Histogram histogram) {
-      try {
-        if (filter.matches(name, histogram)) {
-          final ObjectName objectName = createName("histograms", name);
-          registerMBean(new JmxHistogram(histogram, objectName, tag), 
objectName);
-        }
-      } catch (InstanceAlreadyExistsException e) {
-        log.debug("Unable to register histogram", e);
-      } catch (JMException e) {
-        log.warn("Unable to register histogram", e);
-      }
-    }
-
-    @Override
-    public void onHistogramRemoved(String name) {
-      try {
-        final ObjectName objectName = createName("histograms", name);
-        unregisterMBean(objectName);
-      } catch (InstanceNotFoundException e) {
-        log.debug("Unable to unregister histogram", e);
-      } catch (MBeanRegistrationException e) {
-        log.warn("Unable to unregister histogram", e);
-      }
-    }
-
-    @Override
-    public void onMeterAdded(String name, Meter meter) {
-      try {
-        if (filter.matches(name, meter)) {
-          final ObjectName objectName = createName("meters", name);
-          registerMBean(new JmxMeter(meter, objectName, rateUnit, tag), 
objectName);
-        }
-      } catch (InstanceAlreadyExistsException e) {
-        log.debug("Unable to register meter", e);
-      } catch (JMException e) {
-        log.warn("Unable to register meter", e);
-      }
-    }
-
-    @Override
-    public void onMeterRemoved(String name) {
-      try {
-        final ObjectName objectName = createName("meters", name);
-        unregisterMBean(objectName);
-      } catch (InstanceNotFoundException e) {
-        log.debug("Unable to unregister meter", e);
-      } catch (MBeanRegistrationException e) {
-        log.warn("Unable to unregister meter", e);
-      }
-    }
-
-    @Override
-    public void onTimerAdded(String name, Timer timer) {
-      try {
-        if (filter.matches(name, timer)) {
-          final ObjectName objectName = createName("timers", name);
-          registerMBean(new JmxTimer(timer, objectName, rateUnit, 
durationUnit, tag), objectName);
-        }
-      } catch (InstanceAlreadyExistsException e) {
-        log.debug("Unable to register timer", e);
-      } catch (JMException e) {
-        log.warn("Unable to register timer", e);
-      }
-    }
-
-    @Override
-    public void onTimerRemoved(String name) {
-      try {
-        final ObjectName objectName = createName("timers", name);
-        unregisterMBean(objectName);
-      } catch (InstanceNotFoundException e) {
-        log.debug("Unable to unregister timer", e);
-      } catch (MBeanRegistrationException e) {
-        log.warn("Unable to unregister timer", e);
-      }
-    }
-
-    private ObjectName createName(String type, String name) {
-      return objectNameFactory.createName(type, this.name, name);
-    }
-
-    void unregisterAll() {
-      for (ObjectName name : registered.keySet()) {
-        try {
-          unregisterMBean(name);
-        } catch (InstanceNotFoundException e) {
-          log.debug("Unable to unregister metric", e);
-        } catch (MBeanRegistrationException e) {
-          log.warn("Unable to unregister metric", e);
-        }
-      }
-      registered.clear();
-    }
-  }
-
-  private final MetricRegistry registry;
-  private final JmxListener listener;
-
-  private JmxMetricsReporter(
-      MBeanServer mBeanServer,
-      String domain,
-      MetricRegistry registry,
-      MetricFilter filter,
-      TimeUnit rateUnit,
-      TimeUnit durationUnit,
-      ObjectNameFactory objectNameFactory,
-      String tag) {
-    this.registry = registry;
-    this.listener =
-        new JmxListener(
-            mBeanServer, domain, filter, rateUnit, durationUnit, 
objectNameFactory, tag);
-  }
-
-  public void start() {
-    registry.addListener(listener);
-    // process existing metrics
-    Map<String, Metric> metrics = new HashMap<>(registry.getMetrics());
-    metrics.forEach(
-        (k, v) -> {
-          if (v instanceof Counter) {
-            listener.onCounterAdded(k, (Counter) v);
-          } else if (v instanceof Meter) {
-            listener.onMeterAdded(k, (Meter) v);
-          } else if (v instanceof Histogram) {
-            listener.onHistogramAdded(k, (Histogram) v);
-          } else if (v instanceof Timer) {
-            listener.onTimerAdded(k, (Timer) v);
-          } else if (v instanceof Gauge) {
-            listener.onGaugeAdded(k, (Gauge<?>) v);
-          } else {
-            log.warn("Unknown metric type {} for metric '{}', ignoring", 
v.getClass().getName(), k);
-          }
-        });
-  }
-
-  @Override
-  public void close() {
-    registry.removeListener(listener);
-    listener.unregisterAll();
-  }
-}
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxObjectNameFactory.java
 
b/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxObjectNameFactory.java
deleted file mode 100644
index 2b19344f569..00000000000
--- 
a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/JmxObjectNameFactory.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters.jmx;
-
-import com.codahale.metrics.jmx.ObjectNameFactory;
-import java.util.Arrays;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import org.apache.solr.metrics.SolrMetricInfo;
-
-/** Factory to create MBean names for a given metric. */
-public class JmxObjectNameFactory implements ObjectNameFactory {
-
-  private final String domain;
-  private final String[] subdomains;
-  private final String reporterName;
-  private final String[] props;
-
-  /**
-   * Create ObjectName factory.
-   *
-   * @param reporterName name of the reporter
-   * @param domain JMX domain name
-   * @param additionalProperties additional properties as key, value pairs.
-   */
-  public JmxObjectNameFactory(String reporterName, String domain, String... 
additionalProperties) {
-    this.reporterName = reporterName.replace(":", "_");
-    this.domain = domain;
-    this.subdomains = domain.replace(":", "_").split("\\.");
-    if (additionalProperties != null && (additionalProperties.length % 2) != 
0) {
-      throw new IllegalArgumentException(
-          "additionalProperties length must be even: " + 
Arrays.toString(additionalProperties));
-    }
-    this.props = additionalProperties;
-  }
-
-  /** Return current domain. */
-  public String getDomain() {
-    return domain;
-  }
-
-  /** Return current reporterName. */
-  public String getReporterName() {
-    return reporterName;
-  }
-
-  /**
-   * Create a hierarchical name.
-   *
-   * @param type metric class, eg. "counters", may be null for non-metric 
MBeans
-   * @param currentDomain JMX domain
-   * @param name object name
-   */
-  @Override
-  public ObjectName createName(String type, String currentDomain, String name) 
{
-    SolrMetricInfo metricInfo = SolrMetricInfo.of(name);
-    String safeName = metricInfo != null ? metricInfo.name : name;
-    safeName = safeName.replace(":", "_");
-    // It turns out that ObjectName(String) mostly preserves key ordering
-    // as specified in the constructor (except for the 'type' key that ends
-    // up at top level) - unlike ObjectName(String, Map) constructor
-    // that seems to have a mind of its own...
-    StringBuilder sb = new StringBuilder();
-    if (domain.equals(currentDomain)) {
-      if (subdomains != null && subdomains.length > 1) {
-        // use only first segment as domain
-        sb.append(subdomains[0]);
-        sb.append(':');
-        // use remaining segments as properties
-        for (int i = 1; i < subdomains.length; i++) {
-          if (i > 1) {
-            sb.append(',');
-          }
-          sb.append("dom");
-          sb.append(String.valueOf(i));
-          sb.append('=');
-          sb.append(subdomains[i]);
-        }
-        sb.append(','); // separate from other properties
-      } else {
-        sb.append(currentDomain.replace(":", "_"));
-        sb.append(':');
-      }
-    } else {
-      sb.append(currentDomain);
-      sb.append(':');
-    }
-    if (props != null && props.length > 0) {
-      boolean added = false;
-      for (int i = 0; i < props.length; i += 2) {
-        if (props[i] == null || props[i].isEmpty()) {
-          continue;
-        }
-        if (props[i + 1] == null || props[i + 1].isEmpty()) {
-          continue;
-        }
-        sb.append(',');
-        sb.append(props[i]);
-        sb.append('=');
-        sb.append(props[i + 1]);
-        added = true;
-      }
-      if (added) {
-        sb.append(',');
-      }
-    }
-    if (metricInfo != null) {
-      sb.append("category=");
-      sb.append(metricInfo.category.toString());
-      if (metricInfo.scope != null) {
-        sb.append(",scope=");
-        sb.append(metricInfo.scope);
-      }
-      // we could also split by type, but don't call it 'type' :)
-      // if (type != null) {
-      //   sb.append(",class=");
-      //   sb.append(type);
-      // }
-      sb.append(",name=");
-      sb.append(safeName);
-    } else {
-      // make dotted names into hierarchies
-      String[] path = safeName.split("\\.");
-      for (int i = 0; i < path.length - 1; i++) {
-        if (i > 0) {
-          sb.append(',');
-        }
-        sb.append("name");
-        sb.append(String.valueOf(i));
-        sb.append('=');
-        sb.append(path[i]);
-      }
-      if (path.length > 1) {
-        sb.append(',');
-      }
-      // split by type
-      // if (type != null) {
-      //   sb.append("class=");
-      //   sb.append(type);
-      // }
-      sb.append("name=");
-      sb.append(path[path.length - 1]);
-    }
-
-    ObjectName objectName;
-
-    try {
-      objectName = new ObjectName(sb.toString());
-    } catch (MalformedObjectNameException e) {
-      throw new RuntimeException(sb.toString(), e);
-    }
-
-    return objectName;
-  }
-}
diff --git 
a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/package-info.java 
b/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/package-info.java
deleted file mode 100644
index 2cdd1d68f8d..00000000000
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/jmx/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This package contains components that support {@link
- * org.apache.solr.metrics.reporters.SolrJmxReporter}.
- */
-package org.apache.solr.metrics.reporters.jmx;
diff --git a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java 
b/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
deleted file mode 100644
index f162fe31dce..00000000000
--- a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.core;
-
-import com.codahale.metrics.MetricRegistry;
-import java.lang.invoke.MethodHandles;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.management.AttributeNotFoundException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.metrics.reporters.SolrJmxReporter;
-import org.apache.solr.metrics.reporters.jmx.JmxMetricsReporter;
-import org.apache.solr.metrics.reporters.jmx.JmxObjectNameFactory;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Test for JMX Integration
- *
- * @since solr 1.3
- */
-public class TestJmxIntegration extends SolrTestCaseJ4 {
-
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private static MBeanServer mbeanServer = null;
-  private static MBeanServer newMbeanServer = null;
-  private static JmxObjectNameFactory nameFactory = null;
-  private static String registryName = null;
-
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    // Make sure that at least one MBeanServer is available
-    // prior to initializing the core
-    //
-    // (test configs are set up to use existing server if any,
-    // otherwise skip JMX)
-    newMbeanServer = MBeanServerFactory.createMBeanServer();
-
-    initCore("solrconfig.xml", "schema.xml");
-
-    // we should be able to see that the core has JmxIntegration enabled
-    registryName = h.getCore().getCoreMetricManager().getRegistryName();
-    SolrMetricManager manager = h.getCoreContainer().getMetricManager();
-    Map<String, SolrMetricReporter> reporters = 
manager.getReporters(registryName);
-    assertEquals(1, reporters.size());
-    SolrMetricReporter reporter = reporters.values().iterator().next();
-    assertTrue(reporter instanceof SolrJmxReporter);
-    SolrJmxReporter jmx = (SolrJmxReporter) reporter;
-    assertTrue("JMX not enabled", jmx.isActive());
-    // and we should be able to see that the reporter
-    // refers to the JMX server we started
-
-    mbeanServer = jmx.getMBeanServer();
-
-    assertNotNull("No JMX server found in the reporter", mbeanServer);
-
-    // NOTE: we can't guarantee that "mbeanServer == platformServer"
-    // the JVM may have multiple MBean servers running when the test started
-    // and the contract of not specifying one when configuring solr.xml without
-    // agentId or serviceUrl is that it will use whatever the "first" MBean 
server
-    // returned by the JVM is.
-
-    nameFactory = new JmxObjectNameFactory("default", registryName);
-  }
-
-  @AfterClass
-  public static void afterClass() {
-    if (newMbeanServer != null) {
-      MBeanServerFactory.releaseMBeanServer(newMbeanServer);
-    }
-    mbeanServer = null;
-    newMbeanServer = null;
-  }
-
-  @Before
-  public void resetIndex() {
-    clearIndex();
-    assertU("commit", commit());
-  }
-
-  @Test
-  public void testJmxRegistration() throws Exception {
-    assertTrue("No MBeans found in server", mbeanServer.getMBeanCount() > 0);
-
-    Set<ObjectInstance> objects = mbeanServer.queryMBeans(null, null);
-    assertFalse("No objects found in mbean server", objects.isEmpty());
-    int numDynamicMbeans = 0;
-    for (ObjectInstance o : objects) {
-      ObjectName name = o.getObjectName();
-      assertNotNull("Null name on: " + o, name);
-      MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(name);
-      if (name.getDomain().equals("solr")) {
-        numDynamicMbeans++;
-        MBeanAttributeInfo[] attrs = mbeanInfo.getAttributes();
-        if (name.getKeyProperty("name")
-            .equals("fetcher")) { // no attributes without active replication
-          continue;
-        }
-        assertTrue(
-            "No Attributes found for mbean: " + o.getObjectName() + ", " + 
mbeanInfo,
-            0 < attrs.length);
-        for (MBeanAttributeInfo attr : attrs) {
-          // ensure every advertised attribute is gettable
-          try {
-            Object trash = mbeanServer.getAttribute(o.getObjectName(), 
attr.getName());
-          } catch (javax.management.AttributeNotFoundException e) {
-            throw new RuntimeException(
-                "Unable to fetch attribute for " + o.getObjectName() + ": " + 
attr.getName(), e);
-          }
-        }
-      }
-    }
-    assertTrue("No MBeans found", 0 < numDynamicMbeans);
-  }
-
-  @Test
-  public void testJmxUpdate() throws Exception {
-
-    SolrInfoBean bean = null;
-    // wait until searcher is registered
-    for (int i = 0; i < 100; i++) {
-      bean = h.getCore().getInfoRegistry().get("searcher");
-      if (bean != null) break;
-      Thread.sleep(250);
-    }
-    if (bean == null) throw new RuntimeException("searcher was never 
registered");
-    ObjectName searcher = nameFactory.createName("gauge", registryName, 
"SEARCHER.searcher.*");
-
-    if (log.isInfoEnabled()) {
-      log.info("Mbeans in server: {}", mbeanServer.queryNames(null, null));
-    }
-
-    assertFalse(
-        "No mbean found for SolrIndexSearcher", 
mbeanServer.queryMBeans(searcher, null).isEmpty());
-
-    ObjectName name = nameFactory.createName("gauge", registryName, 
"SEARCHER.searcher.numDocs");
-    int oldNumDocs = (Integer) mbeanServer.getAttribute(name, "Value");
-    assertU(adoc("id", "1"));
-    assertU("commit", commit());
-    int numDocs = (Integer) mbeanServer.getAttribute(name, "Value");
-    assertTrue("New numDocs is same as old numDocs as reported by JMX", 
numDocs > oldNumDocs);
-  }
-
-  @Test
-  @SuppressWarnings({"try"})
-  public void testJmxOnCoreReload() throws Exception {
-    // make sure searcher beans are registered
-    assertQ(req("q", "*:*"), "//result[@numFound='0']");
-
-    SolrMetricManager mgr = h.getCoreContainer().getMetricManager();
-    String registryName = h.getCore().getCoreMetricManager().getRegistryName();
-    String coreName = h.getCore().getName();
-    String coreHashCode = Integer.toHexString(h.getCore().hashCode());
-    Map<String, SolrMetricReporter> reporters = mgr.getReporters(registryName);
-    // take first JMX reporter
-    SolrJmxReporter reporter = null;
-    for (Map.Entry<String, SolrMetricReporter> e : reporters.entrySet()) {
-      if (e.getKey().endsWith(coreHashCode) && e.getValue() instanceof 
SolrJmxReporter) {
-        reporter = (SolrJmxReporter) e.getValue();
-        break;
-      }
-    }
-    assertNotNull("could not find JMX reporter for " + registryName, reporter);
-    String tag = reporter.getInstanceTag();
-
-    Set<ObjectInstance> oldBeans = mbeanServer.queryMBeans(null, null);
-    int oldNumberOfObjects = 0;
-    for (ObjectInstance bean : oldBeans) {
-      try {
-        if (tag.equals(
-            mbeanServer.getAttribute(bean.getObjectName(), 
JmxMetricsReporter.INSTANCE_TAG))) {
-          oldNumberOfObjects++;
-        }
-      } catch (AttributeNotFoundException e) {
-        // expected
-      }
-    }
-
-    int totalCoreMetrics = mgr.registry(registryName).getMetrics().size();
-    log.info(
-        "Before Reload: size of all core metrics: {} MBeans: {}",
-        totalCoreMetrics,
-        oldNumberOfObjects);
-    assertEquals(
-        "Number of registered MBeans is not the same as the number of core 
metrics",
-        totalCoreMetrics,
-        oldNumberOfObjects);
-    h.getCoreContainer().reload(coreName);
-    assertQ(req("q", "*:*"), "//result[@numFound='0']");
-
-    reporters = mgr.getReporters(registryName);
-    coreHashCode = Integer.toHexString(h.getCore().hashCode());
-    // take first JMX reporter
-    reporter = null;
-    for (Map.Entry<String, SolrMetricReporter> e : reporters.entrySet()) {
-      if (e.getKey().endsWith(coreHashCode) && e.getValue() instanceof 
SolrJmxReporter) {
-        reporter = (SolrJmxReporter) e.getValue();
-        break;
-      }
-    }
-    assertNotNull("could not find JMX reporter for " + registryName, reporter);
-    tag = reporter.getInstanceTag();
-
-    Set<ObjectInstance> newBeans = mbeanServer.queryMBeans(null, null);
-    int newNumberOfObjects = 0;
-    Set<String> metricNames = new TreeSet<>();
-    Set<String> beanNames = new TreeSet<>();
-    try (SolrCore core = h.getCoreContainer().getCore(coreName)) {
-      MetricRegistry registry = mgr.registry(registryName);
-      metricNames.addAll(registry.getNames());
-      totalCoreMetrics = registry.getMetrics().size();
-      for (ObjectInstance bean : newBeans) {
-        try {
-          if (tag.equals(
-              mbeanServer.getAttribute(bean.getObjectName(), 
JmxMetricsReporter.INSTANCE_TAG))) {
-            String[] name = 
bean.getObjectName().toString().substring(32).split(",");
-            StringBuilder sb = new StringBuilder();
-            for (String n : name) {
-              if (sb.length() > 0) {
-                sb.append(".");
-              }
-              sb.append(n.split("=")[1]);
-            }
-            beanNames.add(sb.toString());
-            newNumberOfObjects++;
-          }
-        } catch (AttributeNotFoundException e) {
-          // expected
-        }
-      }
-    }
-
-    log.info(
-        "After Reload: size of all core metrics: {} MBeans: {}",
-        totalCoreMetrics,
-        newNumberOfObjects);
-    if (totalCoreMetrics != newNumberOfObjects) {
-      Set<String> errors = new TreeSet<>(beanNames);
-      errors.removeAll(metricNames);
-      log.error("Unexpected bean names: {}", errors);
-      errors = new TreeSet<>(metricNames);
-      errors.removeAll(beanNames);
-      log.error("Unexpected metric names: {}", errors);
-      fail(
-          "Number of registered MBeans is not the same as the number of core 
metrics: "
-              + totalCoreMetrics
-              + " != "
-              + newNumberOfObjects);
-    }
-  }
-}
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java 
b/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
index 2c8f51aec6d..d5701d15111 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricManagerTest.java
@@ -47,8 +47,6 @@ import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.metrics.reporters.MockMetricReporter;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -219,74 +217,6 @@ public class SolrMetricManagerTest extends SolrTestCaseJ4 {
     assertEquals("solr.core." + name + ".collection1.shard1.replica1", result);
   }
 
-  @Test
-  public void testReporters() throws Exception {
-
-    try (SolrResourceLoader loader = new SolrResourceLoader(createTempDir())) {
-      SolrMetricManager metricManager = new SolrMetricManager();
-
-      PluginInfo[] plugins =
-          new PluginInfo[] {
-            createPluginInfo("universal_foo", null, null),
-            createPluginInfo("multigroup_foo", "jvm, node, core", null),
-            createPluginInfo("multiregistry_foo", null, "solr.node, 
solr.core.collection1"),
-            createPluginInfo("specific_foo", null, "solr.core.collection1"),
-            createPluginInfo("node_foo", "node", null),
-            createPluginInfo("core_foo", "core", null)
-          };
-      String tag = "xyz";
-      metricManager.loadReporters(plugins, loader, null, null, tag, 
SolrInfoBean.Group.node);
-      Map<String, SolrMetricReporter> reporters =
-          
metricManager.getReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node));
-
-      assertEquals(4, reporters.size());
-      assertTrue(reporters.containsKey("universal_foo@" + tag));
-      assertTrue(reporters.containsKey("multigroup_foo@" + tag));
-      assertTrue(reporters.containsKey("node_foo@" + tag));
-      assertTrue(reporters.containsKey("multiregistry_foo@" + tag));
-
-      metricManager.loadReporters(
-          plugins, loader, null, null, tag, SolrInfoBean.Group.core, 
"collection1");
-      reporters =
-          metricManager.getReporters(
-              SolrMetricManager.getRegistryName(SolrInfoBean.Group.core, 
"collection1"));
-
-      assertEquals(5, reporters.size());
-      assertTrue(reporters.containsKey("universal_foo@" + tag));
-      assertTrue(reporters.containsKey("multigroup_foo@" + tag));
-      assertTrue(reporters.containsKey("specific_foo@" + tag));
-      assertTrue(reporters.containsKey("core_foo@" + tag));
-      assertTrue(reporters.containsKey("multiregistry_foo@" + tag));
-
-      metricManager.loadReporters(plugins, loader, null, null, tag, 
SolrInfoBean.Group.jvm);
-      reporters =
-          
metricManager.getReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm));
-
-      assertEquals(2, reporters.size());
-      assertTrue(reporters.containsKey("universal_foo@" + tag));
-      assertTrue(reporters.containsKey("multigroup_foo@" + tag));
-
-      metricManager.removeRegistry("solr.jvm");
-      reporters =
-          
metricManager.getReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm));
-
-      assertEquals(0, reporters.size());
-
-      metricManager.removeRegistry("solr.node");
-      reporters =
-          
metricManager.getReporters(SolrMetricManager.getRegistryName(SolrInfoBean.Group.node));
-
-      assertEquals(0, reporters.size());
-
-      metricManager.removeRegistry("solr.core.collection1");
-      reporters =
-          metricManager.getReporters(
-              SolrMetricManager.getRegistryName(SolrInfoBean.Group.core, 
"collection1"));
-
-      assertEquals(0, reporters.size());
-    }
-  }
-
   @Test
   public void testDefaultCloudReporterPeriodUnchanged() {
     assertEquals(60, SolrMetricManager.DEFAULT_CLOUD_REPORTER_PERIOD);
@@ -295,7 +225,6 @@ public class SolrMetricManagerTest extends SolrTestCaseJ4 {
   private PluginInfo createPluginInfo(String name, String group, String 
registry) {
     Map<String, String> attrs = new HashMap<>();
     attrs.put("name", name);
-    attrs.put("class", MockMetricReporter.class.getName());
     if (group != null) {
       attrs.put("group", group);
     }
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java 
b/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java
index 3ae2e6a0810..10704c19fe2 100644
--- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java
@@ -20,17 +20,14 @@ package org.apache.solr.metrics;
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.Timer;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import org.apache.http.client.HttpClient;
 import org.apache.lucene.tests.util.LuceneTestCase;
-import org.apache.lucene.tests.util.TestUtil;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
@@ -42,7 +39,6 @@ import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.core.SolrXmlConfig;
 import org.apache.solr.embedded.JettySolrRunner;
-import org.apache.solr.metrics.reporters.MockMetricReporter;
 import org.apache.solr.util.JmxUtil;
 import org.apache.solr.util.TestHarness;
 import org.hamcrest.number.OrderingComparison;
@@ -131,14 +127,6 @@ public class SolrMetricsIntegrationTest extends 
SolrTestCaseJ4 {
     assertTrue(
         "Reporter '" + MULTIREGISTRY + "' missing in solr.node",
         reporters.containsKey(MULTIREGISTRY));
-    SolrMetricReporter reporter = reporters.get(REPORTER_NAMES[0]);
-    assertTrue(
-        "Reporter " + reporter + " is not an instance of " + 
MockMetricReporter.class.getName(),
-        reporter instanceof MockMetricReporter);
-    reporter = reporters.get(UNIVERSAL);
-    assertTrue(
-        "Reporter " + reporter + " is not an instance of " + 
MockMetricReporter.class.getName(),
-        reporter instanceof MockMetricReporter);
   }
 
   @After
@@ -148,62 +136,10 @@ public class SolrMetricsIntegrationTest extends 
SolrTestCaseJ4 {
     }
 
     SolrCoreMetricManager coreMetricManager = 
h.getCore().getCoreMetricManager();
-    Map<String, SolrMetricReporter> reporters =
-        metricManager.getReporters(coreMetricManager.getRegistryName());
-
     Gauge<?> gauge = (Gauge<?>) 
coreMetricManager.getRegistry().getMetrics().get("CORE.indexDir");
     assertNotNull(gauge.getValue());
     deleteCore(); // closes TestHarness which closes CoreContainer which 
closes SolrCore
     assertEquals(metricManager.nullString(), gauge.getValue());
-
-    for (String reporterName : RENAMED_REPORTERS) {
-      SolrMetricReporter reporter = reporters.get(reporterName + "@" + tag);
-      MockMetricReporter mockReporter = (MockMetricReporter) reporter;
-      assertTrue(
-          "Reporter " + reporterName + " was not closed: " + mockReporter, 
mockReporter.didClose);
-    }
-  }
-
-  @Test
-  public void testConfigureReporter() throws Exception {
-    Random random = random();
-
-    String metricName =
-        SolrMetricManager.mkName(METRIC_NAME, HANDLER_CATEGORY.toString(), 
HANDLER_NAME);
-    SolrCoreMetricManager coreMetricManager = 
h.getCore().getCoreMetricManager();
-    Timer timer = metricManager.timer(null, 
coreMetricManager.getRegistryName(), metricName);
-
-    long initialCount = timer.getCount();
-
-    int iterations = TestUtil.nextInt(random, 0, MAX_ITERATIONS);
-    for (int i = 0; i < iterations; ++i) {
-      h.query(req("*"));
-    }
-
-    long finalCount = timer.getCount();
-    assertEquals("metric counter incorrect", iterations, finalCount - 
initialCount);
-    Map<String, SolrMetricReporter> reporters =
-        metricManager.getReporters(coreMetricManager.getRegistryName());
-    assertEquals(RENAMED_REPORTERS.length + jmxReporter, reporters.size());
-
-    // SPECIFIC and MULTIREGISTRY were skipped because they were
-    // specific to collection1
-    for (String reporterName : RENAMED_REPORTERS) {
-      SolrMetricReporter reporter = reporters.get(reporterName + "@" + tag);
-      assertNotNull("Reporter " + reporterName + " was not found.", reporter);
-      assertTrue(reporter instanceof MockMetricReporter);
-
-      MockMetricReporter mockReporter = (MockMetricReporter) reporter;
-      assertTrue(
-          "Reporter " + reporterName + " was not initialized: " + mockReporter,
-          mockReporter.didInit);
-      assertTrue(
-          "Reporter " + reporterName + " was not validated: " + mockReporter,
-          mockReporter.didValidate);
-      assertFalse(
-          "Reporter " + reporterName + " was incorrectly closed: " + 
mockReporter,
-          mockReporter.didClose);
-    }
   }
 
   @Test
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java
 
b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java
deleted file mode 100644
index da26b845ef0..00000000000
--- 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.solr.metrics.reporters;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.core.CoreContainer;
-import org.apache.solr.core.NodeConfig;
-import org.apache.solr.core.SolrXmlConfig;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.util.JmxUtil;
-import org.apache.solr.util.TestHarness;
-import org.junit.Test;
-
-/** */
-public class SolrGraphiteReporterTest extends SolrTestCaseJ4 {
-
-  @Test
-  public void testReporter() throws Exception {
-    int jmxReporter = JmxUtil.findFirstMBeanServer() != null ? 1 : 0;
-    Path home = TEST_HOME();
-    // define these properties, they are used in solrconfig.xml
-    System.setProperty("solr.test.sys.prop1", "propone");
-    System.setProperty("solr.test.sys.prop2", "proptwo");
-
-    MockGraphite mock = new MockGraphite();
-    try {
-      mock.start();
-      Thread.sleep(1000);
-      // define the port where MockGraphite is running
-      System.setProperty("mock-graphite-port", String.valueOf(mock.port));
-      String solrXml =
-          Files.readString(home.resolve("solr-graphitereporter.xml"), 
StandardCharsets.UTF_8);
-      NodeConfig cfg = SolrXmlConfig.fromString(home, solrXml);
-      CoreContainer cc =
-          createCoreContainer(
-              cfg,
-              new TestHarness.TestCoresLocator(
-                  DEFAULT_TEST_CORENAME,
-                  initAndGetDataDir().toString(),
-                  "solrconfig.xml",
-                  "schema.xml"));
-
-      h.coreName = DEFAULT_TEST_CORENAME;
-      SolrMetricManager metricManager = cc.getMetricManager();
-      Map<String, SolrMetricReporter> reporters = 
metricManager.getReporters("solr.node");
-      assertEquals(1 + jmxReporter, reporters.size());
-      SolrMetricReporter reporter = reporters.get("test");
-      assertNotNull(reporter);
-      assertTrue(reporter instanceof SolrGraphiteReporter);
-      Thread.sleep(5000);
-      assertTrue(mock.lines.size() >= 3);
-      String[] frozenLines = mock.lines.toArray(new String[0]);
-      for (String line : frozenLines) {
-        assertTrue(line, line.startsWith("test.solr.node.CONTAINER.cores."));
-      }
-    } finally {
-      mock.close();
-    }
-  }
-
-  private static class MockGraphite extends Thread {
-    private List<String> lines = new ArrayList<>();
-    private ServerSocket server = null;
-    private int port;
-    private boolean stop;
-
-    MockGraphite() throws Exception {
-      server = new ServerSocket(0);
-      port = server.getLocalPort();
-      stop = false;
-    }
-
-    @Override
-    public void run() {
-      while (!stop) {
-        try {
-          Socket s = server.accept();
-          BufferedReader br =
-              new BufferedReader(new InputStreamReader(s.getInputStream(), 
StandardCharsets.UTF_8));
-          String line;
-          while ((line = br.readLine()) != null) {
-            lines.add(line);
-          }
-        } catch (Exception e) {
-          stop = true;
-        }
-      }
-    }
-
-    public void close() throws Exception {
-      stop = true;
-      if (server != null) {
-        server.close();
-      }
-    }
-  }
-}
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterCloudTest.java
 
b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterCloudTest.java
deleted file mode 100644
index 00a201c2beb..00000000000
--- 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterCloudTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters;
-
-import java.lang.invoke.MethodHandles;
-import java.lang.management.ManagementFactory;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.management.MBeanServer;
-import javax.management.ObjectInstance;
-import javax.management.Query;
-import javax.management.QueryExp;
-import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.request.CollectionAdminRequest;
-import org.apache.solr.cloud.SolrCloudTestCase;
-import org.apache.solr.common.SolrInputDocument;
-import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.embedded.JettySolrRunner;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.metrics.reporters.jmx.JmxMetricsReporter;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** */
-public class SolrJmxReporterCloudTest extends SolrCloudTestCase {
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private static MBeanServer mBeanServer;
-  private static String COLLECTION = 
SolrJmxReporterCloudTest.class.getSimpleName() + "_collection";
-
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    // make sure there's an MBeanServer
-    mBeanServer = ManagementFactory.getPlatformMBeanServer();
-    configureCluster(1).addConfig("conf", 
configset("cloud-minimal")).configure();
-    CollectionAdminRequest.createCollection(COLLECTION, "conf", 2, 1)
-        .process(cluster.getSolrClient());
-  }
-
-  @AfterClass
-  public static void releaseMBeanServer() {
-    mBeanServer = null;
-  }
-
-  @Test
-  public void testJmxReporter() throws Exception {
-    
CollectionAdminRequest.reloadCollection(COLLECTION).processAndWait(cluster.getSolrClient(),
 60);
-    CloudSolrClient solrClient = cluster.getSolrClient();
-    // index some docs
-    for (int i = 0; i < 100; i++) {
-      SolrInputDocument doc = new SolrInputDocument();
-      doc.addField("id", "id-" + i);
-      solrClient.add(COLLECTION, doc);
-    }
-    solrClient.commit(COLLECTION);
-    // make sure searcher is present
-    solrClient.query(COLLECTION, params(CommonParams.Q, "*:*"));
-
-    for (JettySolrRunner runner : cluster.getJettySolrRunners()) {
-      SolrMetricManager manager = runner.getCoreContainer().getMetricManager();
-      for (String registry : manager.registryNames()) {
-        Map<String, SolrMetricReporter> reporters = 
manager.getReporters(registry);
-        long jmxReporters =
-            reporters.entrySet().stream()
-                .filter(e -> e.getValue() instanceof SolrJmxReporter)
-                .count();
-        reporters.forEach(
-            (k, v) -> {
-              if (!(v instanceof SolrJmxReporter)) {
-                return;
-              }
-              if (!((SolrJmxReporter) v).getDomain().startsWith("solr.core")) {
-                return;
-              }
-              if (!((SolrJmxReporter) v).isActive()) {
-                return;
-              }
-              QueryExp exp =
-                  Query.eq(
-                      Query.attr(JmxMetricsReporter.INSTANCE_TAG),
-                      Query.value(Integer.toHexString(v.hashCode())));
-              Set<ObjectInstance> beans = mBeanServer.queryMBeans(null, exp);
-              if (((SolrJmxReporter) v).isStarted() && beans.isEmpty() && 
jmxReporters < 2) {
-                if (log.isInfoEnabled()) {
-                  log.info("DocCollection: {}", 
getCollectionState(COLLECTION));
-                }
-                fail(
-                    "JMX reporter "
-                        + k
-                        + " for registry "
-                        + registry
-                        + " failed to register any beans!");
-              } else {
-                Set<String> categories = new HashSet<>();
-                beans.forEach(
-                    bean -> {
-                      String cat = 
bean.getObjectName().getKeyProperty("category");
-                      if (cat != null) {
-                        categories.add(cat);
-                      }
-                    });
-                log.info("Registered categories: {}", categories);
-                assertTrue("Too few categories: " + categories, 
categories.size() > 5);
-              }
-            });
-      }
-    }
-  }
-}
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java 
b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
deleted file mode 100644
index 25e433b934e..00000000000
--- 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.metrics.reporters;
-
-import com.codahale.metrics.Counter;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import org.apache.lucene.tests.util.LuceneTestCase;
-import org.apache.lucene.tests.util.TestUtil;
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.params.CoreAdminParams;
-import org.apache.solr.core.PluginInfo;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.SolrInfoBean;
-import org.apache.solr.metrics.SolrCoreMetricManager;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricProducer;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.metrics.SolrMetricTestUtils;
-import org.apache.solr.schema.FieldType;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-// NOCOMMIT: All tests failing because of migration for some core metrics 
missing from JMX. See
-// comment on SolrJmxReporter for what we could do.
[email protected](bugUrl = 
"https://issues.apache.org/jira/browse/SOLR-17458";)
-public class SolrJmxReporterTest extends SolrTestCaseJ4 {
-
-  private static final int MAX_ITERATIONS = 20;
-
-  /** The MbeanServer started by the test, that we expect the SolrJmxReporter 
to find by agentId */
-  private static MBeanServer TEST_MBEAN_SERVER;
-
-  private static String PREFIX;
-
-  private String domain;
-
-  private SolrCoreMetricManager coreMetricManager;
-  private SolrMetricManager metricManager;
-  private String rootName;
-
-  @BeforeClass
-  public static void init() {
-    TEST_MBEAN_SERVER = MBeanServerFactory.createMBeanServer();
-    PREFIX = getSimpleClassName() + "-";
-  }
-
-  @AfterClass
-  public static void shutdown() {
-    if (null != TEST_MBEAN_SERVER) {
-      MBeanServerFactory.releaseMBeanServer(TEST_MBEAN_SERVER);
-      TEST_MBEAN_SERVER = null;
-    }
-  }
-
-  @Before
-  public void beforeTest() throws Exception {
-    initCore("solrconfig-basic.xml", "schema.xml");
-
-    final SolrCore core = h.getCore();
-    domain = core.getName();
-    rootName = PREFIX + TestUtil.randomSimpleString(random(), 5, 10);
-
-    coreMetricManager = core.getCoreMetricManager();
-    metricManager = core.getCoreContainer().getMetricManager();
-    PluginInfo pluginInfo = createReporterPluginInfo(rootName, true);
-    metricManager.loadReporter(
-        coreMetricManager.getRegistryName(),
-        coreMetricManager.getCore(),
-        pluginInfo,
-        coreMetricManager.getTag());
-
-    Map<String, SolrMetricReporter> reporters =
-        metricManager.getReporters(coreMetricManager.getRegistryName());
-    assertTrue("reporters.size should be > 0, but was + " + reporters.size(), 
reporters.size() > 0);
-    String reporterName = pluginInfo.name;
-    String taggedName = reporterName + "@" + coreMetricManager.getTag();
-    assertNotNull(
-        "reporter " + taggedName + " not present among " + reporters, 
reporters.get(taggedName));
-    assertTrue(
-        "wrong reporter class: " + reporters.get(taggedName),
-        reporters.get(taggedName) instanceof SolrJmxReporter);
-
-    SolrJmxReporter reporter = (SolrJmxReporter) reporters.get(taggedName);
-    assertNotNull("MBean server not found on reporter", 
reporter.getMBeanServer());
-    assertEquals(
-        "Wrong MBeanServer found on reporter", TEST_MBEAN_SERVER, 
reporter.getMBeanServer());
-  }
-
-  private PluginInfo createReporterPluginInfo(String rootName, boolean 
enabled) {
-    Random random = random();
-    String className = SolrJmxReporter.class.getName();
-    String reporterName = PREFIX + TestUtil.randomSimpleString(random, 5, 10);
-
-    Map<String, Object> attrs = new HashMap<>();
-    attrs.put(FieldType.CLASS_NAME, className);
-    attrs.put(CoreAdminParams.NAME, reporterName);
-    attrs.put("rootName", rootName);
-    attrs.put("enabled", enabled);
-
-    try {
-      String agentId =
-          (String)
-              TEST_MBEAN_SERVER.getAttribute(
-                  new ObjectName("JMImplementation:type=MBeanServerDelegate"), 
"MBeanServerId");
-      attrs.put("agentId", agentId);
-    } catch (Exception e) {
-      throw new RuntimeException(
-          "Unable to determine agentId of MBeanServer: " + e.getMessage(), e);
-    }
-    boolean shouldOverrideDomain = random.nextBoolean();
-    if (shouldOverrideDomain) {
-      domain = PREFIX + TestUtil.randomSimpleString(random);
-      attrs.put("domain", domain);
-    }
-
-    return new PluginInfo(TestUtil.randomUnicodeString(random), attrs);
-  }
-
-  @After
-  public void afterTest() throws Exception {
-    if (null == metricManager) {
-      return; // test failed to init, nothing to clean up
-    }
-
-    metricManager.closeReporters(coreMetricManager.getRegistryName());
-
-    // sanity check there are no longer any registered beans in our domain....
-    assertEquals(
-        Collections.emptySet(),
-        TEST_MBEAN_SERVER.queryMBeans(ObjectName.getInstance(domain + ":*"), 
null));
-
-    coreMetricManager.close();
-    deleteCore();
-  }
-
-  @Test
-  public void testReportMetrics() {
-    Random random = random();
-
-    Map<String, Counter> registered = new HashMap<>();
-    String scope = PREFIX + SolrMetricTestUtils.getRandomScope(random, true);
-    SolrInfoBean.Category category = 
SolrMetricTestUtils.getRandomCategory(random, true);
-
-    int iterations = TestUtil.nextInt(random, 0, MAX_ITERATIONS);
-    for (int i = 0; i < iterations; ++i) {
-      Map<String, Counter> metrics =
-          SolrMetricTestUtils.getRandomMetricsWithReplacements(random, 
registered);
-      SolrMetricProducer producer = 
SolrMetricTestUtils.getProducerOf(category, scope, metrics);
-      coreMetricManager.registerMetricProducer(scope, producer);
-      registered.putAll(metrics);
-      // waitForListener();
-      Set<ObjectInstance> objects = TEST_MBEAN_SERVER.queryMBeans(null, null);
-      assertEquals(
-          registered.size(),
-          objects.stream()
-              .filter(
-                  o ->
-                      scope.equals(o.getObjectName().getKeyProperty("scope"))
-                          && rootName.equals(o.getObjectName().getDomain()))
-              .count());
-    }
-  }
-
-  @Test
-  public void testReloadCore() throws Exception {
-    Random random = random();
-
-    String scope = PREFIX + SolrMetricTestUtils.getRandomScope(random, true);
-    SolrInfoBean.Category category = 
SolrMetricTestUtils.getRandomCategory(random, true);
-    Map<String, Counter> metrics = 
SolrMetricTestUtils.getRandomMetrics(random, true);
-    SolrMetricProducer producer = SolrMetricTestUtils.getProducerOf(category, 
scope, metrics);
-    coreMetricManager.registerMetricProducer(scope, producer);
-    Set<ObjectInstance> objects = TEST_MBEAN_SERVER.queryMBeans(null, null);
-    assertEquals(
-        metrics.size(),
-        objects.stream()
-            .filter(
-                o ->
-                    scope.equals(o.getObjectName().getKeyProperty("scope"))
-                        && o.getObjectName().getDomain().equals(rootName))
-            .count());
-
-    h.getCoreContainer().reload(h.getCore().getName());
-    PluginInfo pluginInfo = createReporterPluginInfo(rootName, true);
-    metricManager.loadReporter(
-        coreMetricManager.getRegistryName(),
-        coreMetricManager.getCore(),
-        pluginInfo,
-        String.valueOf(coreMetricManager.getCore().hashCode()));
-    coreMetricManager.registerMetricProducer(scope, producer);
-
-    objects = TEST_MBEAN_SERVER.queryMBeans(null, null);
-    assertEquals(
-        metrics.size(),
-        objects.stream()
-            .filter(
-                o ->
-                    scope.equals(o.getObjectName().getKeyProperty("scope"))
-                        && rootName.equals(o.getObjectName().getDomain()))
-            .count());
-  }
-
-  @Test
-  public void testClosedCore() throws Exception {
-    Set<ObjectInstance> objects =
-        TEST_MBEAN_SERVER.queryMBeans(new 
ObjectName("*:category=CORE,name=indexDir,*"), null);
-    assertEquals("Unexpected number of indexDir beans: " + objects.toString(), 
1, objects.size());
-    final ObjectInstance inst = objects.iterator().next();
-    final AtomicBoolean running = new AtomicBoolean(true);
-    Thread testThread =
-        new Thread(
-            () -> {
-              while (running.get()) {
-                try {
-                  Object value = 
TEST_MBEAN_SERVER.getAttribute(inst.getObjectName(), "Value");
-                  assertNotNull(value);
-                } catch (InstanceNotFoundException x) {
-                  // no longer present
-                  break;
-                } catch (Exception e) {
-                  fail("Unexpected error retrieving attribute: " + e);
-                }
-              }
-            },
-            "TestMBeanThread");
-    try {
-      testThread.start();
-      // This should be enough time for the
-      Thread.sleep(500);
-    } finally {
-      running.set(false);
-      testThread.join();
-    }
-
-    h.getCoreContainer().unload(h.getCore().getName());
-    Thread.sleep(2000);
-    objects =
-        TEST_MBEAN_SERVER.queryMBeans(new 
ObjectName("*:category=CORE,name=indexDir,*"), null);
-    assertEquals("Unexpected number of beans after core closed: " + objects, 
0, objects.size());
-  }
-
-  @Test
-  public void testEnabled() throws Exception {
-    String root1 = PREFIX + TestUtil.randomSimpleString(random(), 5, 10);
-    PluginInfo pluginInfo1 = createReporterPluginInfo(root1, true);
-    metricManager.loadReporter(
-        coreMetricManager.getRegistryName(),
-        coreMetricManager.getCore(),
-        pluginInfo1,
-        coreMetricManager.getTag());
-
-    String root2 = PREFIX + TestUtil.randomSimpleString(random(), 5, 10);
-    assertNotEquals(root2, root1);
-    PluginInfo pluginInfo2 = createReporterPluginInfo(root2, false);
-    metricManager.loadReporter(
-        coreMetricManager.getRegistryName(),
-        coreMetricManager.getCore(),
-        pluginInfo2,
-        coreMetricManager.getTag());
-
-    Map<String, SolrMetricReporter> reporters =
-        metricManager.getReporters(coreMetricManager.getRegistryName());
-    assertTrue(reporters.containsKey(pluginInfo1.name + "@" + 
coreMetricManager.getTag()));
-    assertTrue(reporters.containsKey(pluginInfo2.name + "@" + 
coreMetricManager.getTag()));
-
-    String scope = PREFIX + SolrMetricTestUtils.getRandomScope(random(), true);
-    SolrInfoBean.Category category = 
SolrMetricTestUtils.getRandomCategory(random(), true);
-    Map<String, Counter> metrics = 
SolrMetricTestUtils.getRandomMetrics(random(), true);
-    SolrMetricProducer producer = SolrMetricTestUtils.getProducerOf(category, 
scope, metrics);
-    coreMetricManager.registerMetricProducer(scope, producer);
-    Set<ObjectInstance> objects = TEST_MBEAN_SERVER.queryMBeans(null, null);
-    assertEquals(
-        metrics.size(),
-        objects.stream()
-            .filter(
-                o ->
-                    scope.equals(o.getObjectName().getKeyProperty("scope"))
-                        && root1.equals(o.getObjectName().getDomain()))
-            .count());
-    assertEquals(
-        0,
-        objects.stream()
-            .filter(
-                o ->
-                    scope.equals(o.getObjectName().getKeyProperty("scope"))
-                        && root2.equals(o.getObjectName().getDomain()))
-            .count());
-  }
-}
diff --git 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java
 
b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java
deleted file mode 100644
index f76f4678dbf..00000000000
--- 
a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.solr.metrics.reporters;
-
-import java.lang.invoke.MethodHandles;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Map;
-import org.apache.lucene.tests.util.LuceneTestCase;
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.core.CoreContainer;
-import org.apache.solr.core.NodeConfig;
-import org.apache.solr.core.SolrXmlConfig;
-import org.apache.solr.logging.LogWatcher;
-import org.apache.solr.logging.LogWatcherConfig;
-import org.apache.solr.metrics.SolrMetricManager;
-import org.apache.solr.metrics.SolrMetricReporter;
-import org.apache.solr.util.TestHarness;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** */
-// NOCOMMIT: Need to see if we are still supporting this and if it is possible 
to wrap otel metrics
-// into slf4j like dropwizard does.
[email protected](bugUrl = 
"https://issues.apache.org/jira/browse/SOLR-17458";)
-public class SolrSlf4jReporterTest extends SolrTestCaseJ4 {
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  @Test
-  public void testReporter() throws Exception {
-    ensureLoggingConfiguredAppropriately();
-    Path home = TEST_HOME();
-    // define these properties, they are used in solrconfig.xml
-    System.setProperty("solr.test.sys.prop1", "propone");
-    System.setProperty("solr.test.sys.prop2", "proptwo");
-
-    String solrXml =
-        Files.readString(home.resolve("solr-slf4jreporter.xml"), 
StandardCharsets.UTF_8);
-    NodeConfig cfg = SolrXmlConfig.fromString(home, solrXml);
-    CoreContainer cc =
-        createCoreContainer(
-            cfg,
-            new TestHarness.TestCoresLocator(
-                DEFAULT_TEST_CORENAME,
-                initAndGetDataDir().toString(),
-                "solrconfig.xml",
-                "schema.xml"));
-
-    h.coreName = DEFAULT_TEST_CORENAME;
-    SolrMetricManager metricManager = cc.getMetricManager();
-    Map<String, SolrMetricReporter> reporters = 
metricManager.getReporters("solr.node");
-    assertTrue(reporters.toString(), reporters.size() >= 2);
-    SolrMetricReporter reporter1 = reporters.get("test1");
-    assertNotNull(reporter1);
-    assertTrue(reporter1 instanceof SolrSlf4jReporter);
-    SolrMetricReporter reporter2 = reporters.get("test2");
-    assertNotNull(reporter2);
-    assertTrue(reporter2 instanceof SolrSlf4jReporter);
-
-    LogWatcherConfig watcherCfg = new LogWatcherConfig(true, null, null, 100);
-    LogWatcher<?> watcher = LogWatcher.newRegisteredLogWatcher(watcherCfg, 
null);
-    watcher.setThreshold("INFO");
-
-    watcher.reset();
-    int cnt = 20;
-    boolean active;
-    do {
-      Thread.sleep(1000);
-      cnt--;
-      active =
-          ((SolrSlf4jReporter) reporter1).isActive() && ((SolrSlf4jReporter) 
reporter2).isActive();
-    } while (!active && cnt > 0);
-    if (!active) {
-      fail("One or more reporters didn't become active in 20 seconds");
-    }
-    Thread.sleep(10000);
-
-    SolrDocumentList history = watcher.getHistory(-1, null);
-    // dot-separated names are treated like class names and collapsed
-    // in regular log output, but here we get the full name
-    if (history.stream().filter(d -> 
"solr.node".equals(d.getFirstValue("logger"))).count() == 0) {
-      fail("No 'solr.node' logs in: " + history);
-    }
-    if (history.stream().filter(d -> 
"foobar".equals(d.getFirstValue("logger"))).count() == 0) {
-      fail("No 'foobar' logs in: " + history);
-    }
-    if (history.stream().filter(d -> 
"collection1".equals(d.getFirstValue("core"))).count() == 0) {
-      fail("No 'solr.core' or MDC context in logs: " + history);
-    }
-  }
-
-  private static void ensureLoggingConfiguredAppropriately() {
-    if (!log.isInfoEnabled()) {
-      fail("Test requires that log-level is at-least INFO, but INFO is 
disabled");
-    }
-  }
-}
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index 3c69e27773c..b64f200e2df 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -114,6 +114,8 @@ Users who that don't need to vary JAR access on a per-core 
basis have several op
 * The `addHttpRequestToContext` option in `solrconfig.xml` has been removed; 
it's obsolete.
 Nowadays, the HTTP request is available via internal APIs: 
`SolrQueryRequest.getHttpSolrCall().getReq()`.
 
+* JMX, SLF4J and Graphite metric reporters have been removed. Users should 
migrate to using OTLP or the /admin/metrics endpoint with external tools to get 
metrics to their preferred backend.
+
 === Security
 
 * There is no longer a distinction between trusted and untrusted configSets; 
all configSets are now considered trusted. To ensure security, Solr should be 
properly protected using authentication and authorization mechanisms, allowing 
only authorized users with administrative privileges to publish them.
diff --git a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java 
b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
index 2e18bf4c33b..300aa7c3185 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
@@ -34,13 +34,11 @@ import org.apache.solr.core.CorePropertiesLocator;
 import org.apache.solr.core.CoresLocator;
 import org.apache.solr.core.MetricsConfig;
 import org.apache.solr.core.NodeConfig;
-import org.apache.solr.core.PluginInfo;
 import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrXmlConfig;
 import org.apache.solr.handler.UpdateRequestHandler;
 import org.apache.solr.logging.MDCSnapshot;
-import org.apache.solr.metrics.reporters.SolrJmxReporter;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
@@ -195,15 +193,7 @@ public class TestHarness extends BaseTestHarness {
                 .setZkHost(System.getProperty("zkHost"))
                 .build();
 
-    // universal default metric reporter
-    Map<String, Object> attributes = new HashMap<>();
-    attributes.put("name", "default");
-    attributes.put("class", SolrJmxReporter.class.getName());
-    PluginInfo defaultPlugin = new PluginInfo("reporter", attributes);
-    MetricsConfig metricsConfig =
-        new MetricsConfig.MetricsConfigBuilder()
-            .setMetricReporterPlugins(new PluginInfo[] {defaultPlugin})
-            .build();
+    MetricsConfig metricsConfig = new 
MetricsConfig.MetricsConfigBuilder().build();
 
     return new NodeConfig.NodeConfigBuilder("testNode", solrHome)
         .setUseSchemaCache(Boolean.getBoolean("shareSchema"))

Reply via email to