Search in sources :

Example 6 with ExitTracer

use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.

the class CircuitBreakerServiceFunctionalTest method aTransaction.

@Trace(dispatcher = true)
private void aTransaction(boolean breakerTripped) {
    Transaction transaction = NewRelic.getAgent().getTransaction();
    InstrumentationImpl impl = new InstrumentationImpl(Agent.LOG);
    if (breakerTripped) {
        ExitTracer createdTracer = impl.createTracer(null, 0, "metricName", TracerFlags.DISPATCHER);
        Assert.assertNull(createdTracer);
        Assert.assertTrue(transaction instanceof NoOpTransaction);
    } else {
        Assert.assertTrue(transaction instanceof TransactionApiImpl);
    }
}
Also used : ExitTracer(com.newrelic.agent.bridge.ExitTracer) NoOpTransaction(com.newrelic.agent.bridge.NoOpTransaction) Transaction(com.newrelic.api.agent.Transaction) InstrumentationImpl(com.newrelic.agent.instrumentation.InstrumentationImpl) TransactionApiImpl(com.newrelic.agent.TransactionApiImpl) NoOpTransaction(com.newrelic.agent.bridge.NoOpTransaction) Trace(com.newrelic.api.agent.Trace)

Example 7 with ExitTracer

use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.

the class Transaction method requestInitialized.

public void requestInitialized(Request request, Response response) {
    Agent.LOG.log(Level.FINEST, "Request initialized: {0}", request.getRequestURI());
    synchronized (requestStateChangeLock) {
        ServiceFactory.getStatsService().doStatsWork(StatsWorks.getIncrementCounterWork(MetricNames.SUPPORTABILITY_TRANSACTION_REQUEST_INITIALIZED, 1), MetricNames.SUPPORTABILITY_TRANSACTION_REQUEST_INITIALIZED);
        if (this.isFinished()) {
            return;
        }
        if (dispatcher == null) {
            ExitTracer tracer = AgentBridge.instrumentation.createTracer(null, REQUEST_INITIALIZED_CLASS_SIGNATURE_ID, null, REQUEST_TRACER_FLAGS);
            if (tracer != null) {
                if (response == null) {
                    response = DUMMY_RESPONSE;
                }
                setDispatcher(new WebRequestDispatcher(request, response, this));
            }
        } else {
            // JAVA-825. Ignore multiple requestInitialized() callbacks.
            ServiceFactory.getStatsService().doStatsWork(StatsWorks.getIncrementCounterWork(MetricNames.SUPPORTABILITY_TRANSACTION_REQUEST_INITIALIZED_STARTED, 1), MetricNames.SUPPORTABILITY_TRANSACTION_REQUEST_INITIALIZED_STARTED);
            Agent.LOG.finer("requestInitialized(): transaction already started.");
        }
    }
}
Also used : ExitTracer(com.newrelic.agent.bridge.ExitTracer) WebRequestDispatcher(com.newrelic.agent.dispatchers.WebRequestDispatcher)

Example 8 with ExitTracer

use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.

the class InstrumentationImpl method oldCreateTracer.

// This code path is similar to the 3.16.1 and earlier tracer creation path. It is retained for use by legacy async
// instrumentation: Play1 and async servlet 3.0 instrumentation. The key difference from the "fast path" is that
// this path switches on the TransactionState during creation.
private ExitTracer oldCreateTracer(TransactionActivity txa, Object invocationTarget, int signatureId, String metricName, int flags) {
    // oldCreateTracer behavior below.
    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 OtherRootTracer(txa, sig, invocationTarget, mnf, flags);
            } else {
                tracer = new DefaultTracer(txa, sig, invocationTarget, mnf, flags);
            }
            txa.tracerStarted(tracer);
            Tracer initiatingTracer = (Tracer) tokenAndRefCount.tracedMethod.getAndSet(tracer);
            tx.startFastAsyncWork(txa, initiatingTracer);
            return noticeTracer(signatureId, flags, 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 noticeTracer(signatureId, flags, null);
        }
        if (transaction.getTransactionActivity().isLeaf()) {
            return null;
        }
        ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
        return transaction.getTransactionState().getTracer(transaction, invocationTarget, sig, metricName, flags);
    } catch (Throwable t) {
        logger.log(Level.FINEST, t, "createTracer({0}, {1}, {2}, {3})", invocationTarget, signatureId, metricName, flags);
        return null;
    }
}
Also used : Transaction(com.newrelic.agent.Transaction) NoOpTransaction(com.newrelic.agent.bridge.NoOpTransaction) ClassMethodSignature(com.newrelic.agent.tracers.ClassMethodSignature) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) ExitTracer(com.newrelic.agent.bridge.ExitTracer) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) UltraLightTracer(com.newrelic.agent.tracers.UltraLightTracer) DefaultSqlTracer(com.newrelic.agent.tracers.DefaultSqlTracer) Tracer(com.newrelic.agent.tracers.Tracer) OtherRootSqlTracer(com.newrelic.agent.tracers.OtherRootSqlTracer) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer) AgentBridge(com.newrelic.agent.bridge.AgentBridge) Transaction(com.newrelic.agent.Transaction) MetricNameFormat(com.newrelic.agent.tracers.metricname.MetricNameFormat) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer)

Example 9 with ExitTracer

use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.

the class InstrumentationImpl method createTracer.

/**
 * Optimized createTracer call for weaved and XML instrumentation. We do not know if either a TransactionActivity or
 * a Transaction is present on the thread. If present, we do not know if the Transaction has been started.
 */
@Override
public ExitTracer createTracer(Object invocationTarget, int signatureId, String metricName, int flags) {
    try {
        if (ServiceFactory.getServiceManager().isStopped()) {
            return null;
        }
        if (ServiceFactory.getServiceManager().getCircuitBreakerService().isTripped()) {
            return null;
        }
        TransactionActivity txa = TransactionActivity.get();
        if (txa != null) {
            if (txa.getRootTracer() != null && txa.getRootTracer().isAsync() && txa.getTransaction() == null) {
                txa = null;
            }
        }
        if (!Agent.canFastPath()) {
            // legacy async instrumentation is in use
            return oldCreateTracer(txa, invocationTarget, signatureId, metricName, 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 OtherRootTracer(txa, sig, invocationTarget, mnf, flags);
                } else {
                    tracer = new DefaultTracer(txa, sig, invocationTarget, mnf, flags);
                }
                txa.tracerStarted(tracer);
                Tracer initiatingTracer = (Tracer) AgentBridge.activeToken.get().tracedMethod.getAndSet(tracer);
                tx.startFastAsyncWork(txa, initiatingTracer);
                return noticeTracer(signatureId, flags, tracer);
            } else if (TracerFlags.isDispatcher(flags)) {
                // Traditional first-time creation of a new transaction
                com.newrelic.agent.Transaction.getTransaction(true);
                txa = TransactionActivity.get();
            } else if (TracerFlags.isAsync(flags)) {
                // Create a transaction activity without a transaction
                txa = TransactionActivity.create(null, Integer.MAX_VALUE);
            }
            if (txa == null) {
                // or we are running on an Agent thread.
                return noticeTracer(signatureId, flags, null);
            }
            return noticeTracer(signatureId, flags, startTracer(txa, invocationTarget, signatureId, metricName, flags));
        }
        // traditional tracer creation code, we check it before creating any objects.
        if (!TracerFlags.isRoot(flags) && !txa.isStarted()) {
            return noticeTracer(signatureId, flags, null);
        }
        Tracer result = null;
        if (txa.checkTracerStart()) {
            try {
                ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
                // Metric naming. When we come here from an @Trace that doesn't specify a metric name, a
                // very common case, getFormatter() will return one of a couple of reusable instances of
                // MetricNameFormat, so we avoid proliferating small objects. But when we come here from
                // XML instrumentation, getFormatter() is forced to create a new MNF instance every time.
                // This proved to be messy to optimize, so unfortunately has been left as-is. 2015-05.
                MetricNameFormat mnf = MetricNameFormats.getFormatter(invocationTarget, sig, metricName, flags);
                if (TracerFlags.isDispatcher(flags) || (TracerFlags.isAsync(flags) && txa.getTransaction() != null && !txa.isStarted())) {
                    result = new OtherRootTracer(txa, sig, invocationTarget, mnf);
                } else {
                    result = new DefaultTracer(txa, sig, invocationTarget, mnf, flags);
                }
            } finally {
                txa.unlockTracerStart();
            }
            txa.tracerStarted(result);
        }
        return noticeTracer(signatureId, flags, result);
    } catch (Throwable t) {
        logger.log(Level.FINEST, t, "createTracer({0}, {1}, {2}, {3})", invocationTarget, signatureId, metricName, flags);
        return null;
    }
}
Also used : Transaction(com.newrelic.agent.Transaction) NoOpTransaction(com.newrelic.agent.bridge.NoOpTransaction) ClassMethodSignature(com.newrelic.agent.tracers.ClassMethodSignature) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) ExitTracer(com.newrelic.agent.bridge.ExitTracer) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) UltraLightTracer(com.newrelic.agent.tracers.UltraLightTracer) DefaultSqlTracer(com.newrelic.agent.tracers.DefaultSqlTracer) Tracer(com.newrelic.agent.tracers.Tracer) OtherRootSqlTracer(com.newrelic.agent.tracers.OtherRootSqlTracer) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer) AgentBridge(com.newrelic.agent.bridge.AgentBridge) TransactionActivity(com.newrelic.agent.TransactionActivity) MetricNameFormat(com.newrelic.agent.tracers.metricname.MetricNameFormat) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer)

Example 10 with ExitTracer

use of com.newrelic.agent.bridge.ExitTracer in project newrelic-java-agent by newrelic.

the class InstrumentationImpl method createSqlTracer.

// I don't like having this method be a copy/paste of the createTracer method above but I do not
// want to introduce a performance hit for the default tracer path just to support sql tracers.
@Override
public ExitTracer createSqlTracer(Object invocationTarget, int signatureId, String metricName, int flags) {
    try {
        if (ServiceFactory.getServiceManager().isStopped()) {
            return null;
        }
        if (ServiceFactory.getServiceManager().getCircuitBreakerService().isTripped()) {
            return null;
        }
        TransactionActivity txa = TransactionActivity.get();
        if (txa != null) {
            if (txa.getRootTracer() != null && txa.getRootTracer().isAsync() && txa.getTransaction() == null) {
                txa = null;
            }
        }
        if (!Agent.canFastPath()) {
            // legacy async instrumentation is in use
            return oldCreateSqlTracer(txa, invocationTarget, signatureId, metricName, 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.isDispatcher(flags)) {
                // Traditional first-time creation of a new transaction
                com.newrelic.agent.Transaction.getTransaction(true);
                txa = TransactionActivity.get();
            } else if (TracerFlags.isAsync(flags)) {
                // Create a transaction activity without a transaction
                txa = TransactionActivity.create(null, Integer.MAX_VALUE);
            }
            if (txa == null) {
                // or we are running on an Agent thread.
                return null;
            }
            return startSqlTracer(txa, invocationTarget, signatureId, metricName, flags);
        }
        // traditional tracer creation code, we check it before creating any objects.
        if (!TracerFlags.isRoot(flags) && !txa.isStarted()) {
            return null;
        }
        Tracer result = null;
        if (txa.checkTracerStart()) {
            try {
                ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
                // Metric naming. When we come here from an @Trace that doesn't specify a metric name, a
                // very common case, getFormatter() will return one of a couple of reusable instances of
                // MetricNameFormat, so we avoid proliferating small objects. But when we come here from
                // XML instrumentation, getFormatter() is forced to create a new MNF instance every time.
                // This proved to be messy to optimize, so unfortunately has been left as-is. 2015-05.
                MetricNameFormat mnf = MetricNameFormats.getFormatter(invocationTarget, sig, metricName, flags);
                if (TracerFlags.isDispatcher(flags) || (TracerFlags.isAsync(flags) && txa.getTransaction() != null && !txa.isStarted())) {
                    result = new OtherRootSqlTracer(txa, sig, invocationTarget, mnf);
                } else if (overSegmentLimit(txa)) {
                    logger.log(Level.FINEST, "Transaction has exceeded tracer segment limit. Returning ultralight sql tracer.");
                    result = UltraLightTracer.createClampedSegment(txa, sig);
                } else {
                    result = new DefaultSqlTracer(txa, sig, invocationTarget, mnf, flags);
                }
            } finally {
                txa.unlockTracerStart();
            }
            txa.tracerStarted(result);
        }
        return result;
    } catch (Throwable t) {
        logger.log(Level.FINEST, t, "createTracer({0}, {1}, {2}, {3})", invocationTarget, signatureId, metricName, flags);
        return null;
    }
}
Also used : Transaction(com.newrelic.agent.Transaction) NoOpTransaction(com.newrelic.agent.bridge.NoOpTransaction) ClassMethodSignature(com.newrelic.agent.tracers.ClassMethodSignature) ExitTracer(com.newrelic.agent.bridge.ExitTracer) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) UltraLightTracer(com.newrelic.agent.tracers.UltraLightTracer) DefaultSqlTracer(com.newrelic.agent.tracers.DefaultSqlTracer) Tracer(com.newrelic.agent.tracers.Tracer) OtherRootSqlTracer(com.newrelic.agent.tracers.OtherRootSqlTracer) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer) AgentBridge(com.newrelic.agent.bridge.AgentBridge) TransactionActivity(com.newrelic.agent.TransactionActivity) MetricNameFormat(com.newrelic.agent.tracers.metricname.MetricNameFormat) OtherRootSqlTracer(com.newrelic.agent.tracers.OtherRootSqlTracer) DefaultSqlTracer(com.newrelic.agent.tracers.DefaultSqlTracer)

Aggregations

ExitTracer (com.newrelic.agent.bridge.ExitTracer)10 DefaultTracer (com.newrelic.agent.tracers.DefaultTracer)6 OtherRootTracer (com.newrelic.agent.tracers.OtherRootTracer)6 Tracer (com.newrelic.agent.tracers.Tracer)6 NoOpTransaction (com.newrelic.agent.bridge.NoOpTransaction)5 Transaction (com.newrelic.agent.Transaction)4 AgentBridge (com.newrelic.agent.bridge.AgentBridge)4 ClassMethodSignature (com.newrelic.agent.tracers.ClassMethodSignature)4 DefaultSqlTracer (com.newrelic.agent.tracers.DefaultSqlTracer)4 OtherRootSqlTracer (com.newrelic.agent.tracers.OtherRootSqlTracer)4 UltraLightTracer (com.newrelic.agent.tracers.UltraLightTracer)4 MetricNameFormat (com.newrelic.agent.tracers.metricname.MetricNameFormat)4 Test (org.junit.Test)3 TransactionActivity (com.newrelic.agent.TransactionActivity)2 TransactionApiImpl (com.newrelic.agent.TransactionApiImpl)1 NoOpInstrumentation (com.newrelic.agent.bridge.NoOpInstrumentation)1 WebRequestDispatcher (com.newrelic.agent.dispatchers.WebRequestDispatcher)1 InstrumentationImpl (com.newrelic.agent.instrumentation.InstrumentationImpl)1 Trace (com.newrelic.api.agent.Trace)1 Transaction (com.newrelic.api.agent.Transaction)1