You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2017/03/29 12:28:33 UTC

lucene-solr:jira/solr-9959: SOLR-9959 First round of fixes, remove dependency on MBeanServer in core metrics.

Repository: lucene-solr
Updated Branches:
  refs/heads/jira/solr-9959 d7772e731 -> d285fa6c4


SOLR-9959 First round of fixes, remove dependency on MBeanServer in core metrics.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/d285fa6c
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/d285fa6c
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/d285fa6c

Branch: refs/heads/jira/solr-9959
Commit: d285fa6c45a39efd24f10b25b008300a12af28b0
Parents: d7772e7
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Wed Mar 29 14:27:45 2017 +0200
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Wed Mar 29 14:27:45 2017 +0200

----------------------------------------------------------------------
 .../org/apache/solr/core/CoreContainer.java     |  4 +
 .../solr/metrics/AltBufferPoolMetricSet.java    | 47 +++++++++++
 .../solr/metrics/OperatingSystemMetricSet.java  | 84 +++++++-------------
 .../solr/metrics/reporters/SolrJmxReporter.java | 34 +++++---
 .../apache/solr/servlet/SolrDispatchFilter.java |  9 +--
 .../org/apache/solr/util/stats/MetricUtils.java | 75 ++++++++++++-----
 .../org/apache/solr/metrics/JvmMetricsTest.java | 49 ++++++++++--
 .../metrics/reporters/SolrJmxReporterTest.java  |  3 +
 8 files changed, 211 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/core/CoreContainer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 211370d..4843c63 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -81,6 +81,7 @@ import org.apache.solr.metrics.SolrCoreMetricManager;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricProducer;
 import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.search.SolrFieldCacheBean;
 import org.apache.solr.security.AuthenticationPlugin;
 import org.apache.solr.security.AuthorizationPlugin;
 import org.apache.solr.security.HttpClientBuilderPlugin;
