Search in sources :

Example 1 with TransactionStats

use of com.newrelic.agent.stats.TransactionStats in project newrelic-java-agent by newrelic.

the class Transaction method finishTransaction.

private void finishTransaction() {
    try {
        synchronized (lock) {
            // this may have the side-effect of ignoring the transaction
            freezeTransactionName();
            if (ignore) {
                Agent.LOG.log(Level.FINER, "Transaction {0} was cancelled: ignored. This is not an error condition.", this);
                ServiceFactory.getTransactionService().transactionCancelled(this);
                return;
            }
            if (finishedChildren.isEmpty()) {
                Agent.LOG.log(Level.FINER, "Transaction {0} was cancelled: no activities. This is not an error condition.", this);
                ServiceFactory.getTransactionService().transactionCancelled(this);
                return;
            }
            // this needs to go before dispatcher.transactionFinished so that all of
            // the time metrics are correct
            TransactionStats transactionStats = transactionFinishedActivityMerging();
            transactionTime.markTransactionAsDone();
            recordFinalGCTime(transactionStats);
            handleTokenTimeout(transactionStats);
            String txName = priorityTransactionName.getName();
            // parse headers in dispatcher request before we get rid of request/response objects
            getInboundHeaderState();
            // this may trigger this dispatcher to record extra metrics like apdex & HttpDispatcher
            dispatcher.transactionFinished(txName, transactionStats);
            if (Agent.LOG.isFinerEnabled()) {
                String requestURI = dispatcher == null ? "No Dispatcher Defined" : dispatcher.getUri();
                Agent.LOG.log(Level.FINER, "Transaction {0} for request: {1} finished {2}ms {3}", txName, requestURI, transactionTime.getResponseTimeInMilliseconds(), this);
            }
            if (!ServiceFactory.getServiceManager().isStarted()) {
                Agent.LOG.log(Level.INFO, "Transaction {0} tried to finish but ServiceManager not started", this);
                return;
            }
            // Some parts of the code below are only required if this transaction's TT is selected
            // for sending upstream. Unfortunately we don't know at this point in the harvest whether
            // this transaction's trace will be selected, and there's no obvious way to know that can
            // be built with maintainable code. There was a previous effort at this, but the obvious
            // happened: it sat broken in the code (i.e. it did some checks, but always returned true)
            // for 18 months before we noticed and ripped it out. Please don't repeat this mistake.
            TransactionTracerConfig ttConfig = getTransactionTracerConfig();
            TransactionCounts rootCounts = getTransactionCounts();
            if (rootCounts.isOverTracerSegmentLimit()) {
                getIntrinsicAttributes().put(AttributeNames.SEGMENT_CLAMP, rootCounts.getSegmentCount());
                // Record supportability metric to track when a segment clamp occurs
                transactionStats.getUnscopedStats().getStats(MetricNames.SUPPORTABILITY_TRANSACTION_SEGMENT_CLAMP).recordDataPoint(rootCounts.getSegmentCount());
            }
            if (rootCounts.isOverTransactionSize()) {
                getIntrinsicAttributes().put(AttributeNames.SIZE_LIMIT_PARAMETER_NAME, "The transaction size limit was reached");
            }
            int count = rootCounts.getStackTraceCount();
            if (count >= ttConfig.getMaxStackTraces()) {
                getIntrinsicAttributes().put(AttributeNames.STACK_TRACE_CLAMP, count);
            }
            if (rootCounts.isOverTokenLimit()) {
                getIntrinsicAttributes().put(AttributeNames.TOKEN_CLAMP, rootCounts.getTokenCount());
            }
            count = rootCounts.getExplainPlanCount();
            if (count >= ttConfig.getMaxExplainPlans()) {
                getIntrinsicAttributes().put(AttributeNames.EXPLAIN_PLAN_CLAMP, count);
            }
            DistributedTracingConfig distributedTracingConfig = getAgentConfig().getDistributedTracingConfig();
            if (!distributedTracingConfig.isEnabled()) {
                if (getInboundHeaderState().isTrustedCatRequest()) {
                    String id = getInboundHeaderState().getClientCrossProcessId();
                    getIntrinsicAttributes().put(AttributeNames.CLIENT_CROSS_PROCESS_ID_PARAMETER_NAME, id);
                }
                String referrerGuid = getInboundHeaderState().getReferrerGuid();
                if (referrerGuid != null) {
                    getIntrinsicAttributes().put(AttributeNames.REFERRING_TRANSACTION_TRACE_ID_PARAMETER_NAME, referrerGuid);
                }
                String tripId = getCrossProcessTransactionState().getTripId();
                if (tripId != null) {
                    getIntrinsicAttributes().put(AttributeNames.TRIP_ID_PARAMETER_NAME, tripId);
                    int pathHash = getCrossProcessTransactionState().generatePathHash();
                    getIntrinsicAttributes().put(AttributeNames.PATH_HASH_PARAMETER_NAME, ServiceUtils.intToHexString(pathHash));
                }
            }
            if (isSynthetic()) {
                Agent.LOG.log(Level.FINEST, "Completing Synthetics transaction for monitor {0}", getInboundHeaderState().getSyntheticsMonitorId());
                getIntrinsicAttributes().put(AttributeNames.SYNTHETICS_RESOURCE_ID, this.getInboundHeaderState().getSyntheticsResourceId());
                getIntrinsicAttributes().put(AttributeNames.SYNTHETICS_MONITOR_ID, this.getInboundHeaderState().getSyntheticsMonitorId());
                getIntrinsicAttributes().put(AttributeNames.SYNTHETICS_JOB_ID, this.getInboundHeaderState().getSyntheticsJobId());
            }
            if (timeoutCause != null && timeoutCause.cause != null) {
                getIntrinsicAttributes().put(AttributeNames.TIMEOUT_CAUSE, timeoutCause.cause);
            }
            String displayHost = getAgentConfig().getValue("process_host.display_name", null);
            if (displayHost != null) {
                getAgentAttributes().put(AttributeNames.DISPLAY_HOST, displayHost);
            }
            String instanceName = ServiceFactory.getEnvironmentService().getEnvironment().getAgentIdentity().getInstanceName();
            if (instanceName != null) {
                getAgentAttributes().put(AttributeNames.INSTANCE_NAME, instanceName);
            }
            // Only add jvm.thread_name if transaction  was not timed out and
            // if it's *NOT* a multi-threaded transaction
            TimedSet<TokenImpl> tokenCache = activeTokensCache.get();
            if ((tokenCache == null || tokenCache.timedOutCount() == 0) && finishedChildren.size() == 1) {
                if (!ServiceFactory.getThreadService().isAgentThreadId(Thread.currentThread().getId())) {
                    getAgentAttributes().put(AttributeNames.THREAD_NAME, Thread.currentThread().getName());
                }
            }
            getIntrinsicAttributes().put(AttributeNames.PRIORITY, getPriority());
            TransactionData transactionData = new TransactionData(this, rootCounts.getTransactionSize());
            ServiceFactory.getTransactionService().transactionFinished(transactionData, transactionStats);
        }
    } catch (Throwable th) {
        Agent.LOG.log(Level.WARNING, th, "Transaction {0} was not reported because of an internal error.", this);
        ServiceFactory.getTransactionService().transactionCancelled(this);
    }
}
Also used : DistributedTracingConfig(com.newrelic.agent.config.DistributedTracingConfig) TransactionStats(com.newrelic.agent.stats.TransactionStats) TransactionThrowable(com.newrelic.agent.transaction.TransactionThrowable) TransactionCounts(com.newrelic.agent.transaction.TransactionCounts) TransactionTracerConfig(com.newrelic.agent.config.TransactionTracerConfig)

Example 2 with TransactionStats

use of com.newrelic.agent.stats.TransactionStats in project newrelic-java-agent by newrelic.

the class Transaction method activityFinished.

public void activityFinished(TransactionActivity activity, Tracer tracer, int opcode) {
    Agent.LOG.log(Level.FINER, "Transaction {0}: Activity {1} finished with opcode {2}", this, activity, opcode);
    synchronized (lock) {
        try {
            if (!isFinished()) {
                // we are assuming if you call this, you are part of the transaction
                if (!tracer.isTransactionSegment()) {
                    /*
                         * If the root tracer is not a transaction segment then there should not be any tracers in the
                         * txa. It also means we do not need to store the txa for the transaction trace. We just need to
                         * port over metrics. The consequence of this is that you will no longer be able to ignore this
                         * txa once it is finished.
                         */
                    if (txStats == null) {
                        txStats = activity.getTransactionStats();
                    } else {
                        TransactionStats toMergeStats = activity.getTransactionStats();
                        txStats.getScopedStats().mergeStats(toMergeStats.getScopedStats());
                        txStats.getUnscopedStats().mergeStats(toMergeStats.getUnscopedStats());
                    }
                } else {
                    finishedChildren.add(activity);
                }
                checkFinishTransaction(activity);
            }
        } finally {
            if (!activity.isNotInThreadLocal()) {
                transactionHolder.remove();
            }
        }
    }
}
Also used : TransactionStats(com.newrelic.agent.stats.TransactionStats)

Example 3 with TransactionStats

use of com.newrelic.agent.stats.TransactionStats in project newrelic-java-agent by newrelic.

the class TransactionServiceTest method testDispatcherTransactionFinished.

@Test
public void testDispatcherTransactionFinished() {
    final AtomicReference<Transaction> finishedTransaction = new AtomicReference<>(null);
    final AtomicReference<Transaction> finishedTransactionExtended = new AtomicReference<>(null);
    ServiceFactory.getTransactionService().addTransactionListener(new ExtendedTransactionListener() {

        @Override
        public void dispatcherTransactionStarted(Transaction transaction) {
        }

        @Override
        public void dispatcherTransactionCancelled(Transaction transaction) {
        }

        @Override
        public void dispatcherTransactionFinished(TransactionData transactionData, TransactionStats transactionStats) {
            finishedTransactionExtended.set(transactionData.getTransaction());
        }
    });
    ServiceFactory.getTransactionService().addTransactionListener(new TransactionListener() {

        @Override
        public void dispatcherTransactionFinished(TransactionData transactionData, TransactionStats transactionStats) {
            finishedTransaction.set(transactionData.getTransaction());
        }
    });
    Tracer tracer = makeTransaction();
    tracer.finish(0, null);
    tracer.getParentTracer().finish(0, null);
    assertNotNull(tracer);
    assertNotNull(finishedTransaction.get());
    assertNotNull(finishedTransactionExtended.get());
    assertEquals(tracer.getTransactionActivity().getTransaction(), finishedTransaction.get());
    assertEquals(tracer.getTransactionActivity().getTransaction(), finishedTransactionExtended.get());
}
Also used : TransactionStats(com.newrelic.agent.stats.TransactionStats) DefaultTracer(com.newrelic.agent.tracers.DefaultTracer) Tracer(com.newrelic.agent.tracers.Tracer) OtherRootTracer(com.newrelic.agent.tracers.OtherRootTracer) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.Test)

Example 4 with TransactionStats

use of com.newrelic.agent.stats.TransactionStats in project newrelic-java-agent by newrelic.

the class TransactionDataList method clone.

private TransactionStats clone(TransactionStats transactionStats) throws CloneNotSupportedException {
    TransactionStats stats = new TransactionStats();
    clone(transactionStats.getScopedStats(), stats.getScopedStats());
    clone(transactionStats.getUnscopedStats(), stats.getUnscopedStats());
    return stats;
}
Also used : TransactionStats(com.newrelic.agent.stats.TransactionStats)

Example 5 with TransactionStats

use of com.newrelic.agent.stats.TransactionStats in project newrelic-java-agent by newrelic.

the class DefaultSqlTracerTest method testSpanEventDatastoreTruncationAtExactLimit.

@Test
public void testSpanEventDatastoreTruncationAtExactLimit() throws SQLException {
    final Connection connection = mock(Connection.class);
    DatastoreInstanceDetection.detectConnectionAddress();
    DatastoreInstanceDetection.associateAddress(connection, new InetSocketAddress("dbserver.nerd.us", 9945));
    DatastoreInstanceDetection.stopDetectingConnectionAddress();
    String longQueryString = "SELECT price, name FROM BOOKS WHERE name = " + Strings.repeat("a", 1957);
    DefaultSqlTracer tracer = newInstanceDBTracer(longQueryString, connection, "MySQL", "mysql");
    tracer.finish(Opcodes.ARETURN, new DummyResultSet());
    SpanEventsService spanEventService = ServiceFactory.getSpanEventService();
    ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats());
    SamplingPriorityQueue<SpanEvent> eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME);
    List<SpanEvent> spanEvents = eventPool.asList();
    assertNotNull(spanEvents);
    assertEquals(1, spanEvents.size());
    SpanEvent spanEvent = Iterables.getFirst(spanEvents, null);
    assertNotNull(spanEvent);
    assertEquals("datastore", spanEvent.getIntrinsics().get("category"));
    assertEquals("MySQL", spanEvent.getIntrinsics().get("component"));
    assertEquals("dbserver.nerd.us", spanEvent.getIntrinsics().get("peer.hostname"));
    assertEquals("dbserver.nerd.us:9945", spanEvent.getIntrinsics().get("peer.address"));
    assertEquals(2000, spanEvent.getIntrinsics().get("db.statement").toString().length());
    // Should not end with ... since it's exactly at the limit
    assertTrue(spanEvent.getIntrinsics().get("db.statement").toString().endsWith("aaa"));
    assertEquals("books", spanEvent.getIntrinsics().get("db.collection"));
    assertEquals("client", spanEvent.getIntrinsics().get("span.kind"));
    assertEquals("Datastore/statement/MySQL/books/select", spanEvent.getName());
    assertNotNull(spanEvent.getTraceId());
    assertNotNull(spanEvent.getGuid());
}
Also used : TransactionStats(com.newrelic.agent.stats.TransactionStats) SpanEventsServiceImpl(com.newrelic.agent.service.analytics.SpanEventsServiceImpl) InetSocketAddress(java.net.InetSocketAddress) SpanEventsService(com.newrelic.agent.service.analytics.SpanEventsService) Connection(java.sql.Connection) DummyConnection(sql.DummyConnection) SpanEvent(com.newrelic.agent.model.SpanEvent) DummyResultSet(sql.DummyResultSet) Test(org.junit.Test)

Aggregations

TransactionStats (com.newrelic.agent.stats.TransactionStats)104 Test (org.junit.Test)90 TransactionData (com.newrelic.agent.TransactionData)40 EventTestHelper.generateTransactionData (com.newrelic.agent.service.analytics.EventTestHelper.generateTransactionData)15 Tracer (com.newrelic.agent.tracers.Tracer)15 HashMap (java.util.HashMap)14 SpanEvent (com.newrelic.agent.model.SpanEvent)13 TransactionService (com.newrelic.agent.TransactionService)12 WebRequestDispatcher (com.newrelic.agent.dispatchers.WebRequestDispatcher)11 SpanEventsService (com.newrelic.agent.service.analytics.SpanEventsService)11 SpanEventsServiceImpl (com.newrelic.agent.service.analytics.SpanEventsServiceImpl)11 ArrayList (java.util.ArrayList)11 DefaultTracer (com.newrelic.agent.tracers.DefaultTracer)10 Map (java.util.Map)9 Transaction (com.newrelic.agent.Transaction)8 OtherRootTracer (com.newrelic.agent.tracers.OtherRootTracer)8 ResponseTimeStats (com.newrelic.agent.stats.ResponseTimeStats)7 TransactionEvent (com.newrelic.agent.service.analytics.TransactionEvent)6 CountDownLatch (java.util.concurrent.CountDownLatch)5 JSONArray (org.json.simple.JSONArray)5