Skip to content
Merged
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
79 changes: 79 additions & 0 deletions instrumentation/quarkus-rest-3.0.0/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
dependencies {
implementation(project(":agent-bridge"))
implementation('io.quarkus:quarkus-resteasy-reactive:3.0.0.Final')
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.quarkus-rest-3.0.0',
'Implementation-Title-Alias': 'quarkus'}
}

verifyInstrumentation {
passesOnly 'io.quarkus:quarkus-resteasy-reactive:[3.0.0,3.9.0)'
passesOnly 'io.quarkus:quarkus-rest:[3.9.0,)'
excludeRegex '.*CR.*'
excludeRegex '.*Alpha[0-9]'
excludeRegex '.*Beta[0-9]'

// quarkus-resteasy-reactive: exclude all pre-3.x versions (module does not apply)
exclude 'io.quarkus:quarkus-resteasy-reactive:[1.11.0.Final,3.0.0.Final)'
// quarkus-resteasy-reactive: keep only last patch of each minor
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.0.0.Final,3.0.3.Final]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.1.0.Final,3.1.2.Final]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.2.0.Final,3.2.11.Final]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.3.0,3.3.2]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.4.0,3.4.2]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.5.0,3.5.2]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.6.0,3.6.8]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.7.0,3.7.3]'
exclude 'io.quarkus:quarkus-resteasy-reactive:[3.8.0,3.8.6]'

// quarkus-rest: keep only last patch of each minor; 3.37.x left open to catch new releases
exclude 'io.quarkus:quarkus-rest:[3.9.0,3.9.4]'
exclude 'io.quarkus:quarkus-rest:[3.10.0,3.10.1]'
exclude 'io.quarkus:quarkus-rest:[3.11.0,3.11.2]'
exclude 'io.quarkus:quarkus-rest:[3.12.0,3.12.2]'
exclude 'io.quarkus:quarkus-rest:[3.13.0,3.13.2]'
exclude 'io.quarkus:quarkus-rest:[3.14.0,3.14.3]'
exclude 'io.quarkus:quarkus-rest:[3.15.0,3.15.6.2]'
exclude 'io.quarkus:quarkus-rest:[3.16.0,3.16.3]'
exclude 'io.quarkus:quarkus-rest:[3.17.0,3.17.7]'
exclude 'io.quarkus:quarkus-rest:[3.18.0,3.18.3]'
exclude 'io.quarkus:quarkus-rest:[3.19.0,3.19.3]'
exclude 'io.quarkus:quarkus-rest:[3.20.0,3.20.6.1]'
exclude 'io.quarkus:quarkus-rest:[3.21.0,3.21.3]'
exclude 'io.quarkus:quarkus-rest:[3.22.0,3.22.2]'
exclude 'io.quarkus:quarkus-rest:[3.23.0,3.23.3]'
exclude 'io.quarkus:quarkus-rest:[3.24.0,3.24.4]'
exclude 'io.quarkus:quarkus-rest:[3.25.0,3.25.3]'
exclude 'io.quarkus:quarkus-rest:[3.26.0,3.26.3]'
exclude 'io.quarkus:quarkus-rest:[3.27.0,3.27.4]'
exclude 'io.quarkus:quarkus-rest:[3.28.0,3.28.4]'
exclude 'io.quarkus:quarkus-rest:[3.29.0,3.29.3]'
exclude 'io.quarkus:quarkus-rest:[3.30.0,3.30.7]'
exclude 'io.quarkus:quarkus-rest:[3.31.0,3.31.3]'
exclude 'io.quarkus:quarkus-rest:[3.32.0,3.32.3]'
exclude 'io.quarkus:quarkus-rest:[3.33.0,3.33.2]'
exclude 'io.quarkus:quarkus-rest:[3.34.0,3.34.6]'
exclude 'io.quarkus:quarkus-rest:[3.35.0,3.35.3]'
exclude 'io.quarkus:quarkus-rest:[3.36.0,3.36.2]'
// The next excludes will be 3.37.x
}

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

