in packages/rum-core/src/performance-monitoring/performance-monitoring.js [208:306]
processAPICalls(event, task) {
const configService = this._configService
const transactionService = this._transactionService
// do not process calls to our own endpoints
if (task.data && task.data.url) {
const endpoints = this._apmServer.getEndpoints()
const isOwnEndpoint = Object.keys(endpoints).some(
endpoint => task.data.url.indexOf(endpoints[endpoint]) !== -1
)
if (isOwnEndpoint) {
return
}
}
if (event === SCHEDULE && task.data) {
const data = task.data
const requestUrl = new Url(data.url)
const spanName =
data.method +
' ' +
(requestUrl.relative
? requestUrl.path
: stripQueryStringFromUrl(requestUrl.href))
if (!transactionService.getCurrentTransaction()) {
transactionService.startTransaction(spanName, HTTP_REQUEST_TYPE, {
managed: true
})
}
const span = transactionService.startSpan(spanName, 'external.http', {
blocking: true
})
if (!span) {
return
}
const isDtEnabled = configService.get('distributedTracing')
const dtOrigins = configService.get('distributedTracingOrigins')
const currentUrl = new Url(window.location.href)
const isSameOrigin =
checkSameOrigin(requestUrl.origin, currentUrl.origin) ||
checkSameOrigin(requestUrl.origin, dtOrigins)
const target = data.target
/**
* Propagate distributed tracing information to the backend systems
* https://www.w3.org/TR/trace-context/
*/
if (isDtEnabled && isSameOrigin && target) {
this.injectDtHeader(span, target)
const propagateTracestate = configService.get('propagateTracestate')
if (propagateTracestate) {
this.injectTSHeader(span, target)
}
} else if (__DEV__) {
this._logginService.debug(
`Could not inject distributed tracing header to the request origin ('${requestUrl.origin}') from the current origin ('${currentUrl.origin}')`
)
}
/**
* set sync flag only for synchronous API calls, setting the flag to
* false would result in UI showing `async` label on non-synchronous spans
* which creates unncessary noise for the user
*/
if (data.sync) {
span.sync = data.sync
}
data.span = span
} else if (event === INVOKE) {
const data = task.data
if (data && data.span) {
const { span, response, target } = data
let status
if (response) {
status = response.status
} else {
status = target.status
}
let outcome
if (data.status != 'abort' && !data.aborted) {
if (status >= 400 || status == 0) {
outcome = OUTCOME_FAILURE
} else {
outcome = OUTCOME_SUCCESS
}
} else {
outcome = OUTCOME_UNKNOWN
}
span.outcome = outcome
const tr = transactionService.getCurrentTransaction()
if (tr && tr.type === HTTP_REQUEST_TYPE) {
tr.outcome = outcome
}
transactionService.endSpan(span, data)
}
}
}