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);
}
}
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;
}
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;
}
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);
}
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());
}
Aggregations