test {
// These instrumentation tests only run on Java 17+ regardless of the -PtestN gradle property that is set.
onlyIf {
!project.hasProperty('test8') && !project.hasProperty('test11')
}
}

site {
title 'Quarkus'
type 'Framework'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package com.nr.agent.instrumentation;

import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.TransactionNamePriority;
import org.jboss.resteasy.reactive.server.mapping.RuntimeResource;
import org.jboss.resteasy.reactive.server.mapping.URITemplate;

public class QuarkusUtils {
// Keys owned by the vertx-web-3.8.3 module — used to bridge into its transaction and
// suppress its name in favor of the JAX-RS route template.
public static final String VERTX_TOKEN_KEY = "newrelic-token";
public static final String VERTX_PATH_KEY = "newrelic-path";

public static void setTransactionName(RuntimeResource resource) {
if (resource != null) {
URITemplate classPath = resource.getClassPath();
URITemplate path = resource.getPath();
String httpMethod = resource.getHttpMethod();

StringBuilder sb = new StringBuilder();
if (classPath != null && classPath.template != null && !classPath.template.isEmpty()) {
sb.append(classPath.template);
}
if (path != null && path.template != null && !path.template.isEmpty()) {
sb.append(path.template);
}
if (httpMethod != null && !httpMethod.isEmpty()) {
sb.append(" (").append(httpMethod).append(")");
}

// We use CUSTOM_LOW here to prevent the Vertx module from overwriting the transaction name
// when a quarkus error occurs. CUSTOM_LOW is priority 11; FRAMEWORK_HIGH is 10.
if (sb.length() > 0) {
NewRelic.getAgent().getTransaction()
.setTransactionName(TransactionNamePriority.CUSTOM_LOW, false, "Quarkus", sb.toString());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package org.jboss.resteasy.reactive.server.handlers;

import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.QuarkusUtils;
import io.vertx.ext.web.RoutingContext;
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;

@Weave(originalName = "org.jboss.resteasy.reactive.server.handlers.InvocationHandler")
public class InvocationHandler_Instrumentation {

@Trace(async = true)
public void handle(ResteasyReactiveRequestContext requestContext) {
RoutingContext routingContext = requestContext.serverRequest().unwrap(RoutingContext.class);
if (routingContext != null) {
Token vertxToken = routingContext.get(QuarkusUtils.VERTX_TOKEN_KEY);
if (vertxToken != null) {
vertxToken.link();
}

// Clears the Vert.x path queue so the vertx-web module's headers-end handler
// doesn't overwrite the JAX-RS route template name we set below.
routingContext.data().remove(QuarkusUtils.VERTX_PATH_KEY);
}

QuarkusUtils.setTransactionName(requestContext.getTarget());
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package org.jboss.resteasy.reactive.server.vertx;

import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.QuarkusUtils;
import io.vertx.ext.web.RoutingContext;

@Weave(originalName = "org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler", type = MatchType.ExactClass)
public class ResteasyReactiveVertxHandler_Instrumentation {

// We're going to piggyback off of the transaction started in the vertx-web module
@Trace(async = true)
public void handle(RoutingContext event) {
Token vertxToken = event.get(QuarkusUtils.VERTX_TOKEN_KEY);
if (vertxToken != null) {
vertxToken.link();
}
Weaver.callOriginal();
}
}
47 changes: 47 additions & 0 deletions instrumentation/smallrye-mutiny-1.0.0/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
dependencies {
implementation(project(":agent-bridge"))
implementation('io.smallrye.reactive:mutiny:0.14.0')
}

jar {
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.smallrye-mutiny-0.14.0' }
}

verifyInstrumentation {
passesOnly 'io.smallrye.reactive:mutiny:[1.0.0,)'
excludeRegex '.*Alpha.*'
excludeRegex '.*Beta.*'
excludeRegex '.*RC.*'
excludeRegex '.*milestone.*'
excludeRegex '.*-M[0-9].*'

// Ignore all 0.x.x versions
excludeRegex 'io.smallrye.reactive:mutiny:0\\..*'


// Keep only last patch of each minor ver to reduce verifier task size
exclude 'io.smallrye.reactive:mutiny:[1.1.0,1.1.2)'
exclude 'io.smallrye.reactive:mutiny:[1.3.0,1.3.1)'
exclude 'io.smallrye.reactive:mutiny:[2.3.0,2.3.1)'
exclude 'io.smallrye.reactive:mutiny:[2.5.0,2.5.8)'
exclude 'io.smallrye.reactive:mutiny:[2.6.0,2.6.2)'
// 2.7.0 and 2.8.0 are singletons — no excludes needed yet
}

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

test {
// These instrumentation tests only run on Java 17+ regardless of the -PtestN gradle property that is set.
onlyIf {
!project.hasProperty('test8') && !project.hasProperty('test11')
}
}

site {
title 'Quarkus'
type 'Framework'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package com.nr.agent.instrumentation;


import com.newrelic.agent.bridge.AgentBridge;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Token;

import java.util.Map;

public class SmallRyeUtils {
// This replaces the usage of @NewField in the Subscriber weave classes
private static final Map<Object, Token> tokenMap = AgentBridge.collectionFactory.createConcurrentWeakKeyedMap();

public static void assignTokenToSubscriber(Object subscriber) {
if (subscriber != null) {
if (getToken(subscriber) == null) {
Token token = NewRelic.getAgent().getTransaction().getToken();
if (token.isActive()) {
putToken(subscriber, token);
} else {
token.expire();
}
}
}
}

public static void putToken(Object key, Token token) {
tokenMap.put(key, token);
}

public static Token getToken(Object key) {
return tokenMap.get(key);
}

// Here to allow proactive removal of tokens if possible
public static void removeToken(Object key) {
tokenMap.remove(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package io.smallrye.mutiny.operators.multi;

import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.SmallRyeUtils;
import io.smallrye.mutiny.subscription.MultiSubscriber_Instrumentation;

@Weave(originalName = "io.smallrye.mutiny.operators.multi.MultiEmitOnOp", type = MatchType.ExactClass)
public class MultiEmitOnOp_Instrumentation<T> {
public void subscribe(MultiSubscriber_Instrumentation<? super T> subscriber) {
SmallRyeUtils.assignTokenToSubscriber(subscriber);
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package io.smallrye.mutiny.operators.multi;

import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.SmallRyeUtils;
import io.smallrye.mutiny.subscription.MultiSubscriber_Instrumentation;

@Weave(originalName = "io.smallrye.mutiny.operators.multi.MultiSubscribeOnOp", type = MatchType.ExactClass)
public class MultiSubscribeOnOp_Instrumentation<T> {
public void subscribe(MultiSubscriber_Instrumentation<? super T> subscriber) {
SmallRyeUtils.assignTokenToSubscriber(subscriber);
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package io.smallrye.mutiny.operators.uni;

import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.SmallRyeUtils;
import io.smallrye.mutiny.subscription.UniSubscriber_Instrumentation;

@Weave(originalName = "io.smallrye.mutiny.operators.uni.UniEmitOn", type = MatchType.ExactClass)
public class UniEmitOn_Instrumentation<I> {
public void subscribe(UniSubscriber_Instrumentation<? super I> subscriber) {
SmallRyeUtils.assignTokenToSubscriber(subscriber);
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
*
* * Copyright 2026 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package io.smallrye.mutiny.operators.uni;

import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.nr.agent.instrumentation.SmallRyeUtils;
import io.smallrye.mutiny.subscription.UniSubscriber_Instrumentation;

@Weave(originalName = "io.smallrye.mutiny.operators.uni.UniRunSubscribeOn", type = MatchType.ExactClass)
public class UniRunSubscribeOn_Instrumentation<I> {
public void subscribe(UniSubscriber_Instrumentation<? super I> subscriber) {
SmallRyeUtils.assignTokenToSubscriber(subscriber);
Weaver.callOriginal();
}
}
Loading
Loading