in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/SpanImpl.java [254:300]
public void beforeEnd(long epochMicros) {
for (SpanEndListener<? super SpanImpl> endListener : endListeners) {
endListener.onEnd(this);
}
// set outcome when not explicitly set by user nor instrumentation
if (outcomeNotSet()) {
Outcome outcome;
if (context.getHttp().hasContent()) {
// HTTP client spans
outcome = ResultUtil.getOutcomeByHttpClientStatus(context.getHttp().getStatusCode());
} else {
// span types & sub-types for which we consider getting an exception as a failure
outcome = hasCapturedExceptions() ? Outcome.FAILURE : Outcome.SUCCESS;
}
withOutcome(outcome);
}
// auto-infer context.destination.service.resource as per spec:
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-spans-destination.md#contextdestinationserviceresource
ServiceTargetImpl serviceTarget = getContext().getServiceTarget();
if (isExit() && !serviceTarget.hasContent() && !serviceTarget.isSetByUser()) {
DbImpl db = context.getDb();
MessageImpl message = context.getMessage();
UrlImpl httpUrl = context.getHttp().getInternalUrl();
String targetServiceType = (subtype != null) ? subtype : type;
if (db.hasContent()) {
serviceTarget.withType(targetServiceType).withName(db.getInstance());
} else if (message.hasContent()) {
serviceTarget.withType(targetServiceType).withName(message.getQueueName());
} else if (httpUrl.hasContent()) {
// direct modification of destination resource to ensure compatibility
serviceTarget.withType("http")
.withHostPortName(httpUrl.getHostname(), httpUrl.getPort())
.withNameOnlyDestinationResource();
} else {
serviceTarget.withType(targetServiceType);
}
}
if (transaction != null) {
transaction.incrementTimer(type, subtype, getSelfDuration());
}
if (parent != null) {
parent.onChildEnd(epochMicros);
}
}