This is an automated email from the ASF dual-hosted git repository.
ishan pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new b51c510885d SOLR-15616: Allow thread metrics to be cached
b51c510885d is described below
commit b51c510885dd1ef7dc7f25e7511b2ced41378a51
Author: Ishan Chattopadhyaya <[email protected]>
AuthorDate: Mon Jan 23 19:32:29 2023 +0530
SOLR-15616: Allow thread metrics to be cached
---
solr/CHANGES.txt | 1 +
.../java/org/apache/solr/core/MetricsConfig.java | 26 ++++++++++++++++++++--
.../java/org/apache/solr/core/SolrXmlConfig.java | 6 +++++
.../apache/solr/servlet/CoreContainerProvider.java | 19 ++++++++++------
solr/server/solr/solr.xml | 8 +++++++
.../deployment-guide/pages/metrics-reporting.adoc | 17 ++++++++++++++
6 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d5e7bcdbf1b..7eaf53198dc 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -109,6 +109,7 @@ Optimizations
* SOLR-15732: queries to missing collection are slow (noble)
+* SOLR-15616: Allow thread metrics to be cached (Ishan Chattopadhyaya, ab)
Bug Fixes
---------------------
diff --git a/solr/core/src/java/org/apache/solr/core/MetricsConfig.java
b/solr/core/src/java/org/apache/solr/core/MetricsConfig.java
index ab84d53f3a1..fd6dc5cd7c5 100644
--- a/solr/core/src/java/org/apache/solr/core/MetricsConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/MetricsConfig.java
@@ -34,6 +34,7 @@ public class MetricsConfig {
private final Object nullString;
private final Object nullObject;
private final boolean enabled;
+ private final CacheConfig cacheConfig;
private MetricsConfig(
boolean enabled,
@@ -46,7 +47,8 @@ public class MetricsConfig {
Object nullNumber,
Object notANumber,
Object nullString,
- Object nullObject) {
+ Object nullObject,
+ CacheConfig cacheConfig) {
this.enabled = enabled;
this.metricReporters = metricReporters;
this.hiddenSysProps = hiddenSysProps;
@@ -58,12 +60,17 @@ public class MetricsConfig {
this.notANumber = notANumber;
this.nullString = nullString;
this.nullObject = nullObject;
+ this.cacheConfig = cacheConfig;
}
public boolean isEnabled() {
return enabled;
}
+ public CacheConfig getCacheConfig() {
+ return cacheConfig;
+ }
+
private static final PluginInfo[] NO_OP_REPORTERS = new PluginInfo[0];
public PluginInfo[] getMetricReporters() {
@@ -149,6 +156,7 @@ public class MetricsConfig {
private Object nullObject = null;
// default to metrics enabled
private boolean enabled = true;
+ private CacheConfig cacheConfig = null;
public MetricsConfigBuilder() {}
@@ -157,6 +165,11 @@ public class MetricsConfig {
return this;
}
+ public MetricsConfigBuilder setCacheConfig(CacheConfig cacheConfig) {
+ this.cacheConfig = cacheConfig;
+ return this;
+ }
+
public MetricsConfigBuilder setHiddenSysProps(Set<String> hiddenSysProps) {
if (hiddenSysProps != null && !hiddenSysProps.isEmpty()) {
this.hiddenSysProps.clear();
@@ -223,7 +236,16 @@ public class MetricsConfig {
nullNumber,
notANumber,
nullString,
- nullObject);
+ nullObject,
+ cacheConfig);
+ }
+ }
+
+ public static class CacheConfig {
+ public Integer threadsIntervalSeconds; // intervals for which the threads
metrics are cached
+
+ public CacheConfig (Integer threadsIntervalSeconds) {
+ this.threadsIntervalSeconds = threadsIntervalSeconds;
}
}
}
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 77c7adb67e0..a8a2c45cca2 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
@@ -657,6 +657,12 @@ public class SolrXmlConfig {
builder.setNullObject(decodeNullValue(missingValues.get("nullObject")));
}
+ ConfigNode caching = metrics.get("solr/metrics/caching");
+ if (caching != null) {
+ Object threadsCachingIntervalSeconds =
DOMUtil.childNodesToNamedList(caching).get("threadsIntervalSeconds", null);
+ builder.setCacheConfig(new
MetricsConfig.CacheConfig(threadsCachingIntervalSeconds == null? null:
Integer.parseInt(threadsCachingIntervalSeconds.toString())));
+ }
+
PluginInfo[] reporterPlugins = getMetricReporterPluginInfos(metrics);
Set<String> hiddenSysProps = getHiddenSysProps(metrics);
return builder
diff --git
a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
index 65568e584d4..1dc0a9dce6f 100644
--- a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
+++ b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java
@@ -23,6 +23,7 @@ import static
org.apache.solr.servlet.SolrDispatchFilter.SOLR_INSTALL_DIR_ATTRIB
import static org.apache.solr.servlet.SolrDispatchFilter.SOLR_LOG_LEVEL;
import static org.apache.solr.servlet.SolrDispatchFilter.SOLR_LOG_MUTECONSOLE;
+import com.codahale.metrics.jvm.CachedThreadStatesGaugeSet;
import com.codahale.metrics.jvm.ClassLoadingGaugeSet;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
@@ -60,6 +61,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.MetricsConfig;
import org.apache.solr.core.NodeConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrInfoBean.Group;
@@ -227,7 +229,7 @@ public class CoreContainerProvider implements
ServletContextListener {
coresInit = createCoreContainer(computeSolrHome(servletContext),
extraProperties);
this.httpClient =
coresInit.getUpdateShardHandler().getDefaultHttpClient();
- setupJvmMetrics(coresInit);
+ setupJvmMetrics(coresInit, coresInit.getNodeConfig().getMetricsConfig());
SolrZkClient zkClient = null;
ZkController zkController = coresInit.getZkController();
@@ -411,7 +413,7 @@ public class CoreContainerProvider implements
ServletContextListener {
return coreContainer;
}
- private void setupJvmMetrics(CoreContainer coresInit) {
+ private void setupJvmMetrics(CoreContainer coresInit, MetricsConfig config) {
metricManager = coresInit.getMetricManager();
registryName = SolrMetricManager.getRegistryName(Group.jvm);
final Set<String> hiddenSysProps =
coresInit.getConfig().getMetricsConfig().getHiddenSysProps();
@@ -426,11 +428,14 @@ public class CoreContainerProvider implements
ServletContextListener {
registryName, new GarbageCollectorMetricSet(),
ResolutionStrategy.IGNORE, "gc");
metricManager.registerAll(
registryName, new MemoryUsageGaugeSet(), ResolutionStrategy.IGNORE,
"memory");
- metricManager.registerAll(
- registryName,
- new ThreadStatesGaugeSet(),
- ResolutionStrategy.IGNORE,
- "threads"); // todo should we use CachedThreadStatesGaugeSet instead?
+
+ if (config.getCacheConfig() != null &&
config.getCacheConfig().threadsIntervalSeconds != null) {
+ log.info("Threads metrics will be cached for " +
config.getCacheConfig().threadsIntervalSeconds + " seconds");
+ metricManager.registerAll(registryName, new
CachedThreadStatesGaugeSet(config.getCacheConfig().threadsIntervalSeconds,
TimeUnit.SECONDS), SolrMetricManager.ResolutionStrategy.IGNORE, "threads");
+ } else {
+ metricManager.registerAll(registryName, new ThreadStatesGaugeSet(),
SolrMetricManager.ResolutionStrategy.IGNORE, "threads");
+ }
+
MetricsMap sysprops =
new MetricsMap(
map ->
diff --git a/solr/server/solr/solr.xml b/solr/server/solr/solr.xml
index 136154acfd6..459dbff87f2 100644
--- a/solr/server/solr/solr.xml
+++ b/solr/server/solr/solr.xml
@@ -60,7 +60,15 @@
</shardHandlerFactory>
<metrics enabled="${metricsEnabled:true}">
+ <!-- Solr computes JVM metrics for threads. Computing these metrics,
esp. computing deadlocks etc.,
+ requires potentially expensive computations, and can be avoided for every
metrics call by
+ setting a high caching expiration interval (in seconds).
+ <caching>
+ <int name="threadsIntervalSeconds">5</int>
+ </caching>
+ -->
<!--reporter name="jmx_metrics" group="core"
class="org.apache.solr.metrics.reporters.SolrJmxReporter"/-->
</metrics>
+
</solr>
diff --git
a/solr/solr-ref-guide/modules/deployment-guide/pages/metrics-reporting.adoc
b/solr/solr-ref-guide/modules/deployment-guide/pages/metrics-reporting.adoc
index b97a25280cf..ac069e247ec 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/metrics-reporting.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/metrics-reporting.adoc
@@ -310,6 +310,23 @@ complex objects:
</metrics>
----
+=== Caching Threads Metrics ===
+The threads metrics in the JVM group can be expensive to compute, as it
requires traversing all threads.
+This can be avoided for every call to the metrics API (group=jvm) by setting a
high caching expiration interval
+(in seconds). For example, to cache the thread metrics for 5 seconds:
+
+[source,xml]
+----
+<solr>
+ <metrics>
+ <caching>
+ <int name="threadsIntervalSeconds">5</int>
+ </caching>
+ ...
+ </metrics>
+...
+</solr>
+----
== Reporters