use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.
the class InstrumentationImpl method oldCreateSqlTracer.
// This code path is similar to the 3.16.1 and earlier tracer creation path. It is retained for use by legacy
// async instrumentation, including NAPS (Netty, Akka, Play, Scala) and async servlet instrumentation.
private ExitTracer oldCreateSqlTracer(TransactionActivity txa, Object invocationTarget, int signatureId, String metricName, int flags) {
if (txa == null) {
AgentBridge.TokenAndRefCount tokenAndRefCount = AgentBridge.activeToken.get();
if (tokenAndRefCount != null && tokenAndRefCount.token != null) {
// Fast path for scala instrumentation (and potentially others in the future)
Transaction tx = Transaction.getTransaction(false);
if (tx == null) {
if (tokenAndRefCount.token.getTransaction() instanceof Transaction) {
tx = (Transaction) tokenAndRefCount.token.getTransaction();
} else {
return null;
}
}
txa = TransactionActivity.create(tx, Integer.MAX_VALUE);
flags = flags | TracerFlags.ASYNC;
ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
MetricNameFormat mnf = MetricNameFormats.getFormatter(invocationTarget, sig, metricName, flags);
Tracer tracer;
if (TracerFlags.isRoot(flags)) {
// Dispatcher || Async
tracer = new OtherRootSqlTracer(txa, sig, invocationTarget, mnf, flags);
} else if (overSegmentLimit(txa)) {
logger.log(Level.FINEST, "Transaction has exceeded tracer segment limit. Returning ultralight sql tracer.");
return UltraLightTracer.createClampedSegment(txa, sig);
} else {
tracer = new DefaultSqlTracer(txa, sig, invocationTarget, mnf, flags);
}
txa.tracerStarted(tracer);
Tracer initiatingTracer = (Tracer) tokenAndRefCount.tracedMethod.getAndSet(tracer);
tx.startFastAsyncWork(txa, initiatingTracer);
return tracer;
} else if (TracerFlags.isAsync(flags)) {
txa = TransactionActivity.create(null, Integer.MAX_VALUE);
return startTracer(txa, invocationTarget, signatureId, metricName, flags);
}
}
// Avoid creating tracers for NoOpTransaction, etc.
com.newrelic.agent.Transaction transaction = com.newrelic.agent.Transaction.getTransaction(TracerFlags.isDispatcher(flags));
if (transaction == null) {
return null;
}
try {
if (!TracerFlags.isDispatcher(flags) && !transaction.isStarted()) {
// if we're not in a transaction and this isn't a dispatcher tracer, bail before we create objects
return null;
}
if (transaction.getTransactionActivity().isLeaf()) {
return null;
}
ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
return transaction.getTransactionState().getSqlTracer(transaction, invocationTarget, sig, metricName, flags);
} catch (Throwable t) {
logger.log(Level.FINEST, t, "createTracer({0}, {1}, {2}, {3})", invocationTarget, signatureId, metricName, flags);
return null;
}
}
use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.
the class SegmentTest method testPsuedoAsync2.
/**
* tracer(dispatcher) start
* --tracedActivity start
* --tracer2 start
* --tracer2 end
* --tracedActivity finish
* tracer finish
* <p>
* Transaction must have two txas due to the creation of tracer2 between the tracedActivity start and finish
* Segment tracer must correctly link to root tracer.
*/
@Test
public void testPsuedoAsync2() throws InterruptedException {
Tracer root = makeTransaction();
Assert.assertNotNull(root);
Assert.assertNotNull(root.getTransactionActivity().getTransaction());
Thread.sleep(1);
final Segment segment = root.getTransactionActivity().getTransaction().startSegment(MetricNames.CUSTOM, "Custom Psuedo Async2");
Assert.assertNotNull(segment);
ExitTracer child = AgentBridge.instrumentation.createTracer(null, 0, "iamyourchild", DefaultTracer.DEFAULT_TRACER_FLAGS);
child.finish(Opcodes.ARETURN, null);
assertTrue(child.getParentTracedMethod() == root);
Thread.sleep(1);
// Need to check this before the segment ends
Assert.assertSame("Segment must be child of root tracer", root, segment.getTracedMethod().getParentTracedMethod());
segment.end();
root.finish(Opcodes.ARETURN, null);
assertTrue(root.getTransactionActivity().getTransaction().isFinished());
assertEquals(2, root.getTransactionActivity().getTransaction().getCountOfRunningAndFinishedTransactionActivities());
assertEquals(3, getNumTracers(root.getTransactionActivity().getTransaction()));
}
use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.
the class SegmentTest method testCorrectParenting.
/**
* Segments have their own txa since they're all ended async.
*/
@Test
public void testCorrectParenting() throws InterruptedException {
Tracer root = makeTransaction();
Assert.assertNotNull(root);
Assert.assertNotNull(root.getTransactionActivity().getTransaction());
{
final Segment segmentUnderRoot = root.getTransactionActivity().getTransaction().startSegment(MetricNames.CUSTOM, "Under Root");
Assert.assertNotNull(segmentUnderRoot);
Assert.assertSame("Segment has the wrong parent", root, segmentUnderRoot.getTracedMethod().getParentTracedMethod());
segmentUnderRoot.end();
}
{
ExitTracer child1 = AgentBridge.instrumentation.createTracer(null, 0, "iamyourchild1", DefaultTracer.DEFAULT_TRACER_FLAGS);
{
final Segment underChild1 = root.getTransactionActivity().getTransaction().startSegment(MetricNames.CUSTOM, "Under Child");
Assert.assertNotNull(underChild1);
Assert.assertSame("Segment has the wrong parent", child1, underChild1.getTracedMethod().getParentTracedMethod());
underChild1.end();
}
{
ExitTracer child2 = AgentBridge.instrumentation.createTracer(null, 0, "iamyourchild2", DefaultTracer.DEFAULT_TRACER_FLAGS);
{
final Segment underChild2 = root.getTransactionActivity().getTransaction().startSegment(MetricNames.CUSTOM, "Under Child 2");
Assert.assertNotNull(underChild2);
Assert.assertSame("Segment has the wrong parent", child2, underChild2.getTracedMethod().getParentTracedMethod());
underChild2.end();
}
child2.finish(Opcodes.ARETURN, null);
}
child1.finish(Opcodes.ARETURN, null);
}
assertFalse(root.getTransactionActivity().getTransaction().isFinished());
root.finish(Opcodes.ARETURN, null);
assertTrue(root.getTransactionActivity().getTransaction().isFinished());
// 4 txas: 1 for each of the 3 segments + 1 tracer
assertEquals(4, root.getTransactionActivity().getTransaction().getCountOfRunningAndFinishedTransactionActivities());
assertEquals(6, getNumTracers(root.getTransactionActivity().getTransaction()));
}
use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.
the class BaseMatchTest method testTrace.
@Test
public void testTrace() {
final boolean[] success = { false };
AgentBridge.instrumentation = new NoOpInstrumentation() {
@Override
public ExitTracer createTracer(Object invocationTarget, int signatureId, String metricName, int flags) {
success[0] = true;
return super.createTracer(invocationTarget, signatureId, metricName, flags);
}
};
Assert.assertNull(child.justTrace());
Assert.assertTrue(success[0]);
}
use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.
the class TraceMethodVisitor method onEveryExit.
/**
* This code is injected at every exit instruction, whether a return or an ATHROW.
*
* If opcode is a throw:
*
* Throwable t = <the exception>;<br/>
* if (tracer != null) {<br/>
* tracer.finish(opcode, t);<br/>
* }<br/>
*
* Otherwise:
*
* if (tracer != null) {<br/>
* tracer.finish(opcode, null);<br/>
* }<br/>
*/
protected void onEveryExit(int opcode) {
Label isTracerNullLabel = new Label();
loadLocal(tracerLocal);
ifNull(isTracerNullLabel);
if (Opcodes.ATHROW == opcode) {
dup();
}
// Label tryToFinishTracer = new Label();
// Label endTryToFinishTracer = new Label();
// visitLabel(tryToFinishTracer);
loadLocal(tracerLocal);
ExitTracer tracer = BytecodeGenProxyBuilder.newBuilder(ExitTracer.class, this, false).build();
if (Opcodes.ATHROW == opcode) {
swap();
tracer.finish(null);
} else {
push(opcode);
visitInsn(Opcodes.ACONST_NULL);
tracer.finish(0, null);
}
visitLabel(isTracerNullLabel);
}
Aggregations