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/04/05 20:15:54 UTC
lucene-solr:jira/solr-9959: SOLR-9959 Simplify metrics snapshot from
SolrInfoBean.getMetricsSnapshot().
Repository: lucene-solr
Updated Branches:
refs/heads/jira/solr-9959 b9b707cce -> 404fccf86
SOLR-9959 Simplify metrics snapshot from SolrInfoBean.getMetricsSnapshot().
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/404fccf8
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/404fccf8
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/404fccf8
Branch: refs/heads/jira/solr-9959
Commit: 404fccf8605232aaf637f6e8d9d58a881f2dc62f
Parents: b9b707c
Author: Andrzej Bialecki <ab...@apache.org>
Authored: Wed Apr 5 22:14:47 2017 +0200
Committer: Andrzej Bialecki <ab...@apache.org>
Committed: Wed Apr 5 22:14:47 2017 +0200
----------------------------------------------------------------------
.../plugin/AnalyticsStatisticsCollector.java | 4 +-
.../java/org/apache/solr/core/SolrInfoBean.java | 27 ++-
.../handler/admin/MetricsCollectorHandler.java | 2 +-
.../solr/handler/admin/PluginInfoHandler.java | 2 +-
.../handler/admin/SolrInfoMBeanHandler.java | 2 +-
.../solr/handler/admin/SystemInfoHandler.java | 66 +------
.../solr/metrics/reporters/SolrJmxReporter.java | 31 +--
.../org/apache/solr/search/FastLRUCache.java | 1 +
.../java/org/apache/solr/search/LFUCache.java | 2 +
.../java/org/apache/solr/search/LRUCache.java | 3 +-
.../apache/solr/search/SolrFieldCacheBean.java | 2 +
.../org/apache/solr/util/stats/MetricUtils.java | 194 ++++++++++++++-----
.../apache/solr/core/TestJmxIntegration.java | 14 +-
.../handler/admin/SystemInfoHandlerTest.java | 9 +-
.../apache/solr/util/stats/MetricUtilsTest.java | 11 +-
15 files changed, 228 insertions(+), 142 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java b/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
index a796803..657768f 100644
--- a/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
+++ b/solr/contrib/analytics/src/java/org/apache/solr/analytics/plugin/AnalyticsStatisticsCollector.java
@@ -88,7 +88,9 @@ public class AnalyticsStatisticsCollector {
public Map<String, Object> getStatistics() {
Map<String, Object> map = new HashMap<>();
- map.putAll(MetricUtils.convertTimer(requestTimes, false));
+ MetricUtils.convertTimer("", requestTimes, false, false, (k, v) -> {
+ map.putAll((Map<String, Object>)v);
+ });
map.put("requests", numRequests.longValue());
map.put("analyticsRequests", numAnalyticsRequests.longValue());
map.put("statsRequests", numStatsRequests.longValue());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
index a2e213f..472b15e 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrInfoBean.java
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Set;
import com.codahale.metrics.MetricRegistry;
+import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.util.stats.MetricUtils;
/**
@@ -50,8 +51,11 @@ public interface SolrInfoBean {
/** Category of this component */
Category getCategory();
- /** Optionally return metrics that this component reports, or null. */
- default Map<String, Object> getMetrics() {
+ /** Optionally return a snapshot of metrics that this component reports, or null.
+ * Default implementation requires that both {@link #getMetricNames()} and
+ * {@link #getMetricRegistry()} return non-null values.
+ */
+ default Map<String, Object> getMetricsSnapshot() {
if (getMetricRegistry() == null || getMetricNames() == null) {
return null;
}
@@ -59,18 +63,29 @@ public interface SolrInfoBean {
}
/**
- * Modifiable set of metric names that this component reports, or null if none.
+ * Modifiable set of metric names that this component reports (default is null,
+ * which means none). If not null then this set is used by {@link #registerMetricName(String)}
+ * to capture what metrics names are reported from this component.
*/
- Set<String> getMetricNames();
+ default Set<String> getMetricNames() {
+ return null;
+ }
/**
- * An instance of {@link MetricRegistry} that this component uses for keeping metrics, or null.
+ * An instance of {@link MetricRegistry} that this component uses for metrics reporting
+ * (default is null, which means no registry).
*/
default MetricRegistry getMetricRegistry() {
return null;
}
- /** Register a metric name that this component reports. */
+ /** Register a metric name that this component reports. This method is called by various
+ * metric registration methods in {@link org.apache.solr.metrics.SolrMetricManager} in order
+ * to capture what metric names are reported from this component (which in turn is called
+ * from {@link org.apache.solr.metrics.SolrMetricProducer#initializeMetrics(SolrMetricManager, String, String)}).
+ * <p>Default implementation registers all metrics added by a component. Implementations may
+ * override this to avoid reporting some or all metrics returned by {@link #getMetricsSnapshot()}</p>
+ */
default void registerMetricName(String name) {
Set<String> names = getMetricNames();
if (names != null) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
index de39a61..8474f55 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/MetricsCollectorHandler.java
@@ -134,7 +134,7 @@ public class MetricsCollectorHandler extends RequestHandlerBase {
@Override
public String getDescription() {
- return "Handler for collecting and aggregating metric reports.";
+ return "Handler for collecting and aggregating SolrCloud metric reports.";
}
private static class MetricUpdateProcessor extends UpdateRequestProcessor {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
index e4457bf..8bdc478 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/PluginInfoHandler.java
@@ -63,7 +63,7 @@ public class PluginInfoHandler extends RequestHandlerBase
info.add( "description", (m.getDescription()!=null ? m.getDescription() : na) );
if (stats) {
- info.add( "stats", m.getMetrics());
+ info.add( "stats", m.getMetricsSnapshot());
}
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
index 9efcaf7..3c04322 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
@@ -145,7 +145,7 @@ public class SolrInfoMBeanHandler extends RequestHandlerBase {
mBeanInfo.add("description", m.getDescription());
if (req.getParams().getFieldBool(key, "stats", false))
- mBeanInfo.add("stats", m.getMetrics());
+ mBeanInfo.add("stats", m.getMetricsSnapshot());
catInfo.add(key, mBeanInfo);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
index fc1679f..ab2d449 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java
@@ -16,10 +16,6 @@
*/
package org.apache.solr.handler.admin;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -27,23 +23,20 @@ import java.io.InputStreamReader;
import java.lang.invoke.MethodHandles;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
-import java.lang.management.PlatformManagedObject;
import java.lang.management.RuntimeMXBean;
-import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
-import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import com.codahale.metrics.Gauge;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.LucenePackage;
import org.apache.lucene.util.Constants;
-import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
@@ -53,6 +46,7 @@ import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.util.RTimer;
import org.apache.solr.util.RedactionUtils;
+import org.apache.solr.util.stats.MetricUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -207,29 +201,13 @@ public class SystemInfoHandler extends RequestHandlerBase
OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
info.add(NAME, os.getName()); // add at least this one
- try {
- // add remaining ones dynamically using Java Beans API
- addMXBeanProperties(os, OperatingSystemMXBean.class, info);
- } catch (IntrospectionException | ReflectiveOperationException e) {
- log.warn("Unable to fetch properties of OperatingSystemMXBean.", e);
- }
-
- // There are some additional beans 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);
- addMXBeanProperties(os, intf, info);
- } catch (ClassNotFoundException e) {
- // ignore
- } catch (IntrospectionException | ReflectiveOperationException e) {
- log.warn("Unable to fetch properties of JVM-specific OperatingSystemMXBean.", e);
+ // add remaining ones dynamically using Java Beans API
+ // also those from JVM implementation-specific classes
+ MetricUtils.addMXBeanMetrics(os, MetricUtils.OS_MXBEAN_CLASSES, null, (name, metric) -> {
+ if (info.get(name) == null) {
+ info.add(name, ((Gauge) metric).getValue());
}
- }
+ });
// Try some command line things:
try {
@@ -244,34 +222,6 @@ public class SystemInfoHandler extends RequestHandlerBase
}
/**
- * Add all bean properties of a {@link PlatformManagedObject} to the given {@link NamedList}.
- * <p>
- * If you are running a OpenJDK/Oracle JVM, there are nice properties in:
- * {@code com.sun.management.UnixOperatingSystemMXBean} and
- * {@code com.sun.management.OperatingSystemMXBean}
- */
- static <T extends PlatformManagedObject> void addMXBeanProperties(T obj, Class<? extends T> intf, NamedList<Object> info)
- throws IntrospectionException, ReflectiveOperationException {
- if (intf.isInstance(obj)) {
- final BeanInfo beanInfo = Introspector.getBeanInfo(intf, intf.getSuperclass(), Introspector.IGNORE_ALL_BEANINFO);
- for (final PropertyDescriptor desc : beanInfo.getPropertyDescriptors()) {
- final String name = desc.getName();
- if (info.get(name) == null) {
- try {
- final Object v = desc.getReadMethod().invoke(obj);
- if(v != null) {
- info.add(name, v);
- }
- } catch (InvocationTargetException ite) {
- // ignore (some properties throw UOE)
- }
- }
- }
- }
- }
-
-
- /**
* Utility function to execute a function
*/
private static String execute( String cmd )
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/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 c500e7f..db3b81f 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
@@ -17,14 +17,15 @@
package org.apache.solr.metrics.reporters;
import javax.management.MBeanServer;
+import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
@@ -60,6 +61,8 @@ public class SolrJmxReporter extends SolrMetricReporter {
private MBeanServer mBeanServer;
private MetricsMapListener listener;
+ private static Map<String,PluginInfo> reporters = new HashMap<>();
+
/**
* Creates a new instance of {@link SolrJmxReporter}.
*
@@ -79,7 +82,12 @@ public class SolrJmxReporter extends SolrMetricReporter {
@Override
public synchronized void init(PluginInfo pluginInfo) {
super.init(pluginInfo);
-
+ log.info("Initializing for registry " + registryName + ": " + pluginInfo);
+ String key = pluginInfo.name + "/" + registryName;
+ if (reporters.containsKey(key)) {
+ throw new RuntimeException("already reporting: " + reporters.get(key));
+ }
+ reporters.put(key, pluginInfo);
if (serviceUrl != null && agentId != null) {
mBeanServer = JmxUtil.findFirstMBeanServer();
log.warn("No more than one of serviceUrl(%s) and agentId(%s) should be configured, using first MBeanServer instead of configuration.",
@@ -95,7 +103,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
mBeanServer = JmxUtil.findMBeanServerForAgentId(agentId);
} else {
mBeanServer = JmxUtil.findFirstMBeanServer();
- log.warn("No serviceUrl or agentId was configured, using first MBeanServer.", mBeanServer);
+ log.debug("No serviceUrl or agentId was configured, using first MBeanServer: " + mBeanServer);
}
if (mBeanServer == null) {
@@ -103,8 +111,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
return;
}
- JmxObjectNameFactory jmxObjectNameFactory = new JmxObjectNameFactory(pluginInfo.name, domain,
- "instance", Integer.toHexString(this.hashCode()));
+ JmxObjectNameFactory jmxObjectNameFactory = new JmxObjectNameFactory(pluginInfo.name, domain);
registry = metricManager.registry(registryName);
// filter out MetricsMap gauges - we have a better way of handling them
MetricFilter filter = (name, metric) -> !(metric instanceof MetricsMap);
@@ -120,7 +127,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
listener = new MetricsMapListener(mBeanServer, jmxObjectNameFactory);
registry.addListener(listener);
- log.info("JMX monitoring enabled at server: " + mBeanServer);
+ log.info("JMX monitoring for registry '" + registryName + "' enabled at server: " + mBeanServer);
}
/**
@@ -206,7 +213,7 @@ public class SolrJmxReporter extends SolrMetricReporter {
}
/**
- * Retrieves the reporter's MBeanServer.
+ * Return the reporter's MBeanServer.
*
* @return the reporter's MBeanServer
*/
@@ -249,15 +256,17 @@ public class SolrJmxReporter extends SolrMetricReporter {
if (!lock.tryLock()) {
return;
}
- log.info("#### registering " + name + " in domain " + nameFactory.getDomain());
try {
ObjectName objectName = nameFactory.createName("gauges", nameFactory.getDomain(), name);
if (server.isRegistered(objectName)) {
// silently unregister - may have been left over from a previous reporter
server.unregisterMBean(objectName);
}
- server.registerMBean(gauge, objectName);
- registered.add(objectName);
+ // some MBean servers re-write object name to include additional properties
+ ObjectInstance instance = server.registerMBean(gauge, objectName);
+ if (instance != null) {
+ registered.add(instance.getObjectName());
+ }
} catch (Exception e) {
log.warn("bean registration error", e);
} finally {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
index cb699b2..4d3f2a9 100644
--- a/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/FastLRUCache.java
@@ -21,6 +21,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.util.ConcurrentLRUCache;
+import org.apache.solr.util.stats.MetricUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/search/LFUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/LFUCache.java b/solr/core/src/java/org/apache/solr/search/LFUCache.java
index 82ba6d2..2a53b95 100644
--- a/solr/core/src/java/org/apache/solr/search/LFUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LFUCache.java
@@ -26,9 +26,11 @@ import java.util.concurrent.TimeUnit;
import com.codahale.metrics.MetricRegistry;
import org.apache.solr.common.SolrException;
+import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.util.ConcurrentLFUCache;
+import org.apache.solr.util.stats.MetricUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/search/LRUCache.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/LRUCache.java b/solr/core/src/java/org/apache/solr/search/LRUCache.java
index 6c12451..530a0a6 100644
--- a/solr/core/src/java/org/apache/solr/search/LRUCache.java
+++ b/solr/core/src/java/org/apache/solr/search/LRUCache.java
@@ -34,6 +34,7 @@ import org.apache.lucene.util.RamUsageEstimator;
import org.apache.solr.common.SolrException;
import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
+import org.apache.solr.util.stats.MetricUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -372,7 +373,7 @@ public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>, Acco
public MetricRegistry getMetricRegistry() {
return registry;
}
-
+
@Override
public String toString() {
return name() + cacheMap != null ? cacheMap.getValue().toString() : "";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
index ffcc37d..2303b6f 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrFieldCacheBean.java
@@ -17,6 +17,7 @@
package org.apache.solr.search;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import com.codahale.metrics.MetricRegistry;
@@ -25,6 +26,7 @@ import org.apache.solr.metrics.MetricsMap;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
import org.apache.solr.uninverting.UninvertingReader;
+import org.apache.solr.util.stats.MetricUtils;
/**
* A SolrInfoBean that provides introspection of the Solr FieldCache
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/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 d54c76b..a2cab8b 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
@@ -21,6 +21,7 @@ import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.invoke.MethodHandles;
+import java.lang.management.OperatingSystemMXBean;
import java.lang.management.PlatformManagedObject;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
@@ -133,7 +134,7 @@ public class MetricUtils {
boolean skipAggregateValues, boolean compact,
Map<String, Object> metadata) {
NamedList result = new SimpleOrderedMap();
- toMaps(registry, shouldMatchFilters, mustMatchFilter, skipHistograms, skipAggregateValues, compact, (k, v) -> {
+ toMaps(registry, shouldMatchFilters, mustMatchFilter, skipHistograms, skipAggregateValues, compact, false, (k, v) -> {
result.add(k, v);
});
if (metadata != null && !metadata.isEmpty()) {
@@ -165,7 +166,7 @@ public class MetricUtils {
boolean skipAggregateValues, boolean compact,
Map<String, Object> metadata, Consumer<SolrInputDocument> consumer) {
boolean addMetadata = metadata != null && !metadata.isEmpty();
- toMaps(registry, shouldMatchFilters, mustMatchFilter, skipHistograms, skipAggregateValues, compact, (k, v) -> {
+ toMaps(registry, shouldMatchFilters, mustMatchFilter, skipHistograms, skipAggregateValues, compact, false, (k, v) -> {
SolrInputDocument doc = new SolrInputDocument();
doc.setField(METRIC_NAME, k);
toSolrInputDocument(null, doc, v);
@@ -176,6 +177,12 @@ public class MetricUtils {
});
}
+ /**
+ * Fill in a SolrInputDocument with values from a converted metric, recursively.
+ * @param prefix prefix to add to generated field names, or null if none.
+ * @param doc document to fill
+ * @param o an instance of converted metric, either a Map or a flat Object
+ */
static void toSolrInputDocument(String prefix, SolrInputDocument doc, Object o) {
if (!(o instanceof Map)) {
String key = prefix != null ? prefix : VALUE;
@@ -193,9 +200,21 @@ public class MetricUtils {
}
}
+ /**
+ * Convert selected metrics to maps or to flattened objects.
+ * @param registry source of metrics
+ * @param shouldMatchFilters metrics must match any of these filters
+ * @param mustMatchFilter metrics must match this filter
+ * @param skipHistograms discard any {@link Histogram}-s and histogram parts of {@link Timer}-s.
+ * @param skipAggregateValues discard internal values of {@link AggregateMetric}-s.
+ * @param compact use compact representation for counters and gauges.
+ * @param simple use simplified representation for complex metrics - instead of a (name, map)
+ * only the selected (name "." key, value) pairs will be produced.
+ * @param consumer consumer that accepts produced objects
+ */
static void toMaps(MetricRegistry registry, List<MetricFilter> shouldMatchFilters,
MetricFilter mustMatchFilter, boolean skipHistograms, boolean skipAggregateValues,
- boolean compact,
+ boolean compact, boolean simple,
BiConsumer<String, Object> consumer) {
final Map<String, Metric> metrics = registry.getMetrics();
final SortedSet<String> names = registry.getNames();
@@ -204,20 +223,20 @@ public class MetricUtils {
.filter(s -> mustMatchFilter.matches(s, metrics.get(s)))
.forEach(n -> {
Metric metric = metrics.get(n);
- convertMetric(n, metric, skipHistograms, skipAggregateValues, compact, consumer);
+ convertMetric(n, metric, skipHistograms, skipAggregateValues, compact, simple, consumer);
});
}
/**
- * Convert selected metrics from a registry into a map, with metrics in a compact format.
+ * Convert selected metrics from a registry into a map, with metrics in a compact AND simple format.
* @param registry registry
* @param names metric names
* @return map where keys are metric names (if they were present in the registry) and values are
- * converted metrics.
+ * converted metrics in simplified format.
*/
public static Map<String, Object> convertMetrics(MetricRegistry registry, Collection<String> names) {
final Map<String, Object> metrics = new HashMap<>();
- convertMetrics(registry, names, false, true, true, (k, v) -> metrics.put(k, v));
+ convertMetrics(registry, names, false, true, true, true, (k, v) -> metrics.put(k, v));
return metrics;
}
@@ -229,28 +248,42 @@ public class MetricUtils {
* @param skipHistograms discard any {@link Histogram}-s and histogram parts of {@link Timer}-s.
* @param skipAggregateValues discard internal values of {@link AggregateMetric}-s.
* @param compact use compact representation for counters and gauges.
+ * @param simple use simplified representation for complex metrics - instead of a (name, map)
+ * only the selected (name "." key, value) pairs will be produced.
* @param consumer consumer that accepts produced objects
*/
public static void convertMetrics(MetricRegistry registry, Collection<String> names,
- boolean skipHistograms, boolean skipAggregateValues, boolean compact,
+ boolean skipHistograms, boolean skipAggregateValues,
+ boolean compact, boolean simple,
BiConsumer<String, Object> consumer) {
final Map<String, Metric> metrics = registry.getMetrics();
names.stream()
.forEach(n -> {
Metric metric = metrics.get(n);
- convertMetric(n, metric, skipHistograms, skipAggregateValues, compact, consumer);
+ convertMetric(n, metric, skipHistograms, skipAggregateValues, compact, simple, consumer);
});
}
+ /**
+ * Convert a single instance of metric into a map or flattened object.
+ * @param n metric name
+ * @param metric metric instance
+ * @param skipHistograms discard any {@link Histogram}-s and histogram parts of {@link Timer}-s.
+ * @param skipAggregateValues discard internal values of {@link AggregateMetric}-s.
+ * @param compact use compact representation for counters and gauges.
+ * @param simple use simplified representation for complex metrics - instead of a (name, map)
+ * only the selected (name "." key, value) pairs will be produced.
+ * @param consumer consumer that accepts produced objects
+ */
static void convertMetric(String n, Metric metric, boolean skipHistograms, boolean skipAggregateValues,
- boolean compact, BiConsumer<String, Object> consumer) {
+ boolean compact, boolean simple, BiConsumer<String, Object> consumer) {
if (metric instanceof Counter) {
Counter counter = (Counter) metric;
consumer.accept(n, convertCounter(counter, compact));
} else if (metric instanceof Gauge) {
Gauge gauge = (Gauge) metric;
try {
- consumer.accept(n, convertGauge(gauge, compact));
+ convertGauge(n, gauge, simple, compact, consumer);
} catch (InternalError ie) {
if (n.startsWith("memory.") && ie.getMessage().contains("Memory Pool not found")) {
LOG.warn("Error converting gauge '" + n + "', possible JDK bug: SOLR-10362", ie);
@@ -261,20 +294,26 @@ public class MetricUtils {
}
} else if (metric instanceof Meter) {
Meter meter = (Meter) metric;
- consumer.accept(n, convertMeter(meter));
+ convertMeter(n, meter, simple, consumer);
} else if (metric instanceof Timer) {
Timer timer = (Timer) metric;
- consumer.accept(n, convertTimer(timer, skipHistograms));
+ convertTimer(n, timer, skipHistograms, simple, consumer);
} else if (metric instanceof Histogram) {
if (!skipHistograms) {
Histogram histogram = (Histogram) metric;
- consumer.accept(n, convertHistogram(histogram));
+ convertHistogram(n, histogram, simple, consumer);
}
} else if (metric instanceof AggregateMetric) {
consumer.accept(n, convertAggregateMetric((AggregateMetric)metric, skipAggregateValues));
}
}
+ /**
+ * Convert an instance of {@link AggregateMetric}.
+ * @param metric an instance of {@link AggregateMetric}
+ * @param skipAggregateValues discard internal values of {@link AggregateMetric}-s.
+ * @return a map containing metric properties
+ */
static Map<String, Object> convertAggregateMetric(AggregateMetric metric, boolean skipAggregateValues) {
Map<String, Object> response = new LinkedHashMap<>();
response.put("count", metric.size());
@@ -296,13 +335,23 @@ public class MetricUtils {
return response;
}
- static Map<String, Object> convertHistogram(Histogram histogram) {
- Map<String, Object> response = new LinkedHashMap<>();
+ /**
+ * Convert an instance of {@link Histogram}. NOTE: it's assumed that histogram contains non-time
+ * based values that don't require unit conversion.
+ * @param histogram an instance of {@link Histogram}
+ */
+ static void convertHistogram(String name, Histogram histogram,
+ boolean simple, BiConsumer<String, Object> consumer) {
Snapshot snapshot = histogram.getSnapshot();
- response.put("count", histogram.getCount());
- // non-time based values
- addSnapshot(response, snapshot, false);
- return response;
+ if (simple) {
+ consumer.accept(name + "." + MEAN, snapshot.getMean());
+ } else {
+ Map<String, Object> response = new LinkedHashMap<>();
+ consumer.accept(name, response);
+ response.put("count", histogram.getCount());
+ // non-time based values
+ addSnapshot(response, snapshot, false);
+ }
}
// optionally convert ns to ms
@@ -331,42 +380,75 @@ public class MetricUtils {
* Convert a {@link Timer} to a map.
* @param timer timer instance
* @param skipHistograms if true then discard the histogram part of the timer.
- * @return a map containing timer properties.
*/
- public static Map<String,Object> convertTimer(Timer timer, boolean skipHistograms) {
- Map<String, Object> response = new LinkedHashMap<>();
- response.put("count", timer.getCount());
- response.put("meanRate", timer.getMeanRate());
- response.put("1minRate", timer.getOneMinuteRate());
- response.put("5minRate", timer.getFiveMinuteRate());
- response.put("15minRate", timer.getFifteenMinuteRate());
- if (!skipHistograms) {
- // time-based values in nanoseconds
- addSnapshot(response, timer.getSnapshot(), true);
+ public static void convertTimer(String name, Timer timer, boolean skipHistograms,
+ boolean simple, BiConsumer<String, Object> consumer) {
+ if (simple) {
+ consumer.accept(name + ".meanRate", timer.getMeanRate());
+ } else {
+ Map<String, Object> response = new LinkedHashMap<>();
+ consumer.accept(name, response);
+ response.put("count", timer.getCount());
+ response.put("meanRate", timer.getMeanRate());
+ response.put("1minRate", timer.getOneMinuteRate());
+ response.put("5minRate", timer.getFiveMinuteRate());
+ response.put("15minRate", timer.getFifteenMinuteRate());
+ if (!skipHistograms) {
+ // time-based values in nanoseconds
+ addSnapshot(response, timer.getSnapshot(), true);
+ }
}
- return response;
}
- static Map<String, Object> convertMeter(Meter meter) {
- Map<String, Object> response = new LinkedHashMap<>();
- response.put("count", meter.getCount());
- response.put("meanRate", meter.getMeanRate());
- response.put("1minRate", meter.getOneMinuteRate());
- response.put("5minRate", meter.getFiveMinuteRate());
- response.put("15minRate", meter.getFifteenMinuteRate());
- return response;
+ /**
+ * Convert a {@link Meter} to a map.
+ * @param meter meter instance
+ */
+ static void convertMeter(String name, Meter meter, boolean simple, BiConsumer<String, Object> consumer) {
+ if (simple) {
+ consumer.accept(name + ".count", meter.getCount());
+ } else {
+ Map<String, Object> response = new LinkedHashMap<>();
+ response.put("count", meter.getCount());
+ response.put("meanRate", meter.getMeanRate());
+ response.put("1minRate", meter.getOneMinuteRate());
+ response.put("5minRate", meter.getFiveMinuteRate());
+ response.put("15minRate", meter.getFifteenMinuteRate());
+ consumer.accept(name, response);
+ }
}
- static Object convertGauge(Gauge gauge, boolean compact) {
- if (compact) {
- return gauge.getValue();
+ /**
+ * Convert a {@link Gauge}.
+ * @param gauge gauge instance
+ * @param compact if true then only return {@link Gauge#getValue()}. If false
+ * then return a map with a "value" field.
+ */
+ static void convertGauge(String name, Gauge gauge, boolean simple, boolean compact,
+ BiConsumer<String, Object> consumer) {
+ if (compact || simple) {
+ Object o = gauge.getValue();
+ if (simple && (o instanceof Map)) {
+ for (Map.Entry<?, ?> entry : ((Map<?, ?>)o).entrySet()) {
+ consumer.accept(name + "." + entry.getKey().toString(), entry.getValue());
+ }
+ } else {
+ consumer.accept(name, o);
+ }
} else {
Map<String, Object> response = new LinkedHashMap<>();
response.put("value", gauge.getValue());
- return response;
+ consumer.accept(name, response);
}
}
+ /**
+ * Convert a {@link Counter}
+ * @param counter counter instance
+ * @param compact if true then only return {@link Counter#getCount()}. If false
+ * then return a map with a "count" field.
+ * @return map or object
+ */
static Object convertCounter(Counter counter, boolean compact) {
if (compact) {
return counter.getCount();
@@ -430,4 +512,28 @@ public class MetricUtils {
}
}
}
+
+ /**
+ * These are well-known implementations of {@link java.lang.management.OperatingSystemMXBean}.
+ * Some of them provide additional useful properties beyond those declared by the interface.
+ */
+ public static String[] OS_MXBEAN_CLASSES = new String[] {
+ OperatingSystemMXBean.class.getName(),
+ "com.sun.management.OperatingSystemMXBean",
+ "com.sun.management.UnixOperatingSystemMXBean",
+ "com.ibm.lang.management.OperatingSystemMXBean"
+ };
+
+ public static <T extends PlatformManagedObject> void addMXBeanMetrics(T obj, String[] interfaces,
+ String prefix, BiConsumer<String, Metric> consumer) {
+ for (String clazz : interfaces) {
+ try {
+ final Class<? extends PlatformManagedObject> intf = Class.forName(clazz)
+ .asSubclass(PlatformManagedObject.class);
+ MetricUtils.addMXBeanMetrics(obj, intf, null, consumer);
+ } catch (ClassNotFoundException e) {
+ // ignore
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java b/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
index d374be5..db941f7 100644
--- a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
+++ b/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java
@@ -32,12 +32,10 @@ import javax.management.AttributeNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.lang.invoke.MethodHandles;
import java.lang.management.ManagementFactory;
-import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
@@ -89,8 +87,7 @@ public class TestJmxIntegration extends AbstractSolrTestCase {
// agetnId or serviceUrl is that it will use whatever the "first" MBean server
// returned by the JVM is.
- nameFactory = new JmxObjectNameFactory("default", registryName,
- "instance", Integer.toHexString(jmx.hashCode()));
+ nameFactory = new JmxObjectNameFactory("default", registryName);
}
@AfterClass
@@ -200,13 +197,4 @@ public class TestJmxIntegration extends AbstractSolrTestCase {
log.info("After Reload: Size of infoRegistry: " + registrySize + " MBeans: " + newNumberOfObjects);
assertEquals("Number of registered MBeans is not the same as info registry size", registrySize, newNumberOfObjects);
}
-
- private ObjectName getObjectName(String key, SolrInfoBean infoBean)
- throws MalformedObjectNameException {
- Hashtable<String, String> map = new Hashtable<>();
- map.put("type", key);
- map.put("id", infoBean.getName());
- String coreName = h.getCore().getName();
- return ObjectName.getInstance(("solr" + (null != coreName ? "/" + coreName : "")), map);
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java
index c961a55..92779a1 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java
@@ -20,8 +20,11 @@ import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.Arrays;
+import com.codahale.metrics.Gauge;
+import org.apache.hadoop.metrics.MetricsUtil;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.util.stats.MetricUtils;
public class SystemInfoHandlerTest extends LuceneTestCase {
@@ -36,9 +39,11 @@ public class SystemInfoHandlerTest extends LuceneTestCase {
info.add( "version", os.getVersion() );
info.add( "arch", os.getArch() );
- // make another using addMXBeanProperties()
+ // make another using MetricUtils.addMXBeanMetrics()
SimpleOrderedMap<Object> info2 = new SimpleOrderedMap<>();
- SystemInfoHandler.addMXBeanProperties( os, OperatingSystemMXBean.class, info2 );
+ MetricUtils.addMXBeanMetrics( os, OperatingSystemMXBean.class, null, (k, v) -> {
+ info2.add(k, ((Gauge)v).getValue());
+ } );
// make sure they got the same thing
for (String p : Arrays.asList("name", "version", "arch")) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/404fccf8/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
index aa02de5..b852a28 100644
--- a/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
+++ b/solr/core/src/test/org/apache/solr/util/stats/MetricUtilsTest.java
@@ -18,6 +18,7 @@
package org.apache.solr.util.stats;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -45,7 +46,11 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
timer.update(Math.abs(random().nextInt()) + 1, TimeUnit.NANOSECONDS);
}
// obtain timer metrics
- NamedList lst = new NamedList(MetricUtils.convertTimer(timer, false));
+ Map<String,Object> map = new HashMap<>();
+ MetricUtils.convertTimer("", timer, false, false, (k, v) -> {
+ map.putAll((Map<String,Object>)v);
+ });
+ NamedList lst = new NamedList(map);
// check that expected metrics were obtained
assertEquals(14, lst.size());
final Snapshot snapshot = timer.getSnapshot();
@@ -84,7 +89,7 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
Gauge<Long> error = () -> {throw new InternalError("Memory Pool not found error");};
registry.register("memory.expected.error", error);
MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
- false, false, false, (k, o) -> {
+ false, false, false, false, (k, o) -> {
Map v = (Map)o;
if (k.startsWith("counter")) {
assertEquals(1L, v.get("count"));
@@ -114,7 +119,7 @@ public class MetricUtilsTest extends SolrTestCaseJ4 {
});
// test compact format
MetricUtils.toMaps(registry, Collections.singletonList(MetricFilter.ALL), MetricFilter.ALL,
- false, false, true, (k, o) -> {
+ false, false, true, false, (k, o) -> {
if (k.startsWith("counter")) {
assertTrue(o instanceof Long);
assertEquals(1L, o);