public void beforeEnd()

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