Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion instrumentation/solr-jmx-7.4.0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ verifyInstrumentation {
passesOnly 'org.apache.solr:solr-core:[7.4.0,9.0.0)'

excludeRegex 'org.apache.solr:solr-core:.*(ALPHA|BETA)+$'
}
}

site {
title 'Solr'
type 'Datastore'
}
39 changes: 39 additions & 0 deletions instrumentation/solr-jmx-9.0.0/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
dependencies {
implementation(project(":agent-bridge"))
implementation(project(":agent-bridge-datastore"))
implementation(project(":newrelic-api"))
implementation(project(":newrelic-weaver-api"))

implementation("org.apache.lucene:lucene-core:9.0.0")
implementation("org.apache.solr:solr-core:9.0.0") {
exclude(group: "org.restlet.jee", module: "org.restlet")
exclude(group: "org.restlet.jee", module: "org.restlet.ext.servlet")
}
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.solr-jmx-9.0.0' }
}

verifyInstrumentation {
passesOnly 'org.apache.solr:solr-core:[9.0.0,10.0.0)'

excludeRegex 'org.apache.solr:solr-core:.*(ALPHA|BETA)+$'
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}

test {
onlyIf {
!project.hasProperty('test8')
}
}

site {
title 'Solr'
type 'Datastore'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package com.agent.instrumentation.solr;

import com.codahale.metrics.Metric;
import com.newrelic.api.agent.NewRelic;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.MetricsMap;

import java.util.Map;

public class CacheMetric extends NRMetric {

MetricsMap metric = null;
String metricType = null;

public CacheMetric(String mt, String r, Metric m, String b) {
super(r, b);
metricType = mt;
if (MetricsMap.class.isInstance(m)) {
metric = (MetricsMap) m;
}
}

public CacheMetric(String mt, String r, Metric m, String b, String tag) {
super(r, b);
metricType = mt;
if (MetricsMap.class.isInstance(m)) {
metric = (MetricsMap) m;
}
this.contextTag = tag;
}

@Override
public String getMetricName(String name) {
return getMetricBase() + "/" + name;
}

@Override
public int reportMetrics() {
int numMetrics = 0;
Map<String, Object> map = metric.getValue();
for (String key : map.keySet()) {
Object obj = map.get(key);
if (Number.class.isInstance(obj)) {
Number num = (Number) obj;
String fullMetricName = getMetricName(key);
NewRelic.recordMetric(fullMetricName, num.floatValue());
numMetrics++;
}
}
return numMetrics;
}

@Override
public String getMetricBase() {
return prefix + registry + "/" + metricType + "/" + name;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package com.agent.instrumentation.solr;

import com.codahale.metrics.Gauge;
import com.newrelic.api.agent.NewRelic;
import org.apache.solr.core.SolrInfoBean;

public class GaugeMetric extends NRMetric {

@SuppressWarnings("rawtypes")
Gauge metric;
String metricType;
String metricName;

@SuppressWarnings("rawtypes")
public GaugeMetric(String mn, String mt, String r, Gauge m, String b) {
super(r, b);
metric = m;
metricType = mt;
metricName = mn;
}

@SuppressWarnings("rawtypes")
public GaugeMetric(String mn, String mt, String r, Gauge m, String b, String tag) {
super(r, b);
metric = m;
metricType = mt;
metricName = mn;
this.contextTag = tag;
}

@Override
public String getMetricName(String name) {
return getMetricBase() + "/" + name;
}

@Override
public String getMetricBase() {
return prefix + registry + "/" + metricType + "/" + name;
}

@Override
public int reportMetrics() {
int numMetrics = 0;
Object obj = metric.getValue();
if (Number.class.isInstance(obj)) {
Number num = (Number) obj;
NewRelic.recordMetric(getMetricName(metricName), num.floatValue());
numMetrics++;
}
return numMetrics;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/

package com.agent.instrumentation.solr;

import com.codahale.metrics.Metered;
import com.newrelic.api.agent.NewRelic;
import org.apache.solr.core.SolrInfoBean;

public class MeteredMetric extends NRMetric {

Metered metered;
String metricType;
String metricName;

public MeteredMetric(String mn, String mt, String r, String b, Metered m) {
super(r, b);
metered = m;
metricType = mt;
metricName = mn;
}

public MeteredMetric(String mn, String mt, String r, String b, Metered m, String tag) {
super(r, b);
metered = m;
metricType = mt;
metricName = mn;
this.contextTag = tag;
}

@Override
public String getMetricName(String name) {
return getMetricBase() + "/" + name;
}

@Override
public String getMetricBase() {
return prefix + registry + "/" + metricType + "/" + name;
}

@Override
public int reportMetrics() {
long count = metered.getCount();
String fullMetricName = getMetricName(metricName);
NewRelic.recordMetric(fullMetricName, count);
return 1;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package com.agent.instrumentation.solr;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;

public class MetricUtil {

private static List<String> desiredMetrics = new ArrayList<>();

private static List<String> desiredPaths = new ArrayList<>();

private static ConcurrentHashMap<String, NRMetric> metrics = new ConcurrentHashMap<>();

private static final String REGISTRY_PREFIX = "solr.core";

private static final HashMap<String, String> remaps = new HashMap<>();

static {
desiredMetrics.add("filterCache");
desiredMetrics.add("queryResultCache");
desiredMetrics.add("documentCache");
desiredPaths.add("updateHandler");
remaps.put("cumulativeAdds", "cumulative_adds");
remaps.put("cumulativeDeletesById", "cumulative_deletesById");
remaps.put("cumulativeDeletesByQuery", "cumulative_deletesByQuery");
remaps.put("cumulativeErrors", "cumulative_errors");
}

public static String getRemap(String key) {
if (remaps.containsKey(key)) {
return remaps.get(key);
}
return key;
}

public static void addMetric(NRMetric metric) {
String metricBase = metric.getMetricBase();
metrics.put(metricBase, metric);
}

public static void removeMetric(String registry, String... metricPath) {
metrics.entrySet()
.stream()
.filter(entry -> entry.getValue().registry.equals(registry) && Arrays.stream(metricPath).anyMatch(path -> path.startsWith(entry.getValue().name)))
.forEach(x -> metrics.remove(x.getKey()));
}

public static void swapRegistries(String sourceRegistry, String targetRegistry) {
metrics.entrySet()
.stream()
.filter(entry -> entry.getValue().registry.equals(getRegistry(sourceRegistry)))
.forEach(x -> {
String currentKey = x.getKey();
NRMetric metric = x.getValue();
metric.setRegistry(getRegistry(targetRegistry));
addMetric(metric);
metrics.remove(currentKey);
});
}

public static void clearRegistry(String registry) {
metrics.entrySet()
.stream()
.filter(entry -> entry.getValue().registry.equals(registry))
.forEach(x -> metrics.remove(x.getKey()));
}

public static void clearAll() {
metrics.clear();
}

public static String getRegistry(String r) {
if (r.startsWith(REGISTRY_PREFIX)) {
return r.substring(REGISTRY_PREFIX.length() + 1);
} else {
return r;
}
}

public static ConcurrentHashMap<String, NRMetric> getMetrics() {
return metrics;
}

public static String getDesired(String metricName, String[] metricPath) {
if (!isDesired(metricName, metricPath)) {
return null;
}
if (metricName != null && !metricName.isEmpty()) {
StringTokenizer st = new StringTokenizer(metricName, ".");
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (desiredMetrics.contains(token)) {
return token;
}
}
}
if (metricPath != null) {
for (int i = 0; i < metricPath.length; i++) {
if (desiredPaths.contains(metricPath[i])) {
return metricPath[i];
}
}
}
return null;
}

public static boolean isDesired(String metricName, String[] metricPath) {
if (metricName != null && !metricName.isEmpty()) {
StringTokenizer st = new StringTokenizer(metricName, ".");
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (desiredMetrics.contains(token)) {
return true;
}
}
}
if (metricPath != null) {
for (int i = 0; i < metricPath.length; i++) {
if (desiredPaths.contains(metricPath[i])) {
return true;
}
}
}
return false;
}

}
Loading
Loading