use of com.newrelic.agent.bridge.Transaction in project newrelic-java-agent by newrelic.
the class JavaxWsRsApi_Instrumentation method instrumentation.
@WeaveWithAnnotation(annotationClasses = { "javax.ws.rs.PUT", "javax.ws.rs.POST", "javax.ws.rs.GET", "javax.ws.rs.DELETE", "javax.ws.rs.HEAD", "javax.ws.rs.OPTIONS", "javax.ws.rs.PATCH" })
@WeaveIntoAllMethods
@Trace(dispatcher = true)
private static void instrumentation() {
Transaction transaction = AgentBridge.getAgent().getWeakRefTransaction(false);
if (transaction != null) {
JavaxWsRsApiHelper.ResourcePath resourcePath = JavaxWsRsApiHelper.subresourcePath.get();
if (!transaction.equals(resourcePath.transaction)) {
resourcePath.pathQueue.clear();
resourcePath.transaction = transaction;
}
String rootPath = null;
Path rootPathAnnotation = Weaver.getClassAnnotation(Path.class);
if (rootPathAnnotation != null) {
rootPath = rootPathAnnotation.value();
}
String methodPath = null;
Path methodPathAnnotation = Weaver.getMethodAnnotation(Path.class);
if (methodPathAnnotation != null) {
methodPath = methodPathAnnotation.value();
}
String httpMethod = null;
/* Unfortunately we have to do this in a big if/else block because we can't currently support variables passed
into the Weaver.getMethodAnnotation method. We might be able to make an improvement to handle this in the future */
if (Weaver.getMethodAnnotation(PUT.class) != null) {
httpMethod = PUT.class.getSimpleName();
} else if (Weaver.getMethodAnnotation(POST.class) != null) {
httpMethod = POST.class.getSimpleName();
} else if (Weaver.getMethodAnnotation(GET.class) != null) {
httpMethod = GET.class.getSimpleName();
} else if (Weaver.getMethodAnnotation(DELETE.class) != null) {
httpMethod = DELETE.class.getSimpleName();
} else if (Weaver.getMethodAnnotation(HEAD.class) != null) {
httpMethod = HEAD.class.getSimpleName();
} else if (Weaver.getMethodAnnotation(OPTIONS.class) != null) {
httpMethod = OPTIONS.class.getSimpleName();
} else {
// PATCH annotation was added later so may not be available
try {
if (Weaver.getMethodAnnotation(PATCH.class) != null) {
httpMethod = PATCH.class.getSimpleName();
}
} catch (NoClassDefFoundError e) {
}
}
if (httpMethod != null) {
Queue<String> subresourcePath = resourcePath.pathQueue;
String fullPath = JavaxWsRsApiHelper.getPath(rootPath, methodPath, httpMethod);
subresourcePath.offer(fullPath);
StringBuilder txNameBuilder = new StringBuilder();
String pathPart;
while ((pathPart = subresourcePath.poll()) != null) {
txNameBuilder.append(pathPart);
}
transaction.setTransactionName(TransactionNamePriority.FRAMEWORK_HIGH, false, "RestWebService", txNameBuilder.toString());
} else {
String fullPath = JavaxWsRsApiHelper.getPath(rootPath, methodPath, null);
if (!resourcePath.pathQueue.offer(fullPath)) {
AgentBridge.getAgent().getLogger().log(Level.FINE, "JAX-RS Subresource naming queue is full.");
resourcePath.pathQueue.clear();
}
}
}
}
use of com.newrelic.agent.bridge.Transaction in project newrelic-java-agent by newrelic.
the class MetricState method nonNetworkPreamble.
public void nonNetworkPreamble(boolean isConnected, HttpURLConnection connection, String operation) {
TracedMethod method = AgentBridge.getAgent().getTracedMethod();
Transaction tx = AgentBridge.getAgent().getTransaction(false);
if (!isConnected && method.isMetricProducer() && tx != null) {
// This method doesn't have any network I/O so we are explicitly not recording external rollup metrics
makeMetric(connection, method, operation);
tx.getCrossProcessState().processOutboundRequestHeaders(new OutboundWrapper(connection), method);
}
}
use of com.newrelic.agent.bridge.Transaction in project newrelic-java-agent by newrelic.
the class MetricState method getResponseCodePreamble.
public void getResponseCodePreamble(HttpURLConnection connection, TracedMethod method) {
Transaction tx = AgentBridge.getAgent().getTransaction(false);
if (method.isMetricProducer() && tx != null && !recordedANetworkCall) {
this.recordedANetworkCall = true;
makeMetric(connection, method, "getResponseCode");
}
}
use of com.newrelic.agent.bridge.Transaction in project newrelic-java-agent by newrelic.
the class HttpAsyncClient4_Instrumentation method execute.
/* Most common uses of the execute methods defined in the HttpAsyncClient interface should eventually call into this
* particular execute signature, thus instrumenting only this one should result in fairly thorough instrumentation
* coverage without double counting external calls. Possible exceptions include uses of execute in
* CachingHttpAsyncClient and those defined in the HttpPipeliningClient interface.
*/
public <T> Future<T> execute(HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer_Instrumentation<T> responseConsumer, HttpContext context, FutureCallback<T> callback) {
try {
URI uri = new URI(requestProducer.getTarget().toURI());
String scheme = uri.getScheme();
final Transaction txn = AgentBridge.getAgent().getTransaction(false);
// only instrument HTTP or HTTPS calls
final String lowerCaseScheme = scheme.toLowerCase();
if (("http".equals(lowerCaseScheme) || "https".equals(lowerCaseScheme)) && txn != null) {
try {
// Calls to generateRequest() don't appear to create a new HttpRequest object each time, but it does
// seem like other people could implement their own version that does. Something to be aware of.
final HttpRequest httpRequest = requestProducer.generateRequest();
Segment segment = txn.startSegment("External");
segment.addOutboundRequestHeaders(new OutboundWrapper(httpRequest));
// forward uri and segment to HttpAsyncResponseConsumer_Instrumentation
responseConsumer.segment = segment;
responseConsumer.uri = uri;
} catch (IOException | HttpException e) {
AgentBridge.getAgent().getLogger().log(Level.FINEST, e, "Caught exception in HttpAsyncClient4 instrumentation: {0}");
}
}
} catch (URISyntaxException uriSyntaxException) {
// if Java can't parse the URI, HttpAsyncClient won't be able to either
// let's just proceed without instrumentation
}
return Weaver.callOriginal();
}
use of com.newrelic.agent.bridge.Transaction in project newrelic-java-agent by newrelic.
the class FlyweightTraceMethodVisitor method onMethodEnter.
/**
* @see Transaction#startFlyweightTracer()
*/
@Override
protected void onMethodEnter() {
super.onMethodEnter();
// initialize local variables
push(0l);
super.storeLocal(startTimeLocal, Type.LONG_TYPE);
visitInsn(Opcodes.ACONST_NULL);
super.storeLocal(parentTracerLocal, BridgeUtils.TRACED_METHOD_TYPE);
visitInsn(Opcodes.ACONST_NULL);
super.storeLocal(metricNameLocal);
Label start = new Label();
Label end = new Label();
visitLabel(start);
BridgeUtils.getCurrentTransactionOrNull(this);
super.ifNull(end);
// System.nanoTime();
super.invokeStatic(Type.getType(System.class), new Method("nanoTime", Type.LONG_TYPE, new Type[0]));
super.storeLocal(startTimeLocal, Type.LONG_TYPE);
// load the current transaction (this gets rewritten later)
BridgeUtils.getCurrentTransaction(this);
Transaction transactionApi = BytecodeGenProxyBuilder.newBuilder(Transaction.class, this, true).build();
transactionApi.startFlyweightTracer();
super.storeLocal(parentTracerLocal, BridgeUtils.TRACED_METHOD_TYPE);
String fullMetricName = traceDetails.getFullMetricName(className, method.getName());
if (fullMetricName == null) {
fullMetricName = Strings.join(MetricNames.SEGMENT_DELIMITER, MetricNames.JAVA, className, method.getName());
}
push(fullMetricName);
super.storeLocal(metricNameLocal);
goTo(end);
Label handler = new Label();
visitLabel(handler);
// toss the exception on the stack
pop();
visitLabel(end);
visitTryCatchBlock(start, end, handler, TraceMethodVisitor.THROWABLE_TYPE.getInternalName());
super.visitLabel(startFinallyLabel);
}
Aggregations