Skip to content

Commit bae9e03

Browse files
authored
Merge pull request #2821 from newrelic/solr-jmx-9
Solr 9 JMX module
2 parents fe737e0 + b82e796 commit bae9e03

16 files changed

Lines changed: 1234 additions & 1 deletion

File tree

instrumentation/solr-jmx-7.4.0/build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@ verifyInstrumentation {
1919
passesOnly 'org.apache.solr:solr-core:[7.4.0,9.0.0)'
2020

2121
excludeRegex 'org.apache.solr:solr-core:.*(ALPHA|BETA)+$'
22-
}
22+
}
23+
24+
site {
25+
title 'Solr'
26+
type 'Datastore'
27+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
dependencies {
2+
implementation(project(":agent-bridge"))
3+
implementation(project(":agent-bridge-datastore"))
4+
implementation(project(":newrelic-api"))
5+
implementation(project(":newrelic-weaver-api"))
6+
7+
implementation("org.apache.lucene:lucene-core:9.0.0")
8+
implementation("org.apache.solr:solr-core:9.0.0") {
9+
exclude(group: "org.restlet.jee", module: "org.restlet")
10+
exclude(group: "org.restlet.jee", module: "org.restlet.ext.servlet")
11+
}
12+
}
13+
14+
jar {
15+
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.solr-jmx-9.0.0' }
16+
}
17+
18+
verifyInstrumentation {
19+
passesOnly 'org.apache.solr:solr-core:[9.0.0,10.0.0)'
20+
21+
excludeRegex 'org.apache.solr:solr-core:.*(ALPHA|BETA)+$'
22+
}
23+
24+
java {
25+
toolchain {
26+
languageVersion.set(JavaLanguageVersion.of(11))
27+
}
28+
}
29+
30+
test {
31+
onlyIf {
32+
!project.hasProperty('test8')
33+
}
34+
}
35+
36+
site {
37+
title 'Solr'
38+
type 'Datastore'
39+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
*
3+
* * Copyright 2026 New Relic Corporation. All rights reserved.
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
8+
package com.agent.instrumentation.solr;
9+
10+
import com.codahale.metrics.Metric;
11+
import com.newrelic.api.agent.NewRelic;
12+
import org.apache.solr.core.SolrInfoBean;
13+
import org.apache.solr.metrics.MetricsMap;
14+
15+
import java.util.Map;
16+
17+
public class CacheMetric extends NRMetric {
18+
19+
MetricsMap metric = null;
20+
String metricType = null;
21+
22+
public CacheMetric(String mt, String r, Metric m, String b) {
23+
super(r, b);
24+
metricType = mt;
25+
if (MetricsMap.class.isInstance(m)) {
26+
metric = (MetricsMap) m;
27+
}
28+
}
29+
30+
public CacheMetric(String mt, String r, Metric m, String b, String tag) {
31+
super(r, b);
32+
metricType = mt;
33+
if (MetricsMap.class.isInstance(m)) {
34+
metric = (MetricsMap) m;
35+
}
36+
this.contextTag = tag;
37+
}
38+
39+
@Override
40+
public String getMetricName(String name) {
41+
return getMetricBase() + "/" + name;
42+
}
43+
44+
@Override
45+
public int reportMetrics() {
46+
int numMetrics = 0;
47+
Map<String, Object> map = metric.getValue();
48+
for (String key : map.keySet()) {
49+
Object obj = map.get(key);
50+
if (Number.class.isInstance(obj)) {
51+
Number num = (Number) obj;
52+
String fullMetricName = getMetricName(key);
53+
NewRelic.recordMetric(fullMetricName, num.floatValue());
54+
numMetrics++;
55+
}
56+
}
57+
return numMetrics;
58+
}
59+
60+
@Override
61+
public String getMetricBase() {
62+
return prefix + registry + "/" + metricType + "/" + name;
63+
}
64+
65+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
*
3+
* * Copyright 2026 New Relic Corporation. All rights reserved.
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
8+
package com.agent.instrumentation.solr;
9+
10+
import com.codahale.metrics.Gauge;
11+
import com.newrelic.api.agent.NewRelic;
12+
import org.apache.solr.core.SolrInfoBean;
13+
14+
public class GaugeMetric extends NRMetric {
15+
16+
@SuppressWarnings("rawtypes")
17+
Gauge metric;
18+
String metricType;
19+
String metricName;
20+
21+
@SuppressWarnings("rawtypes")
22+
public GaugeMetric(String mn, String mt, String r, Gauge m, String b) {
23+
super(r, b);
24+
metric = m;
25+
metricType = mt;
26+
metricName = mn;
27+
}
28+
29+
@SuppressWarnings("rawtypes")
30+
public GaugeMetric(String mn, String mt, String r, Gauge m, String b, String tag) {
31+
super(r, b);
32+
metric = m;
33+
metricType = mt;
34+
metricName = mn;
35+
this.contextTag = tag;
36+
}
37+
38+
@Override
39+
public String getMetricName(String name) {
40+
return getMetricBase() + "/" + name;
41+
}
42+
43+
@Override
44+
public String getMetricBase() {
45+
return prefix + registry + "/" + metricType + "/" + name;
46+
}
47+
48+
@Override
49+
public int reportMetrics() {
50+
int numMetrics = 0;
51+
Object obj = metric.getValue();
52+
if (Number.class.isInstance(obj)) {
53+
Number num = (Number) obj;
54+
NewRelic.recordMetric(getMetricName(metricName), num.floatValue());
55+
numMetrics++;
56+
}
57+
return numMetrics;
58+
}
59+
60+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
*
3+
* * Copyright 2026 New Relic Corporation. All rights reserved.
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
8+
package com.agent.instrumentation.solr;
9+
10+
import com.codahale.metrics.Metered;
11+
import com.newrelic.api.agent.NewRelic;
12+
import org.apache.solr.core.SolrInfoBean;
13+
14+
public class MeteredMetric extends NRMetric {
15+
16+
Metered metered;
17+
String metricType;
18+
String metricName;
19+
20+
public MeteredMetric(String mn, String mt, String r, String b, Metered m) {
21+
super(r, b);
22+
metered = m;
23+
metricType = mt;
24+
metricName = mn;
25+
}
26+
27+
public MeteredMetric(String mn, String mt, String r, String b, Metered m, String tag) {
28+
super(r, b);
29+
metered = m;
30+
metricType = mt;
31+
metricName = mn;
32+
this.contextTag = tag;
33+
}
34+
35+
@Override
36+
public String getMetricName(String name) {
37+
return getMetricBase() + "/" + name;
38+
}
39+
40+
@Override
41+
public String getMetricBase() {
42+
return prefix + registry + "/" + metricType + "/" + name;
43+
}
44+
45+
@Override
46+
public int reportMetrics() {
47+
long count = metered.getCount();
48+
String fullMetricName = getMetricName(metricName);
49+
NewRelic.recordMetric(fullMetricName, count);
50+
return 1;
51+
}
52+
53+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
*
3+
* * Copyright 2026 New Relic Corporation. All rights reserved.
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
package com.agent.instrumentation.solr;
8+
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.StringTokenizer;
14+
import java.util.concurrent.ConcurrentHashMap;
15+
16+
public class MetricUtil {
17+
18+
private static List<String> desiredMetrics = new ArrayList<>();
19+
20+
private static List<String> desiredPaths = new ArrayList<>();
21+
22+
private static ConcurrentHashMap<String, NRMetric> metrics = new ConcurrentHashMap<>();
23+
24+
private static final String REGISTRY_PREFIX = "solr.core";
25+
26+
private static final HashMap<String, String> remaps = new HashMap<>();
27+
28+
static {
29+
desiredMetrics.add("filterCache");
30+
desiredMetrics.add("queryResultCache");
31+
desiredMetrics.add("documentCache");
32+
desiredPaths.add("updateHandler");
33+
remaps.put("cumulativeAdds", "cumulative_adds");
34+
remaps.put("cumulativeDeletesById", "cumulative_deletesById");
35+
remaps.put("cumulativeDeletesByQuery", "cumulative_deletesByQuery");
36+
remaps.put("cumulativeErrors", "cumulative_errors");
37+
}
38+
39+
public static String getRemap(String key) {
40+
if (remaps.containsKey(key)) {
41+
return remaps.get(key);
42+
}
43+
return key;
44+
}
45+
46+
public static void addMetric(NRMetric metric) {
47+
String metricBase = metric.getMetricBase();
48+
metrics.put(metricBase, metric);
49+
}
50+
51+
public static void removeMetric(String registry, String... metricPath) {
52+
metrics.entrySet()
53+
.stream()
54+
.filter(entry -> entry.getValue().registry.equals(registry) && Arrays.stream(metricPath).anyMatch(path -> path.startsWith(entry.getValue().name)))
55+
.forEach(x -> metrics.remove(x.getKey()));
56+
}
57+
58+
public static void swapRegistries(String sourceRegistry, String targetRegistry) {
59+
metrics.entrySet()
60+
.stream()
61+
.filter(entry -> entry.getValue().registry.equals(getRegistry(sourceRegistry)))
62+
.forEach(x -> {
63+
String currentKey = x.getKey();
64+
NRMetric metric = x.getValue();
65+
metric.setRegistry(getRegistry(targetRegistry));
66+
addMetric(metric);
67+
metrics.remove(currentKey);
68+
});
69+
}
70+
71+
public static void clearRegistry(String registry) {
72+
metrics.entrySet()
73+
.stream()
74+
.filter(entry -> entry.getValue().registry.equals(registry))
75+
.forEach(x -> metrics.remove(x.getKey()));
76+
}
77+
78+
public static void clearAll() {
79+
metrics.clear();
80+
}
81+
82+
public static String getRegistry(String r) {
83+
if (r.startsWith(REGISTRY_PREFIX)) {
84+
return r.substring(REGISTRY_PREFIX.length() + 1);
85+
} else {
86+
return r;
87+
}
88+
}
89+
90+
public static ConcurrentHashMap<String, NRMetric> getMetrics() {
91+
return metrics;
92+
}
93+
94+
public static String getDesired(String metricName, String[] metricPath) {
95+
if (!isDesired(metricName, metricPath)) {
96+
return null;
97+
}
98+
if (metricName != null && !metricName.isEmpty()) {
99+
StringTokenizer st = new StringTokenizer(metricName, ".");
100+
while (st.hasMoreTokens()) {
101+
String token = st.nextToken();
102+
if (desiredMetrics.contains(token)) {
103+
return token;
104+
}
105+
}
106+
}
107+
if (metricPath != null) {
108+
for (int i = 0; i < metricPath.length; i++) {
109+
if (desiredPaths.contains(metricPath[i])) {
110+
return metricPath[i];
111+
}
112+
}
113+
}
114+
return null;
115+
}
116+
117+
public static boolean isDesired(String metricName, String[] metricPath) {
118+
if (metricName != null && !metricName.isEmpty()) {
119+
StringTokenizer st = new StringTokenizer(metricName, ".");
120+
while (st.hasMoreTokens()) {
121+
String token = st.nextToken();
122+
if (desiredMetrics.contains(token)) {
123+
return true;
124+
}
125+
}
126+
}
127+
if (metricPath != null) {
128+
for (int i = 0; i < metricPath.length; i++) {
129+
if (desiredPaths.contains(metricPath[i])) {
130+
return true;
131+
}
132+
}
133+
}
134+
return false;
135+
}
136+
137+
}

0 commit comments

Comments
 (0)