Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updates to work with Micronaut Http Netty 4.6 #19

Merged
merged 1 commit into from
Aug 28, 2024
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
2 changes: 1 addition & 1 deletion micronaut-http-server-netty-4.5/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jar {
}

verifyInstrumentation {
passes 'io.micronaut:micronaut-http-server-netty:[4.5.0,)'
passes 'io.micronaut:micronaut-http-server-netty:[4.5.0,4.6.0)'
excludeRegex '.*RC.'
excludeRegex '.*M.'
}
32 changes: 32 additions & 0 deletions micronaut-http-server-netty-4.6/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

// Build.gradle generated for instrumentation module micronaut-http-netty-2

apply plugin: 'java'

targetCompatibility=JavaVersion.VERSION_17

dependencies {
implementation 'io.micronaut:micronaut-http-server-netty:4.6.0'
implementation group: 'io.projectreactor', name: 'reactor-core', version: '3.5.11'

// New Relic Java Agent dependencies
implementation 'com.newrelic.agent.java:newrelic-agent:7.4.0'
implementation 'com.newrelic.agent.java:newrelic-api:7.4.0'
implementation fileTree(include: ['*.jar'], dir: '../libs')
implementation fileTree(include: ['*.jar'], dir: '../test-lib')
}

jar {
manifest {
attributes 'Implementation-Title': 'com.newrelic.instrumentation.labs.micronaut-http-server-netty-4.6'
attributes 'Implementation-Vendor': 'New Relic Labs'
attributes 'Implementation-Vendor-Id': 'com.newrelic.labs'
attributes 'Implementation-Version': 1.0
}
}

verifyInstrumentation {
passes 'io.micronaut:micronaut-http-server-netty:[4.6.0,)'
excludeRegex '.*RC.'
excludeRegex '.*M.'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.newrelic.instrumentation.micronaut.netty_45;

import java.util.function.BiConsumer;

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

public class NRBiConsumerWrapper<R> implements BiConsumer<R, Throwable> {

BiConsumer<R, Throwable> delegate = null;
private Token token = null;
private static boolean isTransformed = false;

public NRBiConsumerWrapper(BiConsumer<R, Throwable> d, Token t) {
delegate = d;
token = t;
if(!isTransformed) {
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
isTransformed = true;
}
}

@Override
@Trace(async = true)
public void accept(R t, Throwable u) {
if(token != null) {
token.linkAndExpire();
token = null;
}
if(u != null) {
NewRelic.noticeError(u);
}
if(delegate != null) {
delegate.accept(t, u);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.newrelic.instrumentation.micronaut.netty_45;

import java.util.Map;

import io.micronaut.web.router.RouteMatch;

public class Utils {

public static void decorateWithRoute(RouteMatch<?> routeMatch) {
// TracedMethod traced = NewRelic.getAgent().getTracedMethod();
// if(routeMatch instanceof BasicObjectRouteMatch) {
// BasicObjectRouteMatch objMatch = (BasicObjectRouteMatch)routeMatch;
// Class<?> declaringClass = objMatch.getDeclaringType();
// traced.setMetricName("Custom","Micronaut","Netty","Route","Object", declaringClass.getSimpleName());
// traced.addCustomAttribute("Declaring-Class", declaringClass.getName());
// } else if(routeMatch instanceof UriRouteMatch) {
// UriRouteMatch<?,?> uriRouteMatch = (UriRouteMatch<?, ?>)routeMatch;
//
//
//
// String uri = uriRouteMatch.getUri();
// UriMatchTemplate matchTemplate = uriRouteMatch.getRoute().getUriMatchTemplate();
// String pathString = matchTemplate != null ? matchTemplate.toPathString() : null;
//
// String uriTemplate = uriRouteMatch.toString();
// String methodName = uriRouteMatch.getMethodName();
// String name = uriRouteMatch.getName();
//
// HashMap<String, Object> attributes = new HashMap<String, Object>();
// addAttribute(attributes, "PathString", pathString);
// addAttribute(attributes, "Method-Name", methodName);
// addAttribute(attributes, "URI", uri);
// addAttribute(attributes, "URITemplate", uriTemplate);
// addAttribute(attributes, "Name", name);
// traced.addCustomAttributes(attributes);
//
// traced.setMetricName("Custom","Micronaut","Netty","Route","URI");
// }
}

public static void addAttribute(Map<String, Object> attributes, String key, Object value) {
if(attributes != null && key != null && !key.isEmpty() && value != null) {
attributes.put(key, value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.micronaut.http.reactive.execution;

import java.util.function.BiConsumer;

import org.reactivestreams.Publisher;

import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.NewField;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import com.newrelic.instrumentation.micronaut.netty_45.NRBiConsumerWrapper;

import reactor.core.publisher.Mono;

@Weave
abstract class ReactorExecutionFlowImpl {

@NewField
protected Token token = null;

<K> ReactorExecutionFlowImpl(Publisher<K> value) {
}

<K> ReactorExecutionFlowImpl(Mono<K> value) {
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Trace(async = true)
public void onComplete(BiConsumer<? super Object, Throwable> fn) {
if(token != null) {
token.link();
NRBiConsumerWrapper wrapper = new NRBiConsumerWrapper(fn, token);
token = null;
fn = wrapper;
}
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.micronaut.http.server.netty;

import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

import io.micronaut.http.body.CloseableByteBody;
import io.micronaut.http.server.netty.handler.OutboundAccess;
import io.netty.channel.ChannelHandlerContext;

@Weave
public abstract class RoutingInBoundHandler {

@Trace(dispatcher = true)
public void accept(ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpRequest request, CloseableByteBody body, OutboundAccess outboundAccess) {
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.micronaut.http.server.netty.handler;

import com.newrelic.api.agent.weaver.SkipIfPresent;

@SkipIfPresent
class BlockingWriter {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package io.micronaut.http.server.netty.handler;

import com.newrelic.api.agent.NewRelic;
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 io.netty.channel.ChannelHandlerContext;

@Weave
public abstract class PipeliningServerHandler {

@Trace(dispatcher = true)
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Weaver.callOriginal();
}

@Weave
private static class MessageInboundHandler {

@Trace
void read(Object message) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","InboundHander","MessageInboundHandler","read");
Weaver.callOriginal();
}

}

@Weave
private static class DecompressingInboundHandler {

@Trace
void read(Object message) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","InboundHander","DecompressingInboundHandler","read");
Weaver.callOriginal();
}

}

@Weave
private static class OptimisticBufferingInboundHandler {

@Trace
void read(Object message) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","InboundHander","OptimisticBufferingInboundHandler","read");
Weaver.callOriginal();
}

}

@Weave
private static class DroppingInboundHandler {

@Trace
void read(Object message) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","InboundHander","DroppingInboundHandler","read");
Weaver.callOriginal();
}

}

@Weave
private static class StreamingInboundHandler {

@Trace
void read(Object message) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","InboundHander","StreamingInboundHandler","read");
Weaver.callOriginal();
}

}

@Weave
private static class ContinueOutboundHandler {

@Trace
void writeSome() {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","OutboundHander","ContinueOutboundHandler","writeSome");
Weaver.callOriginal();
}
}

@Weave
private static class FullOutboundHandler {

@Trace
void writeSome() {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","OutboundHander","FullOutboundHandler","writeSome");
Weaver.callOriginal();
}
}

@Weave
private static class StreamingOutboundHandler {

@Trace
void writeSome() {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Micronaut","HTTP","Netty","OutboundHander","StreamingOutboundHandler","writeSome");
Weaver.callOriginal();
}
}

@Weave
public static class OutboundAccessImpl {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.micronaut.http.server.netty.websocket;

import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

import io.netty.channel.ChannelHandlerContext;

@Weave
public abstract class NettyServerWebSocketHandler {

@Trace(dispatcher = true)
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
Weaver.callOriginal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.micronaut.http.server.netty.websocket;

import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;

import io.micronaut.http.body.CloseableByteBody;
import io.micronaut.http.server.netty.handler.OutboundAccess;
import io.netty.channel.ChannelHandlerContext;

@Weave
public abstract class NettyServerWebSocketUpgradeHandler {

@Trace(dispatcher = true)
public void accept(ChannelHandlerContext ctx, io.netty.handler.codec.http.HttpRequest request, CloseableByteBody body, OutboundAccess outboundAccess){
Weaver.callOriginal();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.netty.channel;

import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.NewField;
import com.newrelic.api.agent.weaver.Weave;

@Weave(type = MatchType.BaseClass, originalName = "io.netty.channel.ChannelPipeline")
public class ChannelPipeline_Instrumentation {

@NewField
public Token micronautToken;

}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ include 'micronaut-http-server-netty-4'
include 'micronaut-http-server-netty-4.3'
include 'micronaut-http-server-netty-4.4'
include 'micronaut-http-server-netty-4.5'
include 'micronaut-http-server-netty-4.6'
include 'micronaut-http'
include 'micronaut-http-server'
include 'micronaut-router'
Expand Down
Loading