com.newrelic.opentracing.events.TransactionEvent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of newrelic-java-lambda Show documentation
Show all versions of newrelic-java-lambda Show documentation
New Relic OpenTracing Tracer implementation for instrumenting AWS Lambda functions.
The newest version!
/*
* Copyright 2020 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.newrelic.opentracing.events;
import com.newrelic.opentracing.LambdaSpan;
import com.newrelic.opentracing.LambdaSpanContext;
import com.newrelic.opentracing.dt.DistributedTracePayloadImpl;
import com.newrelic.opentracing.dt.DistributedTracing;
import com.newrelic.opentracing.state.DistributedTracingState;
import com.newrelic.opentracing.state.TransactionState;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class TransactionEvent extends Event {
private static final int INTRINSIC_DEFAULT_CAPACITY = 32;
private final Map intrinsics = new HashMap<>(INTRINSIC_DEFAULT_CAPACITY);
private final Map userAttributes = new HashMap<>();
private final Map agentAttributes = new HashMap<>();
private static final Set AGENT_ATTRIBUTE_KEYS;
static {
AGENT_ATTRIBUTE_KEYS = new HashSet<>();
AGENT_ATTRIBUTE_KEYS.add("aws.lambda.arn");
AGENT_ATTRIBUTE_KEYS.add("aws.lambda.coldStart");
AGENT_ATTRIBUTE_KEYS.add("aws.lambda.eventSource.arn");
AGENT_ATTRIBUTE_KEYS.add("aws.lambda.eventSource.eventType");
AGENT_ATTRIBUTE_KEYS.add("aws.requestId");
}
public TransactionEvent(LambdaSpan span, TransactionState txnState, DistributedTracingState dtState) {
intrinsics.put("type", "Transaction");
intrinsics.put("timestamp", span.getTimestamp());
intrinsics.put("duration", span.getDurationInSeconds());
if (span.context() != null && span.context() instanceof LambdaSpanContext) {
LambdaSpanContext context = (LambdaSpanContext) span.context();
intrinsics.put("name", txnState.getTransactionName());
final DistributedTracing dt = DistributedTracing.getInstance();
intrinsics.putAll(dt.getDistributedTracingAttributes(dtState, txnState.getTransactionId(), context.getPriority()));
final DistributedTracePayloadImpl inboundPayload = dtState.getInboundPayload();
if (inboundPayload != null && inboundPayload.hasTransactionId()) {
// TransactionEvents parent other TransactionEvents
intrinsics.put("parentId", inboundPayload.getTransactionId());
if (inboundPayload.hasGuid()) {
// Guid of span that started the TransactionEvent
intrinsics.put("parentSpanId", inboundPayload.getGuid());
}
}
if (txnState.hasError()) {
agentAttributes.put("error", true);
}
}
for (Map.Entry tag : span.getTags().entrySet()) {
if (AGENT_ATTRIBUTE_KEYS.contains(tag.getKey())) {
agentAttributes.put(tag.getKey(), tag.getValue());
} else {
userAttributes.put(tag.getKey(), tag.getValue());
}
}
userAttributes.remove("http.status_code");
String status = parseStatusCode(span.getTag("http.status_code"));
if (status != null && !status.isEmpty()) {
agentAttributes.put("response.status", status);
}
}
/**
* New Relic expects status code to be a string, but the OpenTracing semantic convention is an integer,
* so check for either, but return it as a string.
*/
private String parseStatusCode(Object statusCodeObject) {
if (statusCodeObject instanceof String) {
return (String) statusCodeObject;
} else if (statusCodeObject instanceof Number) {
return ((Number) statusCodeObject) + "";
}
return null;
}
@Override
public Map getIntrinsics() {
return intrinsics;
}
@Override
public Map getUserAttributes() {
return userAttributes;
}
@Override
public Map getAgentAttributes() {
return agentAttributes;
}
}