@@ -549,6 +550,9 @@ public class CoreContainer {
     metricManager.registerGauge(registryName, () -> this.getClass().getPackage().getImplementationVersion(),
         true, "implementation", SolrInfoBean.Category.CONTAINER.toString(), "version");
 
+    SolrFieldCacheBean fieldCacheBean = new SolrFieldCacheBean();
+    fieldCacheBean.initializeMetrics(metricManager, registryName, null);
+
     if (isZooKeeperAware()) {
       metricManager.loadClusterReporters(cfg.getMetricReporterPlugins(), this);
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/metrics/AltBufferPoolMetricSet.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/AltBufferPoolMetricSet.java b/solr/core/src/java/org/apache/solr/metrics/AltBufferPoolMetricSet.java
new file mode 100644
index 0000000..f9d3a43
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/metrics/AltBufferPoolMetricSet.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.metrics;
+
+import java.lang.management.BufferPoolMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricSet;
+
+/**
+ * This is an alternative implementation of {@link com.codahale.metrics.jvm.BufferPoolMetricSet} that
+ * doesn't need an MBean server.
+ */
+public class AltBufferPoolMetricSet implements MetricSet {
+
+  @Override
+  public Map<String, Metric> getMetrics() {
+    final Map<String, Metric> metrics = new HashMap<>();
+    List<BufferPoolMXBean> pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
+    for (final BufferPoolMXBean pool : pools) {
+      String name = pool.getName();
+      metrics.put(name + ".Count", (Gauge<Long>)() -> pool.getCount());
+      metrics.put(name + ".MemoryUsed", (Gauge<Long>)() -> pool.getMemoryUsed());
+      metrics.put(name + ".TotalCapacity", (Gauge<Long>)() -> pool.getTotalCapacity());
+    }
+    return metrics;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/metrics/OperatingSystemMetricSet.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/metrics/OperatingSystemMetricSet.java b/solr/core/src/java/org/apache/solr/metrics/OperatingSystemMetricSet.java
index 34ef5d1..56043d9 100644
--- a/solr/core/src/java/org/apache/solr/metrics/OperatingSystemMetricSet.java
+++ b/solr/core/src/java/org/apache/solr/metrics/OperatingSystemMetricSet.java
@@ -16,77 +16,51 @@
  */
 package org.apache.solr.metrics;
 
-import javax.management.JMException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.lang.invoke.MethodHandles;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.PlatformManagedObject;
+import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 
-import com.codahale.metrics.JmxAttributeGauge;
 import com.codahale.metrics.Metric;
 import com.codahale.metrics.MetricSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.solr.util.stats.MetricUtils;
 
 /**
  * This is an extended replacement for {@link com.codahale.metrics.jvm.FileDescriptorRatioGauge}
- * - that class uses reflection and doesn't work under Java 9. We can also get much more
- * information about OS environment once we have to go through MBeanServer anyway.
+ * - that class uses reflection and doesn't work under Java 9. This implementation tries to retrieve
+ * bean properties from known implementations of {@link java.lang.management.OperatingSystemMXBean}.
  */
 public class OperatingSystemMetricSet implements MetricSet {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  /** Metric names - these correspond to known numeric MBean attributes. Depending on the OS and
-   * Java implementation only some of them may be actually present.
-   */
-  public static final String[] METRICS = {
-      "AvailableProcessors",
-      "CommittedVirtualMemorySize",
-      "FreePhysicalMemorySize",
-      "FreeSwapSpaceSize",
-      "MaxFileDescriptorCount",
-      "OpenFileDescriptorCount",
-      "ProcessCpuLoad",
-      "ProcessCpuTime",
-      "SystemLoadAverage",
-      "TotalPhysicalMemorySize",
-      "TotalSwapSpaceSize"
-  };
-
-  private final MBeanServer mBeanServer;
-
-  public OperatingSystemMetricSet(MBeanServer mBeanServer) {
-    this.mBeanServer = mBeanServer;
-  }
 
   @Override
   public Map<String, Metric> getMetrics() {
     final Map<String, Metric> metrics = new HashMap<>();
-
-    try {
-      final ObjectName on = new ObjectName("java.lang:type=OperatingSystem");
-      // verify that it exists
-      MBeanInfo info = mBeanServer.getMBeanInfo(on);
-      // collect valid attributes
-      Set<String> attributes = new HashSet<>();
-      for (MBeanAttributeInfo ai : info.getAttributes()) {
-        attributes.add(ai.getName());
-      }
-      for (String metric : METRICS) {
-        // verify that an attribute exists before attempting to add it
-        if (attributes.contains(metric)) {
-          metrics.put(metric, new JmxAttributeGauge(mBeanServer, on, metric));
-        }
+    OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
+    MetricUtils.addMXBeanMetrics(os, OperatingSystemMXBean.class, null, (k, v) -> {
+      metrics.put(k, v);
+    });
+    // There are some additional implementation-specific properties we want to add
+    // (not available on all JVMs):
+    for (String clazz : Arrays.asList(
+        "com.sun.management.OperatingSystemMXBean",
+        "com.sun.management.UnixOperatingSystemMXBean",
+        "com.ibm.lang.management.OperatingSystemMXBean"
+        )) {
+      try {
+        final Class<? extends PlatformManagedObject> intf = Class.forName(clazz)
+            .asSubclass(PlatformManagedObject.class);
+        MetricUtils.addMXBeanMetrics(os, intf, null, (k, v) -> {
+          // skip already existing properties
+          if (!metrics.containsKey(k)) {
+            metrics.put(k, v);
+          }
+        });
+      } catch (ClassNotFoundException e) {
+        // ignore
       }
-    } catch (JMException ignored) {
-      log.debug("Unable to load OperatingSystem MBean", ignored);
     }
-
     return metrics;
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
----------------------------------------------------------------------
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
index bdc4edf..f8f2eed 100644
--- a/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
+++ b/solr/core/src/java/org/apache/solr/metrics/reporters/SolrJmxReporter.java
@@ -20,7 +20,6 @@ import javax.management.MBeanServer;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.lang.management.ManagementFactory;
 import java.util.Locale;
 
 import com.codahale.metrics.JmxReporter;
@@ -59,7 +58,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
   }
 
   /**
-   * Initializes the reporter by finding (or creating) a MBeanServer
+   * Initializes the reporter by finding an MBeanServer
    * and registering the metricManager's metric registry.
    *
    * @param pluginInfo the configuration for the reporter
@@ -69,29 +68,25 @@ public class SolrJmxReporter extends SolrMetricReporter {
     super.init(pluginInfo);
 
     if (serviceUrl != null && agentId != null) {
-      ManagementFactory.getPlatformMBeanServer(); // Ensure at least one MBeanServer is available.
       mBeanServer = JmxUtil.findFirstMBeanServer();
       log.warn("No more than one of serviceUrl(%s) and agentId(%s) should be configured, using first MBeanServer instead of configuration.",
           serviceUrl, agentId, mBeanServer);
-    }
-    else if (serviceUrl != null) {
+    } else if (serviceUrl != null) {
       try {
         mBeanServer = JmxUtil.findMBeanServerForServiceUrl(serviceUrl);
       } catch (IOException e) {
         log.warn("findMBeanServerForServiceUrl(%s) exception: %s", serviceUrl, e);
         mBeanServer = null;
       }
-    }
-    else if (agentId != null) {
+    } else if (agentId != null) {
       mBeanServer = JmxUtil.findMBeanServerForAgentId(agentId);
     } else {
-      ManagementFactory.getPlatformMBeanServer(); // Ensure at least one MBeanServer is available.
       mBeanServer = JmxUtil.findFirstMBeanServer();
       log.warn("No serviceUrl or agentId was configured, using first MBeanServer.", mBeanServer);
     }
 
     if (mBeanServer == null) {
-      log.warn("No JMX server found. Not exposing Solr metrics.");
+      log.warn("No JMX server found. Not exposing Solr metrics via JMX.");
       return;
     }
 
@@ -164,6 +159,27 @@ public class SolrJmxReporter extends SolrMetricReporter {
   }
 
   /**
+   * 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;
+  }
+
+  /**
    * Retrieves the reporter's MBeanServer.
    *
    * @return the reporter's MBeanServer

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
index d0841c3..24bcf3d 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.servlet;
 
-import javax.management.MBeanServer;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -34,7 +33,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.invoke.MethodHandles;
-import java.lang.management.ManagementFactory;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.Instant;
@@ -47,7 +45,6 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import com.codahale.metrics.jvm.BufferPoolMetricSet;
 import com.codahale.metrics.jvm.ClassLoadingGaugeSet;
 import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
 import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
@@ -69,6 +66,7 @@ import org.apache.solr.core.SolrCore;
 import org.apache.solr.core.SolrInfoBean;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.core.SolrXmlConfig;
+import org.apache.solr.metrics.AltBufferPoolMetricSet;
 import org.apache.solr.metrics.OperatingSystemMetricSet;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.request.SolrRequestInfo;
@@ -185,13 +183,12 @@ public class SolrDispatchFilter extends BaseSolrFilter {
   }
 
   private void setupJvmMetrics()  {
-    MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
     SolrMetricManager metricManager = cores.getMetricManager();
     try {
       String registry = SolrMetricManager.getRegistryName(SolrInfoBean.Group.jvm);
-      metricManager.registerAll(registry, new BufferPoolMetricSet(platformMBeanServer), true, "buffers");
+      metricManager.registerAll(registry, new AltBufferPoolMetricSet(), true, "buffers");
       metricManager.registerAll(registry, new ClassLoadingGaugeSet(), true, "classes");
-      metricManager.registerAll(registry, new OperatingSystemMetricSet(platformMBeanServer), true, "os");
+      metricManager.registerAll(registry, new OperatingSystemMetricSet(), true, "os");
       metricManager.registerAll(registry, new GarbageCollectorMetricSet(), true, "gc");
       metricManager.registerAll(registry, new MemoryUsageGaugeSet(), true, "memory");
       metricManager.registerAll(registry, new ThreadStatesGaugeSet(), true, "threads"); // todo should we use CachedThreadStatesGaugeSet instead?

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java b/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
index 1007234..1b3b63e 100644
--- a/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
+++ b/solr/core/src/java/org/apache/solr/util/stats/MetricUtils.java
@@ -16,6 +16,13 @@
  */
 package org.apache.solr.util.stats;
 
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.invoke.MethodHandles;
+import java.lang.management.PlatformManagedObject;
+import java.lang.reflect.InvocationTargetException;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -40,11 +47,14 @@ import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.metrics.AggregateMetric;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Metrics specific utility functions.
  */
 public class MetricUtils {
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   public static final String METRIC_NAME = "metric";
   public static final String VALUE = "value";
@@ -131,11 +141,11 @@ public class MetricUtils {
   }
 
   /**
-   * Returns a representation of the given metric registry as a list of {@link SolrInputDocument}-s.
+   * Provides a representation of the given metric registry as {@link SolrInputDocument}-s.
    Only those metrics
-   * are converted to NamedList which match at least one of the given MetricFilter instances.
+   * are converted which match at least one of the given MetricFilter instances.
    *
-   * @param registry      the {@link MetricRegistry} to be converted to NamedList
+   * @param registry      the {@link MetricRegistry} to be converted
    * @param shouldMatchFilters a list of {@link MetricFilter} instances.
    *                           A metric must match <em>any one</em> of the filters from this list to be
    *                           included in the output
@@ -145,20 +155,8 @@ public class MetricUtils {
    * @param compact use compact representation for counters and gauges.
    * @param metadata optional metadata. If not null and not empty then this map will be added under a
    *                 {@code _metadata_} key.
-   * @return a list of {@link SolrInputDocument}-s
+   * @param consumer consumer that accepts produced {@link SolrInputDocument}-s
    */
-  public static List<SolrInputDocument> toSolrInputDocuments(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
-                                                             MetricFilter mustMatchFilter, boolean skipHistograms,
-                                                             boolean skipAggregateValues, boolean compact,
-                                                             Map<String, Object> metadata) {
-    List<SolrInputDocument> result = new LinkedList<>();
-    toSolrInputDocuments(registry, shouldMatchFilters, mustMatchFilter, skipHistograms,
-        skipAggregateValues, compact, metadata, doc -> {
-      result.add(doc);
-    });
-    return result;
-  }
-
   public static void toSolrInputDocuments(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
                                           MetricFilter mustMatchFilter, boolean skipHistograms,
                                           boolean skipAggregateValues, boolean compact,
@@ -175,7 +173,7 @@ public class MetricUtils {
     });
   }
 
-  public static void toSolrInputDocument(String prefix, SolrInputDocument doc, Object o) {
+  static void toSolrInputDocument(String prefix, SolrInputDocument doc, Object o) {
     if (!(o instanceof Map)) {
       String key = prefix != null ? prefix : VALUE;
       doc.addField(key, o);
@@ -192,7 +190,7 @@ public class MetricUtils {
     }
   }
 
-  public static void toMaps(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
+  static void toMaps(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
                             MetricFilter mustMatchFilter, boolean skipHistograms, boolean skipAggregateValues,
                             boolean compact,
                             BiConsumer<String, Object> consumer) {
@@ -328,4 +326,45 @@ public class MetricUtils {
   public static ExecutorService instrumentedExecutorService(ExecutorService delegate, MetricRegistry metricRegistry, String scope)  {
     return new InstrumentedExecutorService(delegate, metricRegistry, scope);
   }
+
+  /**
+   * Creates a set of metrics (gauges) that correspond to available bean properties for the provided MXBean.
+   * @param obj an instance of MXBean
+   * @param intf MXBean interface, one of {@link PlatformManagedObject}-s
+   * @param <T> formal type
+   */
+  public static <T extends PlatformManagedObject> void addMXBeanMetrics(T obj, Class<? extends T> intf,
+      String prefix, BiConsumer<String, Metric> consumer) {
+    if (intf.isInstance(obj)) {
+      BeanInfo beanInfo;
+      try {
+        beanInfo = Introspector.getBeanInfo(intf, intf.getSuperclass(), Introspector.IGNORE_ALL_BEANINFO);
+      } catch (IntrospectionException e) {
+        LOG.warn("Unable to fetch properties of MXBean " + obj.getClass().getName());
+        return;
+      }
+      for (final PropertyDescriptor desc : beanInfo.getPropertyDescriptors()) {
+        final String name = desc.getName();
+        // test if it works at all
+        try {
+          desc.getReadMethod().invoke(obj);
+          // worked - consume it
+          final Gauge<?> gauge = () -> {
+            try {
+              return desc.getReadMethod().invoke(obj);
+            } catch (InvocationTargetException ite) {
+              // ignore (some properties throw UOE)
+              return null;
+            } catch (IllegalAccessException e) {
+              return null;
+            }
+          };
+          String metricName = MetricRegistry.name(prefix, name);
+          consumer.accept(metricName, gauge);
+        } catch (Exception e) {
+          // didn't work, skip it...
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java b/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java
index 72adc68..36ae004 100644
--- a/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.solr.metrics;
 
-import javax.management.MBeanServer;
-import java.lang.management.ManagementFactory;
 import java.util.Map;
 
 import com.codahale.metrics.Gauge;
@@ -31,26 +29,65 @@ import org.junit.Test;
  */
 public class JvmMetricsTest extends SolrJettyTestBase {
 
+  static final String[] OS_METRICS = {
+      "availableProcessors",
+      "committedVirtualMemorySize",
+      "freePhysicalMemorySize",
+      "freeSwapSpaceSize",
+      "maxFileDescriptorCount",
+      "openFileDescriptorCount",
+      "processCpuLoad",
+      "processCpuTime",
+      "systemLoadAverage",
+      "totalPhysicalMemorySize",
+      "totalSwapSpaceSize"
+  };
+
+  static final String[] BUFFER_METRICS = {
+      "direct.Count",
+      "direct.MemoryUsed",
+      "direct.TotalCapacity",
+      "mapped.Count",
+      "mapped.MemoryUsed",
+      "mapped.TotalCapacity"
+  };
+
   @BeforeClass
   public static void beforeTest() throws Exception {
     createJetty(legacyExampleCollection1SolrHome());
   }
 
   @Test
-  public void testOperatingSystemMetricsSet() throws Exception {
-    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
-    OperatingSystemMetricSet set = new OperatingSystemMetricSet(mBeanServer);
+  public void testOperatingSystemMetricSet() throws Exception {
+    OperatingSystemMetricSet set = new OperatingSystemMetricSet();
     Map<String, Metric> metrics = set.getMetrics();
     assertTrue(metrics.size() > 0);
-    for (String metric : OperatingSystemMetricSet.METRICS) {
+    int found = 0;
+    for (String metric : OS_METRICS) {
       Gauge<?> gauge = (Gauge<?>)metrics.get(metric);
       if (gauge == null || gauge.getValue() == null) { // some are optional depending on OS
         continue;
       }
+      found++;
       double value = ((Number)gauge.getValue()).doubleValue();
       // SystemLoadAverage on Windows may be -1.0
       assertTrue("unexpected value of " + metric + ": " + value, value >= 0 || value == -1.0);
     }
+    assertTrue("no known metrics found", found > 0);
+  }
+
+  @Test
+  public void testAltBufferPoolMetricSet() throws Exception {
+    AltBufferPoolMetricSet set = new AltBufferPoolMetricSet();
+    Map<String, Metric> metrics = set.getMetrics();
+    assertTrue(metrics.size() > 0);
+    for (String name : BUFFER_METRICS) {
+      assertNotNull(name, metrics.get(name));
+      Object g = metrics.get(name);
+      assertTrue(g instanceof Gauge);
+      Object v = ((Gauge)g).getValue();
+      assertTrue(v instanceof Long);
+    }
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d285fa6c/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
----------------------------------------------------------------------
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
index 27908a4..ba46691 100644
--- a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
+++ b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrJmxReporterTest.java
@@ -20,6 +20,7 @@ import javax.management.MBeanServer;
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
 
+import java.lang.management.ManagementFactory;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
@@ -56,6 +57,8 @@ public class SolrJmxReporterTest extends SolrTestCaseJ4 {
 
   @Before
   public void beforeTest() throws Exception {
+    // make sure we're running an MBeanServer
+    ManagementFactory.getPlatformMBeanServer();
     initCore("solrconfig-basic.xml", "schema.xml");
 
     final SolrCore core = h.getCore();