Search in sources :

Example 1 with DistributedTracingConfig

use of com.newrelic.agent.config.DistributedTracingConfig 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 DistributedTracingConfig

use of com.newrelic.agent.config.DistributedTracingConfig in project newrelic-java-agent by newrelic.

the class HeadersUtil method createAndSetDistributedTraceHeaders.

/**
 * creates new trace context distributed trace headers (and maybe new relic headers) and adds them to the headers object passed in
 *
 * @param tx           current transaction
 * @param tracedMethod the current traced method, used to grab the span id
 * @param headers      outbound headers where distributed trace headers will be added
 * @return true if the headers were successfully added, false otherwise
 */
public static boolean createAndSetDistributedTraceHeaders(Transaction tx, com.newrelic.api.agent.TracedMethod tracedMethod, OutboundHeaders headers) {
    final String spanId = getSpanId(tx, tracedMethod);
    DistributedTracePayloadImpl payload = tx.createDistributedTracePayload(spanId);
    if (payload == null) {
        return false;
    }
    Agent.LOG.log(Level.FINER, "Sending distributed trace header in transaction {0}", tx);
    DistributedTracingConfig distributedTracingConfig = tx.getAgentConfig().getDistributedTracingConfig();
    boolean includeNewRelicHeader = distributedTracingConfig.isIncludeNewRelicHeader();
    if (includeNewRelicHeader) {
        HeadersUtil.setNewRelicTraceHeader(headers, payload.httpSafe());
    }
    try {
        SpanProxy spanProxy = tx.getSpanProxy();
        HeadersUtil.setTraceParentHeader(headers, W3CTraceParentHeader.create(spanProxy, payload.traceId, payload.guid, payload.sampled.booleanValue()));
        W3CTraceStateHeader traceStateHeader = new W3CTraceStateHeader(spanEventsEnabled(tx), transactionEventsEnabled(tx));
        String traceStateHeaderValue = traceStateHeader.create(spanProxy);
        HeadersUtil.setTraceStateHeader(headers, traceStateHeaderValue);
        tx.getMetricAggregator().incrementCounter(MetricNames.SUPPORTABILITY_TRACE_CONTEXT_CREATE_SUCCESS);
    } catch (Exception e) {
        tx.getMetricAggregator().incrementCounter(MetricNames.SUPPORTABILITY_TRACE_CONTEXT_CREATE_EXCEPTION);
    }
    return true;
}
Also used : DistributedTracingConfig(com.newrelic.agent.config.DistributedTracingConfig) SpanProxy(com.newrelic.agent.tracing.SpanProxy) W3CTraceStateHeader(com.newrelic.agent.tracing.W3CTraceStateHeader) DistributedTracePayloadImpl(com.newrelic.agent.tracing.DistributedTracePayloadImpl)

Example 3 with DistributedTracingConfig

use of com.newrelic.agent.config.DistributedTracingConfig in project newrelic-java-agent by newrelic.

the class ErrorServiceImpl method createTracedError.

private TracedError createTracedError(final String theAppName, TransactionData td, Throwable throwable, int responseStatus, String statusMessage) {
    TracedError error;
    // noticeError(expected = true)?
    boolean responseStatusExpected = errorCollectorConfig.getExpectedStatusCodes().contains(responseStatus);
    boolean throwableExpected = td.getThrowable() == null ? false : td.getThrowable().expected;
    boolean markedExpected = responseStatusExpected || throwableExpected;
    Map<String, Object> joinedIntrinsics = new HashMap<>(td.getIntrinsicAttributes());
    DistributedTraceService distributedTraceService = ServiceFactory.getDistributedTraceService();
    DistributedTracingConfig distributedTracingConfig = ServiceFactory.getConfigService().getDefaultAgentConfig().getDistributedTracingConfig();
    if (distributedTracingConfig.isEnabled()) {
        joinedIntrinsics.putAll(distributedTraceService.getIntrinsics(td.getInboundDistributedTracePayload(), td.getGuid(), td.getTraceId(), td.getTransportType(), td.getTransportDurationInMillis(), td.getLargestTransportDurationInMillis(), td.getParentId(), td.getParentSpanId(), td.getPriority()));
    }
    if (throwable != null) {
        error = ThrowableError.builder(errorCollectorConfig, theAppName, td.getBlameOrRootMetricName(), throwable, td.getWallClockStartTimeMs()).errorMessageReplacer(errorMessageReplacer).requestUri(td.getRequestUri(AgentConfigImpl.ERROR_COLLECTOR)).prefixedAttributes(td.getPrefixedAttributes()).userAttributes(td.getUserAttributes()).agentAttributes(td.getAgentAttributes()).errorAttributes(td.getErrorAttributes()).intrinsicAttributes(joinedIntrinsics).expected(markedExpected).build();
    } else {
        error = HttpTracedError.builder(errorCollectorConfig, theAppName, td.getBlameOrRootMetricName(), td.getWallClockStartTimeMs()).statusCodeAndMessage(responseStatus, statusMessage).transactionData(td).requestUri(td.getRequestUri(AgentConfigImpl.ERROR_COLLECTOR)).prefixedAttributes(td.getPrefixedAttributes()).userAttributes(td.getUserAttributes()).agentAttributes(td.getAgentAttributes()).errorAttributes(td.getErrorAttributes()).intrinsicAttributes(joinedIntrinsics).expected(markedExpected).build();
    }
    return error;
}
Also used : DistributedTraceService(com.newrelic.agent.tracing.DistributedTraceService) DistributedTracingConfig(com.newrelic.agent.config.DistributedTracingConfig) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 4 with DistributedTracingConfig

use of com.newrelic.agent.config.DistributedTracingConfig in project newrelic-java-agent by newrelic.

the class CrossProcessStateTest method processOutboundResponseHeaders.

@Test
public void processOutboundResponseHeaders() {
    String incomingId = "6#66";
    String obfuscatedAppData = Obfuscator.obfuscateNameUsingKey("[\"6#66\",\"TestTransaction\\/name\",0.0,0.0,12345,\"5001D\",false]", encodingKey);
    cps.processOutboundResponseHeaders(null, 0);
    TransactionStats txStats = mock(TransactionStats.class);
    TransactionActivity ta = mock(TransactionActivity.class);
    when(tx.getTransactionActivity()).thenReturn(ta);
    when(ta.getTransactionStats()).thenReturn(txStats);
    SimpleStatsEngine statsEngine = mock(SimpleStatsEngine.class);
    when(txStats.getUnscopedStats()).thenReturn(statsEngine);
    ResponseTimeStats stats = mock(ResponseTimeStats.class);
    when(statsEngine.getOrCreateResponseTimeStats(anyString())).thenReturn(stats);
    InboundHeaderState ihs = mock(InboundHeaderState.class);
    when(ihs.getClientCrossProcessId()).thenReturn(incomingId);
    when(ihs.isTrustedCatRequest()).thenReturn(true);
    when(tx.getInboundHeaderState()).thenReturn(ihs);
    AgentConfig agentConfig = mock(AgentConfig.class);
    DistributedTracingConfig distributedTracingConfig = mock(DistributedTracingConfig.class);
    when(distributedTracingConfig.isEnabled()).thenReturn(false);
    when(agentConfig.getDistributedTracingConfig()).thenReturn(distributedTracingConfig);
    when(tx.getAgentConfig()).thenReturn(agentConfig);
    PriorityTransactionName txName = mock(PriorityTransactionName.class);
    when(tx.getPriorityTransactionName()).thenReturn(txName);
    when(txName.getName()).thenReturn("TestTransaction/name");
    when(tx.getGuid()).thenReturn("5001D");
    when(config.getCrossProcessId()).thenReturn(incomingId);
    cps.processOutboundResponseHeaders(outboundHeaders, 12345);
    verify(outboundHeaders).setHeader(eq("X-NewRelic-App-Data"), eq(obfuscatedAppData));
    cps.processOutboundResponseHeaders(outboundHeaders, 12345);
    verify(outboundHeaders, Mockito.times(2)).getHeaderType();
    verifyNoMoreInteractions(outboundHeaders);
    verify(config, atLeastOnce()).isCrossApplicationTracing();
    verify(config, atLeastOnce()).getCrossProcessId();
    verify(config, atLeastOnce()).getEncodingKey();
    verify(tx, atLeastOnce()).getAgentConfig();
    verify(tx, atLeastOnce()).getCrossProcessConfig();
    verify(tx, atLeastOnce()).getInboundHeaderState();
    verify(tx, atLeastOnce()).isIgnore();
    verify(tx, atLeastOnce()).getLock();
    verify(tx, atLeastOnce()).getGuid();
    verify(tx, atLeastOnce()).freezeTransactionName();
    verify(tx, atLeastOnce()).getRunningDurationInNanos();
    verify(tx, atLeastOnce()).getExternalTime();
    verify(tx, atLeastOnce()).getPriorityTransactionName();
    verify(txName, atLeastOnce()).getName();
    verify(tx, atLeastOnce()).getTransactionActivity();
    verify(ta, atLeastOnce()).getTransactionStats();
    verify(txStats, atLeastOnce()).getUnscopedStats();
    verify(statsEngine, atLeastOnce()).getOrCreateResponseTimeStats(anyString());
    verify(stats, atLeastOnce()).recordResponseTime(anyLong(), any(TimeUnit.class));
    verifyNoMoreInteractions(txStats, statsEngine, stats, txName);
}
Also used : ResponseTimeStats(com.newrelic.agent.stats.ResponseTimeStats) AgentConfig(com.newrelic.agent.config.AgentConfig) DistributedTracingConfig(com.newrelic.agent.config.DistributedTracingConfig) TransactionStats(com.newrelic.agent.stats.TransactionStats) PriorityTransactionName(com.newrelic.agent.transaction.PriorityTransactionName) TimeUnit(java.util.concurrent.TimeUnit) SimpleStatsEngine(com.newrelic.agent.stats.SimpleStatsEngine) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.junit.Test)

Example 5 with DistributedTracingConfig

use of com.newrelic.agent.config.DistributedTracingConfig in project newrelic-java-agent by newrelic.

the class InboundHeaderStateTest method setup.

@Before
public void setup() {
    serviceManager.setConfigService(new MockConfigService(AgentConfigFactory.createAgentConfig(Collections.emptyMap(), Collections.emptyMap(), null)));
    ServiceFactory.setServiceManager(serviceManager);
    OutboundHeaders outboundHeaders = mock(OutboundHeaders.class);
    InboundHeaders inboundHeaders = mock(InboundHeaders.class);
    request = mock(ExtendedRequest.class);
    agentConfig = mock(AgentConfig.class);
    crossProcessConfig = mock(CrossProcessConfig.class);
    distributedTracingConfig = mock(DistributedTracingConfig.class);
    tx = mock(Transaction.class);
    when(inboundHeaders.getHeaderType()).thenReturn(HeaderType.HTTP);
    when(outboundHeaders.getHeaderType()).thenReturn(HeaderType.HTTP);
    when(crossProcessConfig.getEncodingKey()).thenReturn(encodingKey);
    when(crossProcessConfig.isCrossApplicationTracing()).thenReturn(true);
    when(distributedTracingConfig.isEnabled()).thenReturn(false);
    when(agentConfig.getDistributedTracingConfig()).thenReturn(distributedTracingConfig);
    when(tx.isIgnore()).thenReturn(false);
    when(tx.getDispatcher()).thenReturn(mock(Dispatcher.class));
    when(tx.getDispatcher().getRequest()).thenReturn(request);
    when(tx.getDispatcher().getRequest().getHeaderType()).thenReturn(HeaderType.HTTP);
    when(tx.getCrossProcessConfig()).thenReturn(crossProcessConfig);
    when(tx.getAgentConfig()).thenReturn(agentConfig);
    when(tx.getPriorityTransactionName()).thenReturn(PriorityTransactionName.create("Test", "TEST", TransactionNamePriority.NONE));
    when(tx.getApplicationName()).thenReturn("TestApp");
    when(tx.getLock()).thenReturn(new Object());
}
Also used : AgentConfig(com.newrelic.agent.config.AgentConfig) DistributedTracingConfig(com.newrelic.agent.config.DistributedTracingConfig) ExtendedRequest(com.newrelic.api.agent.ExtendedRequest) InboundHeaders(com.newrelic.api.agent.InboundHeaders) CrossProcessConfig(com.newrelic.agent.config.CrossProcessConfig) OutboundHeaders(com.newrelic.api.agent.OutboundHeaders) Dispatcher(com.newrelic.agent.dispatchers.Dispatcher) Before(org.junit.Before)

Aggregations

DistributedTracingConfig (com.newrelic.agent.config.DistributedTracingConfig)10 AgentConfig (com.newrelic.agent.config.AgentConfig)3 DistributedTraceService (com.newrelic.agent.tracing.DistributedTraceService)3 TransactionStats (com.newrelic.agent.stats.TransactionStats)2 DistributedTracePayloadImpl (com.newrelic.agent.tracing.DistributedTracePayloadImpl)2 HashMap (java.util.HashMap)2 Transaction (com.newrelic.agent.Transaction)1 CrossProcessConfig (com.newrelic.agent.config.CrossProcessConfig)1 DatastoreConfig (com.newrelic.agent.config.DatastoreConfig)1 TransactionTracerConfig (com.newrelic.agent.config.TransactionTracerConfig)1 Dispatcher (com.newrelic.agent.dispatchers.Dispatcher)1 ResponseTimeStats (com.newrelic.agent.stats.ResponseTimeStats)1 SimpleStatsEngine (com.newrelic.agent.stats.SimpleStatsEngine)1 SpanProxy (com.newrelic.agent.tracing.SpanProxy)1 W3CTraceStateHeader (com.newrelic.agent.tracing.W3CTraceStateHeader)1 PriorityTransactionName (com.newrelic.agent.transaction.PriorityTransactionName)1 TransactionCounts (com.newrelic.agent.transaction.TransactionCounts)1 TransactionThrowable (com.newrelic.agent.transaction.TransactionThrowable)1 ExtendedRequest (com.newrelic.api.agent.ExtendedRequest)1 InboundHeaders (com.newrelic.api.agent.InboundHeaders)1