@elastic/apm-rum-core
Advanced tools
Comparing version 4.7.0 to 4.8.0
@@ -6,2 +6,27 @@ # Change Log | ||
# [4.8.0](https://github.com/elastic/apm-agent-rum-js/compare/@elastic/apm-rum-core@4.7.0...@elastic/apm-rum-core@4.8.0) (2020-01-15) | ||
### Bug Fixes | ||
* add transaction type redefine order ([#535](https://github.com/elastic/apm-agent-rum-js/issues/535)) ([9e0b311](https://github.com/elastic/apm-agent-rum-js/commit/9e0b311b20f2db0f00702eb5a8389c67dd4628fe)) | ||
* **rum-core:** create temporary transaction on startSpan ([#533](https://github.com/elastic/apm-agent-rum-js/issues/533)) ([8c951d2](https://github.com/elastic/apm-agent-rum-js/commit/8c951d2fb52c1fe61aa90be2cd3ecca3fe6cff1b)) | ||
### Features | ||
* **rum-core:** enrich span context with desination metadata ([#515](https://github.com/elastic/apm-agent-rum-js/issues/515)) ([38276b5](https://github.com/elastic/apm-agent-rum-js/commit/38276b5130c12d0de5d4d3e60c14cd645c10550e)) | ||
* **rum-core:** send transactions with no spans ([#540](https://github.com/elastic/apm-agent-rum-js/issues/540)) ([dd90bf4](https://github.com/elastic/apm-agent-rum-js/commit/dd90bf4e9b63424edf3c53730f94c01bd05e4e34)) | ||
* capture http-request transactions ([#517](https://github.com/elastic/apm-agent-rum-js/issues/517)) ([27ed994](https://github.com/elastic/apm-agent-rum-js/commit/27ed994ea9866e4493015eb3817ab12266f572a5)) | ||
### Performance Improvements | ||
* **rum-core:** ignored XHR's are exempted from task creation process ([#498](https://github.com/elastic/apm-agent-rum-js/issues/498)) ([eb2a376](https://github.com/elastic/apm-agent-rum-js/commit/eb2a376f08364686955453edb27d0f0388ad6d49)) | ||
* **rum-core:** move unexposed configs inside constants to reduce bundlesize ([#521](https://github.com/elastic/apm-agent-rum-js/issues/521)) ([2472e1f](https://github.com/elastic/apm-agent-rum-js/commit/2472e1fd3052faa24ca03dfaa0a3ac961ff32da1)) | ||
# [4.7.0](https://github.com/elastic/apm-agent-rum-js/compare/@elastic/apm-rum-core@4.6.1...@elastic/apm-rum-core@4.7.0) (2019-11-19) | ||
@@ -8,0 +33,0 @@ |
@@ -7,2 +7,3 @@ import { Promise } from 'es6-promise'; | ||
import { truncateModel, METADATA_MODEL } from './truncate'; | ||
import { SERVER_URL_PREFIX } from './constants'; | ||
import { __DEV__ } from '../env'; | ||
@@ -375,5 +376,3 @@ | ||
var ndjsonPayload = ndjson.join(''); | ||
var endPoint = this._configService.getEndpointUrl(); | ||
var endPoint = this._configService.get('serverUrl') + SERVER_URL_PREFIX; | ||
return this._postJson(endPoint, ndjsonPayload); | ||
@@ -380,0 +379,0 @@ }; |
@@ -1,2 +0,2 @@ | ||
import { getCurrentScript, setLabel, merge, extend, getDtHeaderValue } from './utils'; | ||
import { getCurrentScript, setLabel, merge, extend } from './utils'; | ||
import EventHandler from './event-handler'; | ||
@@ -43,3 +43,2 @@ import { CONFIG_CHANGE, LOCAL_CONFIG_KEY } from './constants'; | ||
serverUrl: 'http://localhost:8200', | ||
serverUrlPrefix: '/intake/v2/rum/events', | ||
active: true, | ||
@@ -51,4 +50,2 @@ instrument: true, | ||
breakdownMetrics: false, | ||
browserResponsivenessInterval: 500, | ||
browserResponsivenessBuffer: 3, | ||
checkBrowserResponsiveness: true, | ||
@@ -67,3 +64,2 @@ groupSimilarSpans: true, | ||
distributedTracingOrigins: [], | ||
distributedTracingHeaderValueCallback: getDtHeaderValue, | ||
distributedTracingHeaderName: 'elastic-apm-traceparent', | ||
@@ -124,6 +120,2 @@ pageLoadTraceId: '', | ||
_proto.getEndpointUrl = function getEndpointUrl() { | ||
return this.config.serverUrl + this.config.serverUrlPrefix; | ||
}; | ||
_proto.setUserContext = function setUserContext(userContext) { | ||
@@ -130,0 +122,0 @@ if (userContext === void 0) { |
@@ -11,6 +11,8 @@ var SCHEDULE = 'schedule'; | ||
var ROUTE_CHANGE = 'route-change'; | ||
var TYPE_CUSTOM = 'custom'; | ||
var HTTP_REQUEST_TYPE = 'http-request'; | ||
var TEMPORARY_TYPE = 'temporary'; | ||
var NAME_UNKNOWN = 'Unknown'; | ||
var TYPE_CUSTOM = 'custom'; | ||
var TRANSACTION_TYPE_ORDER = [PAGE_LOAD, ROUTE_CHANGE, HTTP_REQUEST_TYPE, TYPE_CUSTOM, TEMPORARY_TYPE]; | ||
var USER_TIMING_THRESHOLD = 60; | ||
var KEYWORD_LIMIT = 1024; | ||
var TRANSACTION_START = 'transaction:start'; | ||
@@ -26,2 +28,7 @@ var TRANSACTION_END = 'transaction:end'; | ||
var LOCAL_CONFIG_KEY = 'elastic_apm_config'; | ||
export { SCHEDULE, INVOKE, CLEAR, ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR, RESOURCE_INITIATOR_TYPES, REUSABILITY_THRESHOLD, MAX_SPAN_DURATION, PAGE_LOAD, ROUTE_CHANGE, NAME_UNKNOWN, TYPE_CUSTOM, USER_TIMING_THRESHOLD, KEYWORD_LIMIT, TRANSACTION_START, TRANSACTION_END, CONFIG_CHANGE, XMLHTTPREQUEST, FETCH, HISTORY, ERROR, BEFORE_EVENT, AFTER_EVENT, LOCAL_CONFIG_KEY }; | ||
var KEYWORD_LIMIT = 1024; | ||
var SERVER_URL_PREFIX = '/intake/v2/rum/events'; | ||
var BROWSER_RESPONSIVENESS_INTERVAL = 500; | ||
var BROWSER_RESPONSIVENESS_BUFFER = 3; | ||
var SIMILAR_SPAN_TO_TRANSACTION_RATIO = 0.05; | ||
export { SCHEDULE, INVOKE, CLEAR, ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR, RESOURCE_INITIATOR_TYPES, REUSABILITY_THRESHOLD, MAX_SPAN_DURATION, PAGE_LOAD, ROUTE_CHANGE, NAME_UNKNOWN, TYPE_CUSTOM, USER_TIMING_THRESHOLD, TRANSACTION_START, TRANSACTION_END, CONFIG_CHANGE, XMLHTTPREQUEST, FETCH, HISTORY, ERROR, BEFORE_EVENT, AFTER_EVENT, LOCAL_CONFIG_KEY, HTTP_REQUEST_TYPE, KEYWORD_LIMIT, SERVER_URL_PREFIX, BROWSER_RESPONSIVENESS_INTERVAL, BROWSER_RESPONSIVENESS_BUFFER, SIMILAR_SPAN_TO_TRANSACTION_RATIO, TEMPORARY_TYPE, TRANSACTION_TYPE_ORDER }; |
import { Promise } from 'es6-promise'; | ||
import { globalState } from './patch-utils'; | ||
import { SCHEDULE, INVOKE, FETCH } from '../constants'; | ||
import { scheduleMicroTask } from '../utils'; | ||
export function patchFetch(callback) { | ||
@@ -45,3 +46,2 @@ if (!window.fetch || !window.Request) { | ||
url: url, | ||
args: args, | ||
aborted: false | ||
@@ -67,3 +67,3 @@ } | ||
resolve(response); | ||
Promise.resolve().then(function () { | ||
scheduleMicroTask(function () { | ||
task.data.response = response; | ||
@@ -74,3 +74,3 @@ invokeTask(task); | ||
reject(error); | ||
Promise.resolve().then(function () { | ||
scheduleMicroTask(function () { | ||
task.data.error = error; | ||
@@ -77,0 +77,0 @@ invokeTask(task); |
@@ -27,6 +27,3 @@ import { apmSymbol, patchMethod, XHR_SYNC, XHR_URL, XHR_METHOD, XHR_IGNORE } from './patch-utils'; | ||
task.state = INVOKE; | ||
if (!task.ignore) { | ||
callback(INVOKE, task); | ||
} | ||
callback(INVOKE, task); | ||
} | ||
@@ -37,11 +34,7 @@ | ||
task.state = SCHEDULE; | ||
callback(SCHEDULE, task); | ||
var _task$data = task.data, | ||
aborted = _task$data.aborted, | ||
target = _task$data.target; | ||
if (!task.ignore) { | ||
callback(SCHEDULE, task); | ||
} | ||
var data = task.data; | ||
var target = data.target; | ||
var listener = target[XHR_LISTENER]; | ||
if (!oriAddListener) { | ||
@@ -52,2 +45,4 @@ oriAddListener = target[ADD_EVENT_LISTENER_STR]; | ||
var listener = target[XHR_LISTENER]; | ||
if (listener) { | ||
@@ -73,3 +68,3 @@ oriRemoveListener.call(target, READY_STATE_CHANGE, listener); | ||
if (target.readyState === target.DONE) { | ||
if (!data.aborted && XMLHttpRequest[XHR_SCHEDULED] && task.state === SCHEDULE) { | ||
if (!aborted && XMLHttpRequest[XHR_SCHEDULED] && task.state === SCHEDULE) { | ||
earlierEvent = type; | ||
@@ -88,6 +83,2 @@ } | ||
} | ||
var result = sendNative.apply(target, data.args); | ||
XMLHttpRequest[XHR_SCHEDULED] = true; | ||
return result; | ||
} | ||
@@ -104,5 +95,8 @@ | ||
return function (self, args) { | ||
self[XHR_METHOD] = args[0]; | ||
self[XHR_URL] = args[1]; | ||
self[XHR_SYNC] = args[2] === false; | ||
if (!self[XHR_IGNORE]) { | ||
self[XHR_METHOD] = args[0]; | ||
self[XHR_URL] = args[1]; | ||
self[XHR_SYNC] = args[2] === false; | ||
} | ||
return openNative.apply(self, args); | ||
@@ -113,2 +107,6 @@ }; | ||
return function (self, args) { | ||
if (self[XHR_IGNORE]) { | ||
return sendNative.apply(self, args); | ||
} | ||
var task = { | ||
@@ -118,3 +116,2 @@ source: XMLHTTPREQUEST, | ||
type: 'macroTask', | ||
ignore: self[XHR_IGNORE], | ||
data: { | ||
@@ -125,7 +122,8 @@ target: self, | ||
url: self[XHR_URL], | ||
args: args, | ||
aborted: false | ||
} | ||
}; | ||
var result = scheduleTask(task); | ||
scheduleTask(task); | ||
var result = sendNative.apply(self, args); | ||
XMLHttpRequest[XHR_SCHEDULED] = true; | ||
@@ -141,10 +139,12 @@ if (self[XHR_SYNC]) { | ||
return function (self, args) { | ||
var task = self[XHR_TASK]; | ||
if (!self[XHR_IGNORE]) { | ||
var task = self[XHR_TASK]; | ||
if (task && typeof task.type === 'string') { | ||
if (task.data && task.data.aborted) { | ||
return; | ||
if (task && typeof task.type === 'string') { | ||
if (task.data && task.data.aborted) { | ||
return; | ||
} | ||
clearTask(task); | ||
} | ||
clearTask(task); | ||
} | ||
@@ -151,0 +151,0 @@ |
@@ -18,2 +18,8 @@ import { KEYWORD_LIMIT } from './constants'; | ||
}; | ||
var DESTINATION_MODEL = { | ||
address: [KEYWORD_LIMIT], | ||
service: { | ||
'*': [KEYWORD_LIMIT, true] | ||
} | ||
}; | ||
var CONTEXT_MODEL = { | ||
@@ -31,2 +37,3 @@ user: { | ||
}, | ||
destination: DESTINATION_MODEL, | ||
response: RESPONSE_MODEL | ||
@@ -146,2 +153,2 @@ }; | ||
export { truncate, truncateModel, SPAN_MODEL, TRANSACTION_MODEL, ERROR_MODEL, METADATA_MODEL }; | ||
export { truncate, truncateModel, SPAN_MODEL, TRANSACTION_MODEL, ERROR_MODEL, METADATA_MODEL, RESPONSE_MODEL }; |
@@ -0,1 +1,13 @@ | ||
function isDefaultPort(port, protocol) { | ||
switch (protocol) { | ||
case 'http:': | ||
return port === '80'; | ||
case 'https:': | ||
return port === '443'; | ||
} | ||
return true; | ||
} | ||
var RULES = [['#', 'hash'], ['?', 'query'], ['/', 'path'], ['@', 'auth', 1], [NaN, 'host', undefined, 1]]; | ||
@@ -58,2 +70,19 @@ var PROTOCOL_REGEX = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; | ||
this.protocol = protocol || location.protocol; | ||
this.hostname = this.host; | ||
this.port = ''; | ||
if (/:\d+$/.test(this.host)) { | ||
var value = this.host.split(':'); | ||
var port = value.pop(); | ||
var hostname = value.join(':'); | ||
if (isDefaultPort(port, this.protocol)) { | ||
this.host = hostname; | ||
} else { | ||
this.port = port; | ||
} | ||
this.hostname = hostname; | ||
} | ||
this.origin = this.protocol && this.host && this.protocol !== 'file:' ? this.protocol + '//' + this.host : 'null'; | ||
@@ -60,0 +89,0 @@ this.href = this.toString(); |
import Span from './span'; | ||
import { RESOURCE_INITIATOR_TYPES, MAX_SPAN_DURATION, USER_TIMING_THRESHOLD, PAGE_LOAD } from '../common/constants'; | ||
import { stripQueryStringFromUrl, getServerTimingInfo, getPageLoadMarks } from '../common/utils'; | ||
import { stripQueryStringFromUrl, getPageLoadMarks } from '../common/utils'; | ||
var eventPairs = [['domainLookupStart', 'domainLookupEnd', 'Domain lookup'], ['connectStart', 'connectEnd', 'Making a connection to the server'], ['requestStart', 'responseEnd', 'Requesting and receiving the document'], ['domLoading', 'domInteractive', 'Parsing the document, executing sync. scripts'], ['domContentLoadedEventStart', 'domContentLoadedEventEnd', 'Fire "DOMContentLoaded" event'], ['loadEventStart', 'loadEventEnd', 'Fire "load" event']]; | ||
@@ -14,23 +14,2 @@ | ||
function getResponseContext(perfTimingEntry) { | ||
var transferSize = perfTimingEntry.transferSize, | ||
encodedBodySize = perfTimingEntry.encodedBodySize, | ||
decodedBodySize = perfTimingEntry.decodedBodySize, | ||
serverTiming = perfTimingEntry.serverTiming; | ||
var respContext = { | ||
transfer_size: transferSize, | ||
encoded_body_size: encodedBodySize, | ||
decoded_body_size: decodedBodySize | ||
}; | ||
var serverTimingStr = getServerTimingInfo(serverTiming); | ||
if (serverTimingStr) { | ||
respContext.headers = { | ||
'server-timing': serverTimingStr | ||
}; | ||
} | ||
return respContext; | ||
} | ||
function createNavigationTimingSpans(timings, baseTime, trStart, trEnd) { | ||
@@ -54,4 +33,3 @@ var spans = []; | ||
span._start = start - baseTime; | ||
span.ended = true; | ||
span._end = end - baseTime; | ||
span.end(end - baseTime); | ||
spans.push(span); | ||
@@ -76,11 +54,7 @@ } | ||
var span = new Span(spanName, kind); | ||
span.addContext({ | ||
http: { | ||
url: name, | ||
response: getResponseContext(resourceTimingEntry) | ||
} | ||
span._start = startTime; | ||
span.end(responseEnd, { | ||
url: name, | ||
entry: resourceTimingEntry | ||
}); | ||
span._start = startTime; | ||
span.end(); | ||
span._end = responseEnd; | ||
return span; | ||
@@ -151,4 +125,3 @@ } | ||
span._start = startTime; | ||
span.end(); | ||
span._end = end; | ||
span.end(end); | ||
userTimingSpans.push(span); | ||
@@ -220,13 +193,2 @@ } | ||
}); | ||
if (transaction.type === PAGE_LOAD) { | ||
var navigationEntry = perf.getEntriesByType('navigation'); | ||
if (navigationEntry && navigationEntry.length > 0) { | ||
navigationEntry = navigationEntry[0]; | ||
transaction.addContext({ | ||
response: getResponseContext(navigationEntry) | ||
}); | ||
} | ||
} | ||
} | ||
@@ -233,0 +195,0 @@ } |
@@ -1,6 +0,6 @@ | ||
import { checkSameOrigin, isDtHeaderValid, merge, parseDtHeaderValue, stripQueryStringFromUrl } from '../common/utils'; | ||
import { checkSameOrigin, isDtHeaderValid, parseDtHeaderValue, stripQueryStringFromUrl, getDtHeaderValue } from '../common/utils'; | ||
import Url from '../common/url'; | ||
import { patchEventHandler } from '../common/patching'; | ||
import { globalState } from '../common/patching/patch-utils'; | ||
import { SCHEDULE, INVOKE, TRANSACTION_END, AFTER_EVENT, FETCH, HISTORY, XMLHTTPREQUEST } from '../common/constants'; | ||
import { SCHEDULE, INVOKE, TRANSACTION_END, AFTER_EVENT, FETCH, HISTORY, XMLHTTPREQUEST, HTTP_REQUEST_TYPE, BROWSER_RESPONSIVENESS_INTERVAL, BROWSER_RESPONSIVENESS_BUFFER, SIMILAR_SPAN_TO_TRANSACTION_RATIO } from '../common/constants'; | ||
import { truncateModel, SPAN_MODEL, TRANSACTION_MODEL } from '../common/truncate'; | ||
@@ -84,4 +84,12 @@ import { __DEV__ } from '../env'; | ||
if (event === SCHEDULE && task.data) { | ||
var requestUrl = new Url(task.data.url); | ||
var spanName = task.data.method + ' ' + (requestUrl.relative ? requestUrl.path : stripQueryStringFromUrl(requestUrl.href)); | ||
var data = task.data; | ||
var requestUrl = new Url(data.url); | ||
var spanName = data.method + ' ' + (requestUrl.relative ? requestUrl.path : stripQueryStringFromUrl(requestUrl.href)); | ||
if (!transactionService.getCurrentTransaction()) { | ||
transactionService.startTransaction(spanName, HTTP_REQUEST_TYPE, { | ||
managed: true | ||
}); | ||
} | ||
var span = transactionService.startSpan(spanName, 'external.http'); | ||
@@ -98,3 +106,3 @@ var taskId = transactionService.addTask(); | ||
var isSameOrigin = checkSameOrigin(requestUrl.origin, currentUrl.origin) || checkSameOrigin(requestUrl.origin, dtOrigins); | ||
var target = task.data.target; | ||
var target = data.target; | ||
@@ -105,34 +113,14 @@ if (isDtEnabled && isSameOrigin && target) { | ||
span.addContext({ | ||
http: { | ||
method: task.data.method, | ||
url: requestUrl.href | ||
} | ||
}); | ||
span.sync = task.data.sync; | ||
task.data.span = span; | ||
span.sync = data.sync; | ||
data.span = span; | ||
task.id = taskId; | ||
} | ||
} else if (event === INVOKE) { | ||
if (task.data && task.data.span) { | ||
task.data.span.end(null, task.data); | ||
} | ||
if (event === INVOKE && task.data && task.data.span) { | ||
if (typeof task.data.target.status !== 'undefined') { | ||
task.data.span.addContext({ | ||
http: { | ||
status_code: task.data.target.status | ||
} | ||
}); | ||
} else if (task.data.response) { | ||
task.data.span.addContext({ | ||
http: { | ||
status_code: task.data.response.status | ||
} | ||
}); | ||
if (task.id) { | ||
transactionService.removeTask(task.id); | ||
} | ||
task.data.span.end(); | ||
} | ||
if (event === INVOKE && task.id) { | ||
transactionService.removeTask(task.id); | ||
} | ||
}; | ||
@@ -143,4 +131,3 @@ | ||
var headerName = configService.get('distributedTracingHeaderName'); | ||
var headerValueCallback = configService.get('distributedTracingHeaderValueCallback'); | ||
var headerValue = headerValueCallback(span); | ||
var headerValue = getDtHeaderValue(span); | ||
var isHeaderValid = isDtHeaderValid(headerValue); | ||
@@ -168,10 +155,2 @@ | ||
_proto.setTransactionContext = function setTransactionContext(transaction) { | ||
var context = this._configService.get('context'); | ||
if (context) { | ||
transaction.addContext(context); | ||
} | ||
}; | ||
_proto.filterTransaction = function filterTransaction(tr) { | ||
@@ -206,10 +185,2 @@ var transactionDurationThreshold = this._configService.get('transactionDurationThreshold'); | ||
if (tr.spans.length === 0) { | ||
if (__DEV__) { | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Transaction does not include any spans"); | ||
} | ||
return false; | ||
} | ||
if (!tr.sampled) { | ||
@@ -219,14 +190,8 @@ tr.resetSpans(); | ||
var browserResponsivenessInterval = this._configService.get('browserResponsivenessInterval'); | ||
if (tr.options.checkBrowserResponsiveness) { | ||
var wasBrowserResponsive = this.checkBrowserResponsiveness(tr, BROWSER_RESPONSIVENESS_INTERVAL, BROWSER_RESPONSIVENESS_BUFFER); | ||
var checkBrowserResponsiveness = this._configService.get('checkBrowserResponsiveness'); | ||
if (checkBrowserResponsiveness && tr.options.checkBrowserResponsiveness) { | ||
var buffer = this._configService.get('browserResponsivenessBuffer'); | ||
var wasBrowserResponsive = this.checkBrowserResponsiveness(tr, browserResponsivenessInterval, buffer); | ||
if (!wasBrowserResponsive) { | ||
if (__DEV__) { | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Browser was not responsive enough during the transaction.", ' duration:', duration, ' browserResponsivenessCounter:', tr.browserResponsivenessCounter, 'interval:', browserResponsivenessInterval); | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Browser was not responsive enough during the transaction.", ' duration:', duration, ' browserResponsivenessCounter:', tr.browserResponsivenessCounter); | ||
} | ||
@@ -247,5 +212,3 @@ | ||
if (this._configService.get('groupSimilarSpans')) { | ||
var similarSpanThreshold = this._configService.get('similarSpanThreshold'); | ||
transaction.spans = this.groupSmallContinuouslySimilarSpans(transaction, similarSpanThreshold); | ||
transaction.spans = this.groupSmallContinuouslySimilarSpans(transaction, SIMILAR_SPAN_TO_TRANSACTION_RATIO); | ||
} | ||
@@ -256,8 +219,5 @@ | ||
}); | ||
this.setTransactionContext(transaction); | ||
}; | ||
_proto.createTransactionDataModel = function createTransactionDataModel(transaction) { | ||
var configContext = this._configService.get('context'); | ||
var transactionStart = transaction._start; | ||
@@ -281,3 +241,2 @@ var spans = transaction.spans.map(function (span) { | ||
}); | ||
var context = merge({}, configContext, transaction.context); | ||
var transactionData = { | ||
@@ -290,3 +249,3 @@ id: transaction.id, | ||
spans: spans, | ||
context: context, | ||
context: transaction.context, | ||
marks: transaction.marks, | ||
@@ -351,11 +310,5 @@ breakdown: transaction.breakdownTimings, | ||
var counter = transaction.browserResponsivenessCounter; | ||
if (typeof interval === 'undefined' || typeof counter === 'undefined') { | ||
return true; | ||
} | ||
var duration = transaction.duration(); | ||
var expectedCount = Math.floor(duration / interval); | ||
var wasBrowserResponsive = counter + buffer >= expectedCount; | ||
return wasBrowserResponsive; | ||
return counter + buffer >= expectedCount; | ||
}; | ||
@@ -362,0 +315,0 @@ |
@@ -58,6 +58,10 @@ import { generateRandomId, setLabel, merge, getDuration, getTime } from '../common/utils'; | ||
_proto.addContext = function addContext(context) { | ||
if (!context) return; | ||
_proto.addContext = function addContext() { | ||
for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) { | ||
context[_key] = arguments[_key]; | ||
} | ||
if (context.length === 0) return; | ||
this.ensureContext(); | ||
merge(this.context, context); | ||
merge.apply(void 0, [this.context].concat(context)); | ||
}; | ||
@@ -64,0 +68,0 @@ |
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } | ||
import SpanBase from './span-base'; | ||
import { addSpanContext } from '../common/context'; | ||
@@ -28,2 +29,10 @@ var Span = function (_SpanBase) { | ||
var _proto = Span.prototype; | ||
_proto.end = function end(endTime, data) { | ||
_SpanBase.prototype.end.call(this, endTime); | ||
addSpanContext(this, data); | ||
}; | ||
return Span; | ||
@@ -30,0 +39,0 @@ }(SpanBase); |
import { Promise } from 'es6-promise'; | ||
import Transaction from './transaction'; | ||
import { extend, getEarliestSpan, getLatestNonXHRSpan } from '../common/utils'; | ||
import { PAGE_LOAD, NAME_UNKNOWN } from '../common/constants'; | ||
import { captureNavigation } from './capture-navigation'; | ||
import { PAGE_LOAD, NAME_UNKNOWN, TRANSACTION_START, TRANSACTION_END, BROWSER_RESPONSIVENESS_INTERVAL, TEMPORARY_TYPE, TRANSACTION_TYPE_ORDER } from '../common/constants'; | ||
import { addTransactionContext } from '../common/context'; | ||
import { __DEV__ } from '../env'; | ||
import { TRANSACTION_START, TRANSACTION_END } from '../common/constants'; | ||
@@ -14,2 +14,3 @@ var TransactionService = function () { | ||
this.currentTransaction = undefined; | ||
this.respIntervalId = undefined; | ||
} | ||
@@ -19,7 +20,3 @@ | ||
_proto.ensureCurrentTransaction = function ensureCurrentTransaction(options) { | ||
if (!options) { | ||
options = this.createOptions(); | ||
} | ||
_proto.ensureCurrentTransaction = function ensureCurrentTransaction(name, type, options) { | ||
var tr = this.getCurrentTransaction(); | ||
@@ -30,6 +27,7 @@ | ||
} else { | ||
options.canReuse = true; | ||
options.managed = true; | ||
return this.createTransaction(undefined, undefined, options); | ||
tr = new Transaction(name, type, options); | ||
this.setCurrentTransaction(tr); | ||
} | ||
return tr; | ||
}; | ||
@@ -47,33 +45,25 @@ | ||
_proto.createTransaction = function createTransaction(name, type, options) { | ||
var tr = new Transaction(name, type, options); | ||
this.setCurrentTransaction(tr); | ||
_proto.ensureRespInterval = function ensureRespInterval(checkBrowserResponsiveness) { | ||
var _this = this; | ||
if (options.checkBrowserResponsiveness) { | ||
this.startCounter(tr); | ||
} | ||
var clearRespInterval = function clearRespInterval() { | ||
clearInterval(_this.respIntervalId); | ||
_this.respIntervalId = undefined; | ||
}; | ||
return tr; | ||
}; | ||
if (checkBrowserResponsiveness) { | ||
if (typeof this.respIntervalId === 'undefined') { | ||
this.respIntervalId = setInterval(function () { | ||
var tr = _this.getCurrentTransaction(); | ||
_proto.startCounter = function startCounter(transaction) { | ||
transaction.browserResponsivenessCounter = 0; | ||
var interval = this._config.get('browserResponsivenessInterval'); | ||
if (typeof interval === 'undefined') { | ||
if (__DEV__) { | ||
this._logger.debug('browserResponsivenessInterval config is undefined!'); | ||
if (tr) { | ||
tr.browserResponsivenessCounter++; | ||
} else { | ||
clearRespInterval(); | ||
} | ||
}, BROWSER_RESPONSIVENESS_INTERVAL); | ||
} | ||
return; | ||
} else if (typeof this.respIntervalId !== 'undefined') { | ||
clearRespInterval(); | ||
} | ||
var id = setInterval(function () { | ||
if (transaction.ended) { | ||
window.clearInterval(id); | ||
} else { | ||
transaction.browserResponsivenessCounter++; | ||
} | ||
}, interval); | ||
}; | ||
@@ -105,3 +95,3 @@ | ||
if (!tr) { | ||
tr = this.createTransaction(name, type, perfOptions); | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions); | ||
} else if (tr.canReuse() && perfOptions.canReuse) { | ||
@@ -112,3 +102,11 @@ if (__DEV__) { | ||
tr.redefine(name, undefined, perfOptions); | ||
var redefineType; | ||
var currentTypeOrder = TRANSACTION_TYPE_ORDER.indexOf(tr.type); | ||
var redefineTypeOrder = TRANSACTION_TYPE_ORDER.indexOf(type); | ||
if (currentTypeOrder !== -1 && redefineTypeOrder !== -1 && redefineTypeOrder < currentTypeOrder) { | ||
redefineType = type; | ||
} | ||
tr.redefine(name, redefineType, perfOptions); | ||
} else { | ||
@@ -120,3 +118,3 @@ if (__DEV__) { | ||
tr.end(); | ||
tr = this.createTransaction(name, type, perfOptions); | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions); | ||
} | ||
@@ -126,3 +124,3 @@ | ||
if (type === PAGE_LOAD) { | ||
if (tr.type === PAGE_LOAD) { | ||
tr.options.checkBrowserResponsiveness = false; | ||
@@ -143,2 +141,3 @@ | ||
this.ensureRespInterval(tr.options.checkBrowserResponsiveness); | ||
return tr; | ||
@@ -148,3 +147,3 @@ }; | ||
_proto.startTransaction = function startTransaction(name, type, options) { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -161,3 +160,3 @@ var perfOptions = this.createOptions(options); | ||
tr.onEnd = function () { | ||
return _this.handleTransactionEnd(tr); | ||
return _this2.handleTransactionEnd(tr); | ||
}; | ||
@@ -175,3 +174,3 @@ | ||
_proto.handleTransactionEnd = function handleTransactionEnd(tr) { | ||
var _this2 = this; | ||
var _this3 = this; | ||
@@ -182,5 +181,5 @@ return Promise.resolve().then(function () { | ||
if (_this2.shouldIgnoreTransaction(name)) { | ||
if (_this3.shouldIgnoreTransaction(name) || type === TEMPORARY_TYPE) { | ||
if (__DEV__) { | ||
_this2._logger.debug("transaction(" + tr.id + ", " + name + ", " + type + ") is ignored"); | ||
_this3._logger.debug("transaction(" + tr.id + ", " + name + ", " + type + ") is ignored"); | ||
} | ||
@@ -192,3 +191,3 @@ | ||
if (type === PAGE_LOAD) { | ||
var pageLoadTransactionName = _this2._config.get('pageLoadTransactionName'); | ||
var pageLoadTransactionName = _this3._config.get('pageLoadTransactionName'); | ||
@@ -202,5 +201,5 @@ if (name === NAME_UNKNOWN && pageLoadTransactionName) { | ||
_this2.adjustTransactionTime(tr); | ||
_this3.adjustTransactionTime(tr); | ||
var breakdownMetrics = _this2._config.get('breakdownMetrics'); | ||
var breakdownMetrics = _this3._config.get('breakdownMetrics'); | ||
@@ -211,10 +210,14 @@ if (breakdownMetrics) { | ||
_this2._config.events.send(TRANSACTION_END, [tr]); | ||
var configContext = _this3._config.get('context'); | ||
addTransactionContext(tr, configContext); | ||
_this3._config.events.send(TRANSACTION_END, [tr]); | ||
if (__DEV__) { | ||
_this2._logger.debug("end transaction(" + tr.id + ", " + tr.name + ")", tr); | ||
_this3._logger.debug("end transaction(" + tr.id + ", " + tr.name + ")", tr); | ||
} | ||
}, function (err) { | ||
if (__DEV__) { | ||
_this2._logger.debug("error ending transaction(" + tr.id + ", " + tr.name + ")", err); | ||
_this3._logger.debug("error ending transaction(" + tr.id + ", " + tr.name + ")", err); | ||
} | ||
@@ -275,3 +278,6 @@ }); | ||
_proto.startSpan = function startSpan(name, type, options) { | ||
var tr = this.ensureCurrentTransaction(); | ||
var tr = this.ensureCurrentTransaction(undefined, TEMPORARY_TYPE, this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
})); | ||
@@ -290,3 +296,6 @@ if (tr) { | ||
_proto.addTask = function addTask(taskId) { | ||
var tr = this.ensureCurrentTransaction(); | ||
var tr = this.ensureCurrentTransaction(undefined, TEMPORARY_TYPE, this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
})); | ||
@@ -293,0 +302,0 @@ if (tr) { |
@@ -5,3 +5,3 @@ function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } | ||
import SpanBase from './span-base'; | ||
import { generateRandomId, merge, now, getTime, extend, getPageMetadata, removeInvalidChars } from '../common/utils'; | ||
import { generateRandomId, merge, now, getTime, extend, removeInvalidChars } from '../common/utils'; | ||
import { REUSABILITY_THRESHOLD } from '../common/constants'; | ||
@@ -26,2 +26,3 @@ import { captureBreakdown as _captureBreakdown } from './breakdown'; | ||
_this.sampled = Math.random() <= _this.options.transactionSampleRate; | ||
_this.browserResponsivenessCounter = 0; | ||
return _this; | ||
@@ -117,4 +118,2 @@ } | ||
var metadata = getPageMetadata(); | ||
this.addContext(metadata); | ||
this.callOnEnd(); | ||
@@ -121,0 +120,0 @@ }; |
@@ -18,2 +18,4 @@ "use strict"; | ||
var _constants = require("./constants"); | ||
var _env = require("../env"); | ||
@@ -389,3 +391,3 @@ | ||
var endPoint = this._configService.getEndpointUrl(); | ||
var endPoint = this._configService.get('serverUrl') + _constants.SERVER_URL_PREFIX; | ||
@@ -392,0 +394,0 @@ return this._postJson(endPoint, ndjsonPayload); |
@@ -52,3 +52,2 @@ "use strict"; | ||
serverUrl: 'http://localhost:8200', | ||
serverUrlPrefix: '/intake/v2/rum/events', | ||
active: true, | ||
@@ -60,4 +59,2 @@ instrument: true, | ||
breakdownMetrics: false, | ||
browserResponsivenessInterval: 500, | ||
browserResponsivenessBuffer: 3, | ||
checkBrowserResponsiveness: true, | ||
@@ -76,3 +73,2 @@ groupSimilarSpans: true, | ||
distributedTracingOrigins: [], | ||
distributedTracingHeaderValueCallback: _utils.getDtHeaderValue, | ||
distributedTracingHeaderName: 'elastic-apm-traceparent', | ||
@@ -133,6 +129,2 @@ pageLoadTraceId: '', | ||
_proto.getEndpointUrl = function getEndpointUrl() { | ||
return this.config.serverUrl + this.config.serverUrlPrefix; | ||
}; | ||
_proto.setUserContext = function setUserContext(userContext) { | ||
@@ -139,0 +131,0 @@ if (userContext === void 0) { |
"use strict"; | ||
exports.__esModule = true; | ||
exports.LOCAL_CONFIG_KEY = exports.AFTER_EVENT = exports.BEFORE_EVENT = exports.ERROR = exports.HISTORY = exports.FETCH = exports.XMLHTTPREQUEST = exports.CONFIG_CHANGE = exports.TRANSACTION_END = exports.TRANSACTION_START = exports.KEYWORD_LIMIT = exports.USER_TIMING_THRESHOLD = exports.TYPE_CUSTOM = exports.NAME_UNKNOWN = exports.ROUTE_CHANGE = exports.PAGE_LOAD = exports.MAX_SPAN_DURATION = exports.REUSABILITY_THRESHOLD = exports.RESOURCE_INITIATOR_TYPES = exports.REMOVE_EVENT_LISTENER_STR = exports.ADD_EVENT_LISTENER_STR = exports.CLEAR = exports.INVOKE = exports.SCHEDULE = void 0; | ||
exports.TRANSACTION_TYPE_ORDER = exports.TEMPORARY_TYPE = exports.SIMILAR_SPAN_TO_TRANSACTION_RATIO = exports.BROWSER_RESPONSIVENESS_BUFFER = exports.BROWSER_RESPONSIVENESS_INTERVAL = exports.SERVER_URL_PREFIX = exports.KEYWORD_LIMIT = exports.HTTP_REQUEST_TYPE = exports.LOCAL_CONFIG_KEY = exports.AFTER_EVENT = exports.BEFORE_EVENT = exports.ERROR = exports.HISTORY = exports.FETCH = exports.XMLHTTPREQUEST = exports.CONFIG_CHANGE = exports.TRANSACTION_END = exports.TRANSACTION_START = exports.USER_TIMING_THRESHOLD = exports.TYPE_CUSTOM = exports.NAME_UNKNOWN = exports.ROUTE_CHANGE = exports.PAGE_LOAD = exports.MAX_SPAN_DURATION = exports.REUSABILITY_THRESHOLD = exports.RESOURCE_INITIATOR_TYPES = exports.REMOVE_EVENT_LISTENER_STR = exports.ADD_EVENT_LISTENER_STR = exports.CLEAR = exports.INVOKE = exports.SCHEDULE = void 0; | ||
var SCHEDULE = 'schedule'; | ||
@@ -25,10 +25,14 @@ exports.SCHEDULE = SCHEDULE; | ||
exports.ROUTE_CHANGE = ROUTE_CHANGE; | ||
var TYPE_CUSTOM = 'custom'; | ||
exports.TYPE_CUSTOM = TYPE_CUSTOM; | ||
var HTTP_REQUEST_TYPE = 'http-request'; | ||
exports.HTTP_REQUEST_TYPE = HTTP_REQUEST_TYPE; | ||
var TEMPORARY_TYPE = 'temporary'; | ||
exports.TEMPORARY_TYPE = TEMPORARY_TYPE; | ||
var NAME_UNKNOWN = 'Unknown'; | ||
exports.NAME_UNKNOWN = NAME_UNKNOWN; | ||
var TYPE_CUSTOM = 'custom'; | ||
exports.TYPE_CUSTOM = TYPE_CUSTOM; | ||
var TRANSACTION_TYPE_ORDER = [PAGE_LOAD, ROUTE_CHANGE, HTTP_REQUEST_TYPE, TYPE_CUSTOM, TEMPORARY_TYPE]; | ||
exports.TRANSACTION_TYPE_ORDER = TRANSACTION_TYPE_ORDER; | ||
var USER_TIMING_THRESHOLD = 60; | ||
exports.USER_TIMING_THRESHOLD = USER_TIMING_THRESHOLD; | ||
var KEYWORD_LIMIT = 1024; | ||
exports.KEYWORD_LIMIT = KEYWORD_LIMIT; | ||
var TRANSACTION_START = 'transaction:start'; | ||
@@ -53,2 +57,12 @@ exports.TRANSACTION_START = TRANSACTION_START; | ||
var LOCAL_CONFIG_KEY = 'elastic_apm_config'; | ||
exports.LOCAL_CONFIG_KEY = LOCAL_CONFIG_KEY; | ||
exports.LOCAL_CONFIG_KEY = LOCAL_CONFIG_KEY; | ||
var KEYWORD_LIMIT = 1024; | ||
exports.KEYWORD_LIMIT = KEYWORD_LIMIT; | ||
var SERVER_URL_PREFIX = '/intake/v2/rum/events'; | ||
exports.SERVER_URL_PREFIX = SERVER_URL_PREFIX; | ||
var BROWSER_RESPONSIVENESS_INTERVAL = 500; | ||
exports.BROWSER_RESPONSIVENESS_INTERVAL = BROWSER_RESPONSIVENESS_INTERVAL; | ||
var BROWSER_RESPONSIVENESS_BUFFER = 3; | ||
exports.BROWSER_RESPONSIVENESS_BUFFER = BROWSER_RESPONSIVENESS_BUFFER; | ||
var SIMILAR_SPAN_TO_TRANSACTION_RATIO = 0.05; | ||
exports.SIMILAR_SPAN_TO_TRANSACTION_RATIO = SIMILAR_SPAN_TO_TRANSACTION_RATIO; |
@@ -12,2 +12,4 @@ "use strict"; | ||
var _utils = require("../utils"); | ||
function patchFetch(callback) { | ||
@@ -54,3 +56,2 @@ if (!window.fetch || !window.Request) { | ||
url: url, | ||
args: args, | ||
aborted: false | ||
@@ -76,4 +77,3 @@ } | ||
resolve(response); | ||
_es6Promise.Promise.resolve().then(function () { | ||
(0, _utils.scheduleMicroTask)(function () { | ||
task.data.response = response; | ||
@@ -84,4 +84,3 @@ invokeTask(task); | ||
reject(error); | ||
_es6Promise.Promise.resolve().then(function () { | ||
(0, _utils.scheduleMicroTask)(function () { | ||
task.data.error = error; | ||
@@ -88,0 +87,0 @@ invokeTask(task); |
@@ -36,6 +36,3 @@ "use strict"; | ||
task.state = _constants.INVOKE; | ||
if (!task.ignore) { | ||
callback(_constants.INVOKE, task); | ||
} | ||
callback(_constants.INVOKE, task); | ||
} | ||
@@ -46,11 +43,7 @@ | ||
task.state = _constants.SCHEDULE; | ||
callback(_constants.SCHEDULE, task); | ||
var _task$data = task.data, | ||
aborted = _task$data.aborted, | ||
target = _task$data.target; | ||
if (!task.ignore) { | ||
callback(_constants.SCHEDULE, task); | ||
} | ||
var data = task.data; | ||
var target = data.target; | ||
var listener = target[XHR_LISTENER]; | ||
if (!oriAddListener) { | ||
@@ -61,2 +54,4 @@ oriAddListener = target[_constants.ADD_EVENT_LISTENER_STR]; | ||
var listener = target[XHR_LISTENER]; | ||
if (listener) { | ||
@@ -82,3 +77,3 @@ oriRemoveListener.call(target, READY_STATE_CHANGE, listener); | ||
if (target.readyState === target.DONE) { | ||
if (!data.aborted && XMLHttpRequest[XHR_SCHEDULED] && task.state === _constants.SCHEDULE) { | ||
if (!aborted && XMLHttpRequest[XHR_SCHEDULED] && task.state === _constants.SCHEDULE) { | ||
earlierEvent = type; | ||
@@ -97,6 +92,2 @@ } | ||
} | ||
var result = sendNative.apply(target, data.args); | ||
XMLHttpRequest[XHR_SCHEDULED] = true; | ||
return result; | ||
} | ||
@@ -113,5 +104,8 @@ | ||
return function (self, args) { | ||
self[_patchUtils.XHR_METHOD] = args[0]; | ||
self[_patchUtils.XHR_URL] = args[1]; | ||
self[_patchUtils.XHR_SYNC] = args[2] === false; | ||
if (!self[_patchUtils.XHR_IGNORE]) { | ||
self[_patchUtils.XHR_METHOD] = args[0]; | ||
self[_patchUtils.XHR_URL] = args[1]; | ||
self[_patchUtils.XHR_SYNC] = args[2] === false; | ||
} | ||
return openNative.apply(self, args); | ||
@@ -122,2 +116,6 @@ }; | ||
return function (self, args) { | ||
if (self[_patchUtils.XHR_IGNORE]) { | ||
return sendNative.apply(self, args); | ||
} | ||
var task = { | ||
@@ -127,3 +125,2 @@ source: _constants.XMLHTTPREQUEST, | ||
type: 'macroTask', | ||
ignore: self[_patchUtils.XHR_IGNORE], | ||
data: { | ||
@@ -134,7 +131,8 @@ target: self, | ||
url: self[_patchUtils.XHR_URL], | ||
args: args, | ||
aborted: false | ||
} | ||
}; | ||
var result = scheduleTask(task); | ||
scheduleTask(task); | ||
var result = sendNative.apply(self, args); | ||
XMLHttpRequest[XHR_SCHEDULED] = true; | ||
@@ -150,10 +148,12 @@ if (self[_patchUtils.XHR_SYNC]) { | ||
return function (self, args) { | ||
var task = self[XHR_TASK]; | ||
if (!self[_patchUtils.XHR_IGNORE]) { | ||
var task = self[XHR_TASK]; | ||
if (task && typeof task.type === 'string') { | ||
if (task.data && task.data.aborted) { | ||
return; | ||
if (task && typeof task.type === 'string') { | ||
if (task.data && task.data.aborted) { | ||
return; | ||
} | ||
clearTask(task); | ||
} | ||
clearTask(task); | ||
} | ||
@@ -160,0 +160,0 @@ |
@@ -6,3 +6,3 @@ "use strict"; | ||
exports.truncateModel = truncateModel; | ||
exports.METADATA_MODEL = exports.ERROR_MODEL = exports.TRANSACTION_MODEL = exports.SPAN_MODEL = void 0; | ||
exports.RESPONSE_MODEL = exports.METADATA_MODEL = exports.ERROR_MODEL = exports.TRANSACTION_MODEL = exports.SPAN_MODEL = void 0; | ||
@@ -28,2 +28,9 @@ var _constants = require("./constants"); | ||
}; | ||
exports.RESPONSE_MODEL = RESPONSE_MODEL; | ||
var DESTINATION_MODEL = { | ||
address: [_constants.KEYWORD_LIMIT], | ||
service: { | ||
'*': [_constants.KEYWORD_LIMIT, true] | ||
} | ||
}; | ||
var CONTEXT_MODEL = { | ||
@@ -41,2 +48,3 @@ user: { | ||
}, | ||
destination: DESTINATION_MODEL, | ||
response: RESPONSE_MODEL | ||
@@ -43,0 +51,0 @@ }; |
@@ -5,2 +5,15 @@ "use strict"; | ||
exports.default = void 0; | ||
function isDefaultPort(port, protocol) { | ||
switch (protocol) { | ||
case 'http:': | ||
return port === '80'; | ||
case 'https:': | ||
return port === '443'; | ||
} | ||
return true; | ||
} | ||
var RULES = [['#', 'hash'], ['?', 'query'], ['/', 'path'], ['@', 'auth', 1], [NaN, 'host', undefined, 1]]; | ||
@@ -63,2 +76,19 @@ var PROTOCOL_REGEX = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i; | ||
this.protocol = protocol || location.protocol; | ||
this.hostname = this.host; | ||
this.port = ''; | ||
if (/:\d+$/.test(this.host)) { | ||
var value = this.host.split(':'); | ||
var port = value.pop(); | ||
var hostname = value.join(':'); | ||
if (isDefaultPort(port, this.protocol)) { | ||
this.host = hostname; | ||
} else { | ||
this.port = port; | ||
} | ||
this.hostname = hostname; | ||
} | ||
this.origin = this.protocol && this.host && this.protocol !== 'file:' ? this.protocol + '//' + this.host : 'null'; | ||
@@ -65,0 +95,0 @@ this.href = this.toString(); |
@@ -27,23 +27,2 @@ "use strict"; | ||
function getResponseContext(perfTimingEntry) { | ||
var transferSize = perfTimingEntry.transferSize, | ||
encodedBodySize = perfTimingEntry.encodedBodySize, | ||
decodedBodySize = perfTimingEntry.decodedBodySize, | ||
serverTiming = perfTimingEntry.serverTiming; | ||
var respContext = { | ||
transfer_size: transferSize, | ||
encoded_body_size: encodedBodySize, | ||
decoded_body_size: decodedBodySize | ||
}; | ||
var serverTimingStr = (0, _utils.getServerTimingInfo)(serverTiming); | ||
if (serverTimingStr) { | ||
respContext.headers = { | ||
'server-timing': serverTimingStr | ||
}; | ||
} | ||
return respContext; | ||
} | ||
function createNavigationTimingSpans(timings, baseTime, trStart, trEnd) { | ||
@@ -67,4 +46,3 @@ var spans = []; | ||
span._start = start - baseTime; | ||
span.ended = true; | ||
span._end = end - baseTime; | ||
span.end(end - baseTime); | ||
spans.push(span); | ||
@@ -89,11 +67,7 @@ } | ||
var span = new _span.default(spanName, kind); | ||
span.addContext({ | ||
http: { | ||
url: name, | ||
response: getResponseContext(resourceTimingEntry) | ||
} | ||
span._start = startTime; | ||
span.end(responseEnd, { | ||
url: name, | ||
entry: resourceTimingEntry | ||
}); | ||
span._start = startTime; | ||
span.end(); | ||
span._end = responseEnd; | ||
return span; | ||
@@ -164,4 +138,3 @@ } | ||
span._start = startTime; | ||
span.end(); | ||
span._end = end; | ||
span.end(end); | ||
userTimingSpans.push(span); | ||
@@ -233,14 +206,3 @@ } | ||
}); | ||
if (transaction.type === _constants.PAGE_LOAD) { | ||
var navigationEntry = perf.getEntriesByType('navigation'); | ||
if (navigationEntry && navigationEntry.length > 0) { | ||
navigationEntry = navigationEntry[0]; | ||
transaction.addContext({ | ||
response: getResponseContext(navigationEntry) | ||
}); | ||
} | ||
} | ||
} | ||
} |
@@ -97,4 +97,12 @@ "use strict"; | ||
if (event === _constants.SCHEDULE && task.data) { | ||
var requestUrl = new _url.default(task.data.url); | ||
var spanName = task.data.method + ' ' + (requestUrl.relative ? requestUrl.path : (0, _utils.stripQueryStringFromUrl)(requestUrl.href)); | ||
var data = task.data; | ||
var requestUrl = new _url.default(data.url); | ||
var spanName = data.method + ' ' + (requestUrl.relative ? requestUrl.path : (0, _utils.stripQueryStringFromUrl)(requestUrl.href)); | ||
if (!transactionService.getCurrentTransaction()) { | ||
transactionService.startTransaction(spanName, _constants.HTTP_REQUEST_TYPE, { | ||
managed: true | ||
}); | ||
} | ||
var span = transactionService.startSpan(spanName, 'external.http'); | ||
@@ -111,3 +119,3 @@ var taskId = transactionService.addTask(); | ||
var isSameOrigin = (0, _utils.checkSameOrigin)(requestUrl.origin, currentUrl.origin) || (0, _utils.checkSameOrigin)(requestUrl.origin, dtOrigins); | ||
var target = task.data.target; | ||
var target = data.target; | ||
@@ -118,34 +126,14 @@ if (isDtEnabled && isSameOrigin && target) { | ||
span.addContext({ | ||
http: { | ||
method: task.data.method, | ||
url: requestUrl.href | ||
} | ||
}); | ||
span.sync = task.data.sync; | ||
task.data.span = span; | ||
span.sync = data.sync; | ||
data.span = span; | ||
task.id = taskId; | ||
} | ||
} else if (event === _constants.INVOKE) { | ||
if (task.data && task.data.span) { | ||
task.data.span.end(null, task.data); | ||
} | ||
if (event === _constants.INVOKE && task.data && task.data.span) { | ||
if (typeof task.data.target.status !== 'undefined') { | ||
task.data.span.addContext({ | ||
http: { | ||
status_code: task.data.target.status | ||
} | ||
}); | ||
} else if (task.data.response) { | ||
task.data.span.addContext({ | ||
http: { | ||
status_code: task.data.response.status | ||
} | ||
}); | ||
if (task.id) { | ||
transactionService.removeTask(task.id); | ||
} | ||
task.data.span.end(); | ||
} | ||
if (event === _constants.INVOKE && task.id) { | ||
transactionService.removeTask(task.id); | ||
} | ||
}; | ||
@@ -156,4 +144,3 @@ | ||
var headerName = configService.get('distributedTracingHeaderName'); | ||
var headerValueCallback = configService.get('distributedTracingHeaderValueCallback'); | ||
var headerValue = headerValueCallback(span); | ||
var headerValue = (0, _utils.getDtHeaderValue)(span); | ||
var isHeaderValid = (0, _utils.isDtHeaderValid)(headerValue); | ||
@@ -181,10 +168,2 @@ | ||
_proto.setTransactionContext = function setTransactionContext(transaction) { | ||
var context = this._configService.get('context'); | ||
if (context) { | ||
transaction.addContext(context); | ||
} | ||
}; | ||
_proto.filterTransaction = function filterTransaction(tr) { | ||
@@ -219,10 +198,2 @@ var transactionDurationThreshold = this._configService.get('transactionDurationThreshold'); | ||
if (tr.spans.length === 0) { | ||
if (_env.__DEV__) { | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Transaction does not include any spans"); | ||
} | ||
return false; | ||
} | ||
if (!tr.sampled) { | ||
@@ -232,14 +203,8 @@ tr.resetSpans(); | ||
var browserResponsivenessInterval = this._configService.get('browserResponsivenessInterval'); | ||
if (tr.options.checkBrowserResponsiveness) { | ||
var wasBrowserResponsive = this.checkBrowserResponsiveness(tr, _constants.BROWSER_RESPONSIVENESS_INTERVAL, _constants.BROWSER_RESPONSIVENESS_BUFFER); | ||
var checkBrowserResponsiveness = this._configService.get('checkBrowserResponsiveness'); | ||
if (checkBrowserResponsiveness && tr.options.checkBrowserResponsiveness) { | ||
var buffer = this._configService.get('browserResponsivenessBuffer'); | ||
var wasBrowserResponsive = this.checkBrowserResponsiveness(tr, browserResponsivenessInterval, buffer); | ||
if (!wasBrowserResponsive) { | ||
if (_env.__DEV__) { | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Browser was not responsive enough during the transaction.", ' duration:', duration, ' browserResponsivenessCounter:', tr.browserResponsivenessCounter, 'interval:', browserResponsivenessInterval); | ||
this._logginService.debug("transaction(" + tr.id + ", " + tr.name + ") was discarded! Browser was not responsive enough during the transaction.", ' duration:', duration, ' browserResponsivenessCounter:', tr.browserResponsivenessCounter); | ||
} | ||
@@ -260,5 +225,3 @@ | ||
if (this._configService.get('groupSimilarSpans')) { | ||
var similarSpanThreshold = this._configService.get('similarSpanThreshold'); | ||
transaction.spans = this.groupSmallContinuouslySimilarSpans(transaction, similarSpanThreshold); | ||
transaction.spans = this.groupSmallContinuouslySimilarSpans(transaction, _constants.SIMILAR_SPAN_TO_TRANSACTION_RATIO); | ||
} | ||
@@ -269,8 +232,5 @@ | ||
}); | ||
this.setTransactionContext(transaction); | ||
}; | ||
_proto.createTransactionDataModel = function createTransactionDataModel(transaction) { | ||
var configContext = this._configService.get('context'); | ||
var transactionStart = transaction._start; | ||
@@ -294,3 +254,2 @@ var spans = transaction.spans.map(function (span) { | ||
}); | ||
var context = (0, _utils.merge)({}, configContext, transaction.context); | ||
var transactionData = { | ||
@@ -303,3 +262,3 @@ id: transaction.id, | ||
spans: spans, | ||
context: context, | ||
context: transaction.context, | ||
marks: transaction.marks, | ||
@@ -364,11 +323,5 @@ breakdown: transaction.breakdownTimings, | ||
var counter = transaction.browserResponsivenessCounter; | ||
if (typeof interval === 'undefined' || typeof counter === 'undefined') { | ||
return true; | ||
} | ||
var duration = transaction.duration(); | ||
var expectedCount = Math.floor(duration / interval); | ||
var wasBrowserResponsive = counter + buffer >= expectedCount; | ||
return wasBrowserResponsive; | ||
return counter + buffer >= expectedCount; | ||
}; | ||
@@ -375,0 +328,0 @@ |
@@ -64,6 +64,11 @@ "use strict"; | ||
_proto.addContext = function addContext(context) { | ||
if (!context) return; | ||
_proto.addContext = function addContext() { | ||
for (var _len = arguments.length, context = new Array(_len), _key = 0; _key < _len; _key++) { | ||
context[_key] = arguments[_key]; | ||
} | ||
if (context.length === 0) return; | ||
this.ensureContext(); | ||
(0, _utils.merge)(this.context, context); | ||
_utils.merge.apply(void 0, [this.context].concat(context)); | ||
}; | ||
@@ -70,0 +75,0 @@ |
@@ -8,2 +8,4 @@ "use strict"; | ||
var _context = require("../common/context"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -36,2 +38,10 @@ | ||
var _proto = Span.prototype; | ||
_proto.end = function end(endTime, data) { | ||
_SpanBase.prototype.end.call(this, endTime); | ||
(0, _context.addSpanContext)(this, data); | ||
}; | ||
return Span; | ||
@@ -38,0 +48,0 @@ }(_spanBase.default); |
@@ -12,5 +12,7 @@ "use strict"; | ||
var _captureNavigation = require("./capture-navigation"); | ||
var _constants = require("../common/constants"); | ||
var _captureNavigation = require("./capture-navigation"); | ||
var _context = require("../common/context"); | ||
@@ -26,2 +28,3 @@ var _env = require("../env"); | ||
this.currentTransaction = undefined; | ||
this.respIntervalId = undefined; | ||
} | ||
@@ -31,7 +34,3 @@ | ||
_proto.ensureCurrentTransaction = function ensureCurrentTransaction(options) { | ||
if (!options) { | ||
options = this.createOptions(); | ||
} | ||
_proto.ensureCurrentTransaction = function ensureCurrentTransaction(name, type, options) { | ||
var tr = this.getCurrentTransaction(); | ||
@@ -42,6 +41,7 @@ | ||
} else { | ||
options.canReuse = true; | ||
options.managed = true; | ||
return this.createTransaction(undefined, undefined, options); | ||
tr = new _transaction.default(name, type, options); | ||
this.setCurrentTransaction(tr); | ||
} | ||
return tr; | ||
}; | ||
@@ -59,33 +59,25 @@ | ||
_proto.createTransaction = function createTransaction(name, type, options) { | ||
var tr = new _transaction.default(name, type, options); | ||
this.setCurrentTransaction(tr); | ||
_proto.ensureRespInterval = function ensureRespInterval(checkBrowserResponsiveness) { | ||
var _this = this; | ||
if (options.checkBrowserResponsiveness) { | ||
this.startCounter(tr); | ||
} | ||
var clearRespInterval = function clearRespInterval() { | ||
clearInterval(_this.respIntervalId); | ||
_this.respIntervalId = undefined; | ||
}; | ||
return tr; | ||
}; | ||
if (checkBrowserResponsiveness) { | ||
if (typeof this.respIntervalId === 'undefined') { | ||
this.respIntervalId = setInterval(function () { | ||
var tr = _this.getCurrentTransaction(); | ||
_proto.startCounter = function startCounter(transaction) { | ||
transaction.browserResponsivenessCounter = 0; | ||
var interval = this._config.get('browserResponsivenessInterval'); | ||
if (typeof interval === 'undefined') { | ||
if (_env.__DEV__) { | ||
this._logger.debug('browserResponsivenessInterval config is undefined!'); | ||
if (tr) { | ||
tr.browserResponsivenessCounter++; | ||
} else { | ||
clearRespInterval(); | ||
} | ||
}, _constants.BROWSER_RESPONSIVENESS_INTERVAL); | ||
} | ||
return; | ||
} else if (typeof this.respIntervalId !== 'undefined') { | ||
clearRespInterval(); | ||
} | ||
var id = setInterval(function () { | ||
if (transaction.ended) { | ||
window.clearInterval(id); | ||
} else { | ||
transaction.browserResponsivenessCounter++; | ||
} | ||
}, interval); | ||
}; | ||
@@ -117,3 +109,3 @@ | ||
if (!tr) { | ||
tr = this.createTransaction(name, type, perfOptions); | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions); | ||
} else if (tr.canReuse() && perfOptions.canReuse) { | ||
@@ -124,3 +116,13 @@ if (_env.__DEV__) { | ||
tr.redefine(name, undefined, perfOptions); | ||
var redefineType; | ||
var currentTypeOrder = _constants.TRANSACTION_TYPE_ORDER.indexOf(tr.type); | ||
var redefineTypeOrder = _constants.TRANSACTION_TYPE_ORDER.indexOf(type); | ||
if (currentTypeOrder !== -1 && redefineTypeOrder !== -1 && redefineTypeOrder < currentTypeOrder) { | ||
redefineType = type; | ||
} | ||
tr.redefine(name, redefineType, perfOptions); | ||
} else { | ||
@@ -132,3 +134,3 @@ if (_env.__DEV__) { | ||
tr.end(); | ||
tr = this.createTransaction(name, type, perfOptions); | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions); | ||
} | ||
@@ -138,3 +140,3 @@ | ||
if (type === _constants.PAGE_LOAD) { | ||
if (tr.type === _constants.PAGE_LOAD) { | ||
tr.options.checkBrowserResponsiveness = false; | ||
@@ -155,2 +157,3 @@ | ||
this.ensureRespInterval(tr.options.checkBrowserResponsiveness); | ||
return tr; | ||
@@ -160,3 +163,3 @@ }; | ||
_proto.startTransaction = function startTransaction(name, type, options) { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -173,3 +176,3 @@ var perfOptions = this.createOptions(options); | ||
tr.onEnd = function () { | ||
return _this.handleTransactionEnd(tr); | ||
return _this2.handleTransactionEnd(tr); | ||
}; | ||
@@ -187,3 +190,3 @@ | ||
_proto.handleTransactionEnd = function handleTransactionEnd(tr) { | ||
var _this2 = this; | ||
var _this3 = this; | ||
@@ -194,5 +197,5 @@ return _es6Promise.Promise.resolve().then(function () { | ||
if (_this2.shouldIgnoreTransaction(name)) { | ||
if (_this3.shouldIgnoreTransaction(name) || type === _constants.TEMPORARY_TYPE) { | ||
if (_env.__DEV__) { | ||
_this2._logger.debug("transaction(" + tr.id + ", " + name + ", " + type + ") is ignored"); | ||
_this3._logger.debug("transaction(" + tr.id + ", " + name + ", " + type + ") is ignored"); | ||
} | ||
@@ -204,3 +207,3 @@ | ||
if (type === _constants.PAGE_LOAD) { | ||
var pageLoadTransactionName = _this2._config.get('pageLoadTransactionName'); | ||
var pageLoadTransactionName = _this3._config.get('pageLoadTransactionName'); | ||
@@ -214,5 +217,5 @@ if (name === _constants.NAME_UNKNOWN && pageLoadTransactionName) { | ||
_this2.adjustTransactionTime(tr); | ||
_this3.adjustTransactionTime(tr); | ||
var breakdownMetrics = _this2._config.get('breakdownMetrics'); | ||
var breakdownMetrics = _this3._config.get('breakdownMetrics'); | ||
@@ -223,10 +226,14 @@ if (breakdownMetrics) { | ||
_this2._config.events.send(_constants.TRANSACTION_END, [tr]); | ||
var configContext = _this3._config.get('context'); | ||
(0, _context.addTransactionContext)(tr, configContext); | ||
_this3._config.events.send(_constants.TRANSACTION_END, [tr]); | ||
if (_env.__DEV__) { | ||
_this2._logger.debug("end transaction(" + tr.id + ", " + tr.name + ")", tr); | ||
_this3._logger.debug("end transaction(" + tr.id + ", " + tr.name + ")", tr); | ||
} | ||
}, function (err) { | ||
if (_env.__DEV__) { | ||
_this2._logger.debug("error ending transaction(" + tr.id + ", " + tr.name + ")", err); | ||
_this3._logger.debug("error ending transaction(" + tr.id + ", " + tr.name + ")", err); | ||
} | ||
@@ -287,3 +294,6 @@ }); | ||
_proto.startSpan = function startSpan(name, type, options) { | ||
var tr = this.ensureCurrentTransaction(); | ||
var tr = this.ensureCurrentTransaction(undefined, _constants.TEMPORARY_TYPE, this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
})); | ||
@@ -302,3 +312,6 @@ if (tr) { | ||
_proto.addTask = function addTask(taskId) { | ||
var tr = this.ensureCurrentTransaction(); | ||
var tr = this.ensureCurrentTransaction(undefined, _constants.TEMPORARY_TYPE, this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
})); | ||
@@ -305,0 +318,0 @@ if (tr) { |
@@ -36,2 +36,3 @@ "use strict"; | ||
_this.sampled = Math.random() <= _this.options.transactionSampleRate; | ||
_this.browserResponsivenessCounter = 0; | ||
return _this; | ||
@@ -127,4 +128,2 @@ } | ||
var metadata = (0, _utils.getPageMetadata)(); | ||
this.addContext(metadata); | ||
this.callOnEnd(); | ||
@@ -131,0 +130,0 @@ }; |
{ | ||
"name": "@elastic/apm-rum-core", | ||
"version": "4.7.0", | ||
"version": "4.8.0", | ||
"description": "Elastic apm core", | ||
@@ -44,3 +44,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "aa0625d1c4705028065cc2da451ee0f802040d92" | ||
"gitHead": "08b142a7571d7d1c3beec2909bf6170dbb1eef4e" | ||
} |
@@ -32,2 +32,3 @@ /** | ||
import { truncateModel, METADATA_MODEL } from './truncate' | ||
import { SERVER_URL_PREFIX } from './constants' | ||
import { __DEV__ } from '../env' | ||
@@ -314,3 +315,3 @@ | ||
const ndjsonPayload = ndjson.join('') | ||
const endPoint = this._configService.getEndpointUrl() | ||
const endPoint = this._configService.get('serverUrl') + SERVER_URL_PREFIX | ||
return this._postJson(endPoint, ndjsonPayload) | ||
@@ -317,0 +318,0 @@ } |
@@ -26,9 +26,3 @@ /** | ||
import { | ||
getCurrentScript, | ||
setLabel, | ||
merge, | ||
extend, | ||
getDtHeaderValue | ||
} from './utils' | ||
import { getCurrentScript, setLabel, merge, extend } from './utils' | ||
import EventHandler from './event-handler' | ||
@@ -80,3 +74,2 @@ import { CONFIG_CHANGE, LOCAL_CONFIG_KEY } from './constants' | ||
serverUrl: 'http://localhost:8200', | ||
serverUrlPrefix: '/intake/v2/rum/events', | ||
active: true, | ||
@@ -88,4 +81,2 @@ instrument: true, | ||
breakdownMetrics: false, | ||
browserResponsivenessInterval: 500, | ||
browserResponsivenessBuffer: 3, | ||
checkBrowserResponsiveness: true, | ||
@@ -95,4 +86,2 @@ groupSimilarSpans: true, | ||
ignoreTransactions: [], | ||
// throttlingRequestLimit: 20, | ||
// throttlingInterval: 30000, // 30s | ||
errorThrottleLimit: 20, | ||
@@ -109,3 +98,2 @@ errorThrottleInterval: 30000, | ||
distributedTracingOrigins: [], | ||
distributedTracingHeaderValueCallback: getDtHeaderValue, | ||
distributedTracingHeaderName: 'elastic-apm-traceparent', | ||
@@ -169,6 +157,2 @@ | ||
getEndpointUrl() { | ||
return this.config.serverUrl + this.config.serverUrlPrefix | ||
} | ||
setUserContext(userContext = {}) { | ||
@@ -209,4 +193,4 @@ const context = {} | ||
* | ||
* Remove all trailing slash for serverUrl since serverUrlPrefix | ||
* includes a forward slash for the path | ||
* Remove all trailing slash for serverUrl since SERVER_URL_PREFIX | ||
* already includes a forward slash for the path | ||
*/ | ||
@@ -213,0 +197,0 @@ if (properties.serverUrl) { |
@@ -68,5 +68,15 @@ /** | ||
const ROUTE_CHANGE = 'route-change' | ||
const TYPE_CUSTOM = 'custom' | ||
const HTTP_REQUEST_TYPE = 'http-request' | ||
const TEMPORARY_TYPE = 'temporary' | ||
const NAME_UNKNOWN = 'Unknown' | ||
const TYPE_CUSTOM = 'custom' | ||
const TRANSACTION_TYPE_ORDER = [ | ||
PAGE_LOAD, | ||
ROUTE_CHANGE, | ||
HTTP_REQUEST_TYPE, | ||
TYPE_CUSTOM, | ||
TEMPORARY_TYPE | ||
] | ||
/** | ||
@@ -78,7 +88,2 @@ * Check only for long tasks that are more than 60ms | ||
/** | ||
* Others | ||
*/ | ||
const KEYWORD_LIMIT = 1024 | ||
/** | ||
* Events - to be consumed by the users | ||
@@ -111,5 +116,13 @@ */ | ||
*/ | ||
const LOCAL_CONFIG_KEY = 'elastic_apm_config' | ||
/** | ||
* Default configs used on top of extensible configs from ConfigService | ||
*/ | ||
const KEYWORD_LIMIT = 1024 | ||
const SERVER_URL_PREFIX = '/intake/v2/rum/events' | ||
const BROWSER_RESPONSIVENESS_INTERVAL = 500 | ||
const BROWSER_RESPONSIVENESS_BUFFER = 3 | ||
const SIMILAR_SPAN_TO_TRANSACTION_RATIO = 0.05 | ||
export { | ||
@@ -129,3 +142,2 @@ SCHEDULE, | ||
USER_TIMING_THRESHOLD, | ||
KEYWORD_LIMIT, | ||
TRANSACTION_START, | ||
@@ -140,3 +152,11 @@ TRANSACTION_END, | ||
AFTER_EVENT, | ||
LOCAL_CONFIG_KEY | ||
LOCAL_CONFIG_KEY, | ||
HTTP_REQUEST_TYPE, | ||
KEYWORD_LIMIT, | ||
SERVER_URL_PREFIX, | ||
BROWSER_RESPONSIVENESS_INTERVAL, | ||
BROWSER_RESPONSIVENESS_BUFFER, | ||
SIMILAR_SPAN_TO_TRANSACTION_RATIO, | ||
TEMPORARY_TYPE, | ||
TRANSACTION_TYPE_ORDER | ||
} |
@@ -29,2 +29,3 @@ /** | ||
import { SCHEDULE, INVOKE, FETCH } from '../constants' | ||
import { scheduleMicroTask } from '../utils' | ||
@@ -70,3 +71,2 @@ export function patchFetch(callback) { | ||
url, | ||
args, | ||
aborted: false | ||
@@ -91,7 +91,6 @@ } | ||
promise.then( | ||
function(response) { | ||
response => { | ||
resolve(response) | ||
// invokeTask in the next execution cycle to let the promise resolution complete | ||
Promise.resolve().then(() => { | ||
scheduleMicroTask(() => { | ||
task.data.response = response | ||
@@ -101,5 +100,5 @@ invokeTask(task) | ||
}, | ||
function(error) { | ||
error => { | ||
reject(error) | ||
Promise.resolve().then(() => { | ||
scheduleMicroTask(() => { | ||
task.data.error = error | ||
@@ -106,0 +105,0 @@ invokeTask(task) |
@@ -72,5 +72,3 @@ /** | ||
task.state = INVOKE | ||
if (!task.ignore) { | ||
callback(INVOKE, task) | ||
} | ||
callback(INVOKE, task) | ||
} | ||
@@ -81,9 +79,5 @@ | ||
task.state = SCHEDULE | ||
if (!task.ignore) { | ||
callback(SCHEDULE, task) | ||
} | ||
const data = task.data | ||
const target = data.target | ||
// remove existing event listener | ||
const listener = target[XHR_LISTENER] | ||
callback(SCHEDULE, task) | ||
const { aborted, target } = task.data | ||
if (!oriAddListener) { | ||
@@ -94,2 +88,4 @@ oriAddListener = target[ADD_EVENT_LISTENER_STR] | ||
// remove existing event listener | ||
const listener = target[XHR_LISTENER] | ||
if (listener) { | ||
@@ -123,6 +119,8 @@ oriRemoveListener.call(target, READY_STATE_CHANGE, listener) | ||
if (target.readyState === target.DONE) { | ||
// sometimes on some browsers XMLHttpRequest will fire onreadystatechange with | ||
// readyState=4 multiple times, so we need to check task state here | ||
/** | ||
* On some browsers XMLHttpRequest will fire onreadystatechange with | ||
* readyState=4 multiple times, so we need to check task state here | ||
*/ | ||
if ( | ||
!data.aborted && | ||
!aborted && | ||
XMLHttpRequest[XHR_SCHEDULED] && | ||
@@ -136,3 +134,5 @@ task.state === SCHEDULE | ||
}) | ||
/** | ||
* Register event listeners for readystatechange and load events | ||
*/ | ||
oriAddListener.call(target, READY_STATE_CHANGE, newListener) | ||
@@ -145,5 +145,2 @@ oriAddListener.call(target, LOAD, newListener) | ||
} | ||
var result = sendNative.apply(target, data.args) | ||
XMLHttpRequest[XHR_SCHEDULED] = true | ||
return result | ||
} | ||
@@ -165,5 +162,7 @@ | ||
function(self, args) { | ||
self[XHR_METHOD] = args[0] | ||
self[XHR_URL] = args[1] | ||
self[XHR_SYNC] = args[2] === false | ||
if (!self[XHR_IGNORE]) { | ||
self[XHR_METHOD] = args[0] | ||
self[XHR_URL] = args[1] | ||
self[XHR_SYNC] = args[2] === false | ||
} | ||
return openNative.apply(self, args) | ||
@@ -178,2 +177,6 @@ } | ||
function(self, args) { | ||
if (self[XHR_IGNORE]) { | ||
return sendNative.apply(self, args) | ||
} | ||
const task = { | ||
@@ -183,3 +186,2 @@ source: XMLHTTPREQUEST, | ||
type: 'macroTask', | ||
ignore: self[XHR_IGNORE], | ||
data: { | ||
@@ -190,8 +192,8 @@ target: self, | ||
url: self[XHR_URL], | ||
args, | ||
aborted: false | ||
} | ||
} | ||
var result = scheduleTask(task) | ||
scheduleTask(task) | ||
const result = sendNative.apply(self, args) | ||
XMLHttpRequest[XHR_SCHEDULED] = true | ||
if (self[XHR_SYNC]) { | ||
@@ -209,9 +211,11 @@ invokeTask(task) | ||
function(self, args) { | ||
const task = self[XHR_TASK] | ||
if (task && typeof task.type === 'string') { | ||
// If the XHR has already been aborted, do nothing. | ||
if (task.data && task.data.aborted) { | ||
return | ||
if (!self[XHR_IGNORE]) { | ||
const task = self[XHR_TASK] | ||
if (task && typeof task.type === 'string') { | ||
// If the XHR has already been aborted, do nothing. | ||
if (task.data && task.data.aborted) { | ||
return | ||
} | ||
clearTask(task) | ||
} | ||
clearTask(task) | ||
} | ||
@@ -218,0 +222,0 @@ return abortNative.apply(self, args) |
@@ -53,2 +53,9 @@ /** | ||
const DESTINATION_MODEL = { | ||
address: [KEYWORD_LIMIT], | ||
service: { | ||
'*': [KEYWORD_LIMIT, true] | ||
} | ||
} | ||
const CONTEXT_MODEL = { | ||
@@ -67,2 +74,3 @@ user: { | ||
}, | ||
destination: DESTINATION_MODEL, | ||
/** Transactions */ | ||
@@ -179,3 +187,4 @@ response: RESPONSE_MODEL | ||
ERROR_MODEL, | ||
METADATA_MODEL | ||
METADATA_MODEL, | ||
RESPONSE_MODEL | ||
} |
@@ -49,2 +49,16 @@ /** | ||
/** | ||
* Add default ports for other protocols(ws, wss) after | ||
* RUM agent starts instrumenting those | ||
*/ | ||
function isDefaultPort(port, protocol) { | ||
switch (protocol) { | ||
case 'http:': | ||
return port === '80' | ||
case 'https:': | ||
return port === '443' | ||
} | ||
return true | ||
} | ||
/** | ||
* Order of the RULES are very important | ||
@@ -62,3 +76,3 @@ * | ||
['@', 'auth', 1], | ||
[NaN, 'host', undefined, 1] // | ||
[NaN, 'host', undefined, 1] | ||
] | ||
@@ -141,2 +155,22 @@ const PROTOCOL_REGEX = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i | ||
/** | ||
* Construct port and hostname from host | ||
* | ||
* Port numbers are not added for default ports of a given protocol | ||
* and hostname would match host when port is not present | ||
*/ | ||
this.hostname = this.host | ||
this.port = '' | ||
if (/:\d+$/.test(this.host)) { | ||
const value = this.host.split(':') | ||
const port = value.pop() | ||
const hostname = value.join(':') | ||
if (isDefaultPort(port, this.protocol)) { | ||
this.host = hostname | ||
} else { | ||
this.port = port | ||
} | ||
this.hostname = hostname | ||
} | ||
this.origin = | ||
@@ -143,0 +177,0 @@ this.protocol && this.host && this.protocol !== 'file:' |
@@ -33,7 +33,3 @@ /** | ||
} from '../common/constants' | ||
import { | ||
stripQueryStringFromUrl, | ||
getServerTimingInfo, | ||
getPageLoadMarks | ||
} from '../common/utils' | ||
import { stripQueryStringFromUrl, getPageLoadMarks } from '../common/utils' | ||
@@ -87,29 +83,2 @@ /** | ||
/** | ||
* Both Navigation and Resource timing level 2 exposes these below information | ||
* | ||
* for CORS requests without Timing-Allow-Origin header, transferSize & encodedBodySize will be 0 | ||
*/ | ||
function getResponseContext(perfTimingEntry) { | ||
const { | ||
transferSize, | ||
encodedBodySize, | ||
decodedBodySize, | ||
serverTiming | ||
} = perfTimingEntry | ||
const respContext = { | ||
transfer_size: transferSize, | ||
encoded_body_size: encodedBodySize, | ||
decoded_body_size: decodedBodySize | ||
} | ||
const serverTimingStr = getServerTimingInfo(serverTiming) | ||
if (serverTimingStr) { | ||
respContext.headers = { | ||
'server-timing': serverTimingStr | ||
} | ||
} | ||
return respContext | ||
} | ||
function createNavigationTimingSpans(timings, baseTime, trStart, trEnd) { | ||
@@ -129,4 +98,3 @@ const spans = [] | ||
span._start = start - baseTime | ||
span.ended = true | ||
span._end = end - baseTime | ||
span.end(end - baseTime) | ||
spans.push(span) | ||
@@ -145,14 +113,5 @@ } | ||
const span = new Span(spanName, kind) | ||
/** | ||
* Add context information for spans | ||
*/ | ||
span.addContext({ | ||
http: { | ||
url: name, | ||
response: getResponseContext(resourceTimingEntry) | ||
} | ||
}) | ||
span._start = startTime | ||
span.end() | ||
span._end = responseEnd | ||
span.end(responseEnd, { url: name, entry: resourceTimingEntry }) | ||
return span | ||
@@ -235,4 +194,3 @@ } | ||
span._start = startTime | ||
span.end() | ||
span._end = end | ||
span.end(end) | ||
@@ -339,15 +297,2 @@ userTimingSpans.push(span) | ||
) | ||
/** | ||
* Add transaction context information from performance navigation timing entry level 2 API | ||
*/ | ||
if (transaction.type === PAGE_LOAD) { | ||
let navigationEntry = perf.getEntriesByType('navigation') | ||
if (navigationEntry && navigationEntry.length > 0) { | ||
navigationEntry = navigationEntry[0] | ||
transaction.addContext({ | ||
response: getResponseContext(navigationEntry) | ||
}) | ||
} | ||
} | ||
} | ||
@@ -354,0 +299,0 @@ } |
@@ -29,5 +29,5 @@ /** | ||
isDtHeaderValid, | ||
merge, | ||
parseDtHeaderValue, | ||
stripQueryStringFromUrl | ||
stripQueryStringFromUrl, | ||
getDtHeaderValue | ||
} from '../common/utils' | ||
@@ -44,3 +44,7 @@ import Url from '../common/url' | ||
HISTORY, | ||
XMLHTTPREQUEST | ||
XMLHTTPREQUEST, | ||
HTTP_REQUEST_TYPE, | ||
BROWSER_RESPONSIVENESS_INTERVAL, | ||
BROWSER_RESPONSIVENESS_BUFFER, | ||
SIMILAR_SPAN_TO_TRANSACTION_RATIO | ||
} from '../common/constants' | ||
@@ -67,2 +71,3 @@ import { | ||
*/ | ||
this._configService.events.observe(TRANSACTION_END + AFTER_EVENT, tr => { | ||
@@ -121,5 +126,6 @@ const payload = this.createTransactionPayload(tr) | ||
if (event === SCHEDULE && task.data) { | ||
const requestUrl = new Url(task.data.url) | ||
const data = task.data | ||
const requestUrl = new Url(data.url) | ||
const spanName = | ||
task.data.method + | ||
data.method + | ||
' ' + | ||
@@ -129,2 +135,9 @@ (requestUrl.relative | ||
: stripQueryStringFromUrl(requestUrl.href)) | ||
if (!transactionService.getCurrentTransaction()) { | ||
transactionService.startTransaction(spanName, HTTP_REQUEST_TYPE, { | ||
managed: true | ||
}) | ||
} | ||
const span = transactionService.startSpan(spanName, 'external.http') | ||
@@ -142,32 +155,17 @@ const taskId = transactionService.addTask() | ||
checkSameOrigin(requestUrl.origin, dtOrigins) | ||
const target = task.data.target | ||
const target = data.target | ||
if (isDtEnabled && isSameOrigin && target) { | ||
this.injectDtHeader(span, target) | ||
} | ||
span.addContext({ | ||
http: { | ||
method: task.data.method, | ||
url: requestUrl.href | ||
} | ||
}) | ||
span.sync = task.data.sync | ||
task.data.span = span | ||
span.sync = data.sync | ||
data.span = span | ||
task.id = taskId | ||
} | ||
if (event === INVOKE && task.data && task.data.span) { | ||
if (typeof task.data.target.status !== 'undefined') { | ||
task.data.span.addContext({ | ||
http: { status_code: task.data.target.status } | ||
}) | ||
} else if (task.data.response) { | ||
task.data.span.addContext({ | ||
http: { status_code: task.data.response.status } | ||
}) | ||
} else if (event === INVOKE) { | ||
if (task.data && task.data.span) { | ||
task.data.span.end(null, task.data) | ||
} | ||
task.data.span.end() | ||
if (task.id) { | ||
transactionService.removeTask(task.id) | ||
} | ||
} | ||
if (event === INVOKE && task.id) { | ||
transactionService.removeTask(task.id) | ||
} | ||
} | ||
@@ -178,7 +176,3 @@ | ||
var headerName = configService.get('distributedTracingHeaderName') | ||
var headerValueCallback = configService.get( | ||
'distributedTracingHeaderValueCallback' | ||
) | ||
var headerValue = headerValueCallback(span) | ||
var headerValue = getDtHeaderValue(span) | ||
var isHeaderValid = isDtHeaderValid(headerValue) | ||
@@ -207,9 +201,2 @@ if (headerName && headerValue && isHeaderValid) { | ||
setTransactionContext(transaction) { | ||
var context = this._configService.get('context') | ||
if (context) { | ||
transaction.addContext(context) | ||
} | ||
} | ||
filterTransaction(tr) { | ||
@@ -237,5 +224,3 @@ const transactionDurationThreshold = this._configService.get( | ||
this._logginService.debug( | ||
`transaction(${tr.id}, ${ | ||
tr.name | ||
}) was discarded! Transaction duration (${duration}) is greater than the transactionDurationThreshold configuration (${transactionDurationThreshold})` | ||
`transaction(${tr.id}, ${tr.name}) was discarded! Transaction duration (${duration}) is greater than the transactionDurationThreshold configuration (${transactionDurationThreshold})` | ||
) | ||
@@ -246,13 +231,2 @@ } | ||
if (tr.spans.length === 0) { | ||
if (__DEV__) { | ||
this._logginService.debug( | ||
`transaction(${tr.id}, ${ | ||
tr.name | ||
}) was discarded! Transaction does not include any spans` | ||
) | ||
} | ||
return false | ||
} | ||
/** | ||
@@ -266,16 +240,7 @@ * In case of unsampled transaction, send only the transaction to apm server | ||
const browserResponsivenessInterval = this._configService.get( | ||
'browserResponsivenessInterval' | ||
) | ||
const checkBrowserResponsiveness = this._configService.get( | ||
'checkBrowserResponsiveness' | ||
) | ||
if (checkBrowserResponsiveness && tr.options.checkBrowserResponsiveness) { | ||
const buffer = this._configService.get('browserResponsivenessBuffer') | ||
if (tr.options.checkBrowserResponsiveness) { | ||
const wasBrowserResponsive = this.checkBrowserResponsiveness( | ||
tr, | ||
browserResponsivenessInterval, | ||
buffer | ||
BROWSER_RESPONSIVENESS_INTERVAL, | ||
BROWSER_RESPONSIVENESS_BUFFER | ||
) | ||
@@ -286,11 +251,7 @@ | ||
this._logginService.debug( | ||
`transaction(${tr.id}, ${ | ||
tr.name | ||
}) was discarded! Browser was not responsive enough during the transaction.`, | ||
`transaction(${tr.id}, ${tr.name}) was discarded! Browser was not responsive enough during the transaction.`, | ||
' duration:', | ||
duration, | ||
' browserResponsivenessCounter:', | ||
tr.browserResponsivenessCounter, | ||
'interval:', | ||
browserResponsivenessInterval | ||
tr.browserResponsivenessCounter | ||
) | ||
@@ -310,6 +271,5 @@ } | ||
if (this._configService.get('groupSimilarSpans')) { | ||
var similarSpanThreshold = this._configService.get('similarSpanThreshold') | ||
transaction.spans = this.groupSmallContinuouslySimilarSpans( | ||
transaction, | ||
similarSpanThreshold | ||
SIMILAR_SPAN_TO_TRANSACTION_RATIO | ||
) | ||
@@ -325,8 +285,5 @@ } | ||
}) | ||
this.setTransactionContext(transaction) | ||
} | ||
createTransactionDataModel(transaction) { | ||
const configContext = this._configService.get('context') | ||
const transactionStart = transaction._start | ||
@@ -352,4 +309,2 @@ | ||
const context = merge({}, configContext, transaction.context) | ||
const transactionData = { | ||
@@ -362,3 +317,3 @@ id: transaction.id, | ||
spans, | ||
context, | ||
context: transaction.context, | ||
marks: transaction.marks, | ||
@@ -425,12 +380,7 @@ breakdown: transaction.breakdownTimings, | ||
checkBrowserResponsiveness(transaction, interval, buffer) { | ||
var counter = transaction.browserResponsivenessCounter | ||
if (typeof interval === 'undefined' || typeof counter === 'undefined') { | ||
return true | ||
} | ||
const counter = transaction.browserResponsivenessCounter | ||
const duration = transaction.duration() | ||
const expectedCount = Math.floor(duration / interval) | ||
var duration = transaction.duration() | ||
var expectedCount = Math.floor(duration / interval) | ||
var wasBrowserResponsive = counter + buffer >= expectedCount | ||
return wasBrowserResponsive | ||
return counter + buffer >= expectedCount | ||
} | ||
@@ -437,0 +387,0 @@ } |
@@ -80,6 +80,6 @@ /** | ||
addContext(context) { | ||
if (!context) return | ||
addContext(...context) { | ||
if (context.length === 0) return | ||
this.ensureContext() | ||
merge(this.context, context) | ||
merge(this.context, ...context) | ||
} | ||
@@ -86,0 +86,0 @@ |
@@ -27,2 +27,3 @@ /** | ||
import SpanBase from './span-base' | ||
import { addSpanContext } from '../common/context' | ||
@@ -43,4 +44,9 @@ class Span extends SpanBase { | ||
} | ||
end(endTime, data) { | ||
super.end(endTime) | ||
addSpanContext(this, data) | ||
} | ||
} | ||
export default Span |
@@ -29,6 +29,14 @@ /** | ||
import { extend, getEarliestSpan, getLatestNonXHRSpan } from '../common/utils' | ||
import { PAGE_LOAD, NAME_UNKNOWN } from '../common/constants' | ||
import { captureNavigation } from './capture-navigation' | ||
import { | ||
PAGE_LOAD, | ||
NAME_UNKNOWN, | ||
TRANSACTION_START, | ||
TRANSACTION_END, | ||
BROWSER_RESPONSIVENESS_INTERVAL, | ||
TEMPORARY_TYPE, | ||
TRANSACTION_TYPE_ORDER | ||
} from '../common/constants' | ||
import { addTransactionContext } from '../common/context' | ||
import { __DEV__ } from '../env' | ||
import { TRANSACTION_START, TRANSACTION_END } from '../common/constants' | ||
@@ -40,16 +48,14 @@ class TransactionService { | ||
this.currentTransaction = undefined | ||
this.respIntervalId = undefined | ||
} | ||
ensureCurrentTransaction(options) { | ||
if (!options) { | ||
options = this.createOptions() | ||
} | ||
var tr = this.getCurrentTransaction() | ||
ensureCurrentTransaction(name, type, options) { | ||
let tr = this.getCurrentTransaction() | ||
if (tr) { | ||
return tr | ||
} else { | ||
options.canReuse = true | ||
options.managed = true | ||
return this.createTransaction(undefined, undefined, options) | ||
tr = new Transaction(name, type, options) | ||
this.setCurrentTransaction(tr) | ||
} | ||
return tr | ||
} | ||
@@ -67,28 +73,22 @@ | ||
createTransaction(name, type, options) { | ||
var tr = new Transaction(name, type, options) | ||
this.setCurrentTransaction(tr) | ||
if (options.checkBrowserResponsiveness) { | ||
this.startCounter(tr) | ||
ensureRespInterval(checkBrowserResponsiveness) { | ||
const clearRespInterval = () => { | ||
clearInterval(this.respIntervalId) | ||
this.respIntervalId = undefined | ||
} | ||
return tr | ||
} | ||
startCounter(transaction) { | ||
transaction.browserResponsivenessCounter = 0 | ||
var interval = this._config.get('browserResponsivenessInterval') | ||
if (typeof interval === 'undefined') { | ||
if (__DEV__) { | ||
this._logger.debug('browserResponsivenessInterval config is undefined!') | ||
if (checkBrowserResponsiveness) { | ||
if (typeof this.respIntervalId === 'undefined') { | ||
this.respIntervalId = setInterval(() => { | ||
let tr = this.getCurrentTransaction() | ||
if (tr) { | ||
tr.browserResponsivenessCounter++ | ||
} else { | ||
clearRespInterval() | ||
} | ||
}, BROWSER_RESPONSIVENESS_INTERVAL) | ||
} | ||
return | ||
} else if (typeof this.respIntervalId !== 'undefined') { | ||
clearRespInterval() | ||
} | ||
const id = setInterval(function() { | ||
if (transaction.ended) { | ||
window.clearInterval(id) | ||
} else { | ||
transaction.browserResponsivenessCounter++ | ||
} | ||
}, interval) | ||
} | ||
@@ -119,3 +119,3 @@ | ||
if (!tr) { | ||
tr = this.createTransaction(name, type, perfOptions) | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions) | ||
} else if (tr.canReuse() && perfOptions.canReuse) { | ||
@@ -136,7 +136,18 @@ /* | ||
/** | ||
* We want to keep the type in it's original value, therefore, | ||
* passing undefined as type. For example, in the case of a page-load | ||
* we want to keep the type but redefine the name to the first route. | ||
* We only update based precedence defined in TRANSACTION_TYPE_ORDER. | ||
* If either orders don't exist we also don't redefine the type. | ||
*/ | ||
tr.redefine(name, undefined, perfOptions) | ||
let redefineType | ||
let currentTypeOrder = TRANSACTION_TYPE_ORDER.indexOf(tr.type) | ||
let redefineTypeOrder = TRANSACTION_TYPE_ORDER.indexOf(type) | ||
if ( | ||
currentTypeOrder !== -1 && | ||
redefineTypeOrder !== -1 && | ||
redefineTypeOrder < currentTypeOrder | ||
) { | ||
redefineType = type | ||
} | ||
tr.redefine(name, redefineType, perfOptions) | ||
} else { | ||
@@ -150,3 +161,3 @@ if (__DEV__) { | ||
tr.end() | ||
tr = this.createTransaction(name, type, perfOptions) | ||
tr = this.ensureCurrentTransaction(name, type, perfOptions) | ||
} | ||
@@ -156,3 +167,3 @@ | ||
if (type === PAGE_LOAD) { | ||
if (tr.type === PAGE_LOAD) { | ||
tr.options.checkBrowserResponsiveness = false | ||
@@ -174,2 +185,4 @@ if (perfOptions.pageLoadTraceId) { | ||
this.ensureRespInterval(tr.options.checkBrowserResponsiveness) | ||
return tr | ||
@@ -201,3 +214,4 @@ } | ||
const { name, type } = tr | ||
if (this.shouldIgnoreTransaction(name)) { | ||
if (this.shouldIgnoreTransaction(name) || type === TEMPORARY_TYPE) { | ||
if (__DEV__) { | ||
@@ -210,2 +224,3 @@ this._logger.debug( | ||
} | ||
if (type === PAGE_LOAD) { | ||
@@ -237,2 +252,5 @@ /** | ||
} | ||
const configContext = this._config.get('context') | ||
addTransactionContext(tr, configContext) | ||
this._config.events.send(TRANSACTION_END, [tr]) | ||
@@ -309,3 +327,10 @@ if (__DEV__) { | ||
startSpan(name, type, options) { | ||
const tr = this.ensureCurrentTransaction() | ||
const tr = this.ensureCurrentTransaction( | ||
undefined, | ||
TEMPORARY_TYPE, | ||
this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
}) | ||
) | ||
@@ -325,3 +350,11 @@ if (tr) { | ||
addTask(taskId) { | ||
var tr = this.ensureCurrentTransaction() | ||
const tr = this.ensureCurrentTransaction( | ||
undefined, | ||
TEMPORARY_TYPE, | ||
this.createOptions({ | ||
canReuse: true, | ||
managed: true | ||
}) | ||
) | ||
if (tr) { | ||
@@ -328,0 +361,0 @@ var taskId = tr.addTask(taskId) |
@@ -34,3 +34,2 @@ /** | ||
extend, | ||
getPageMetadata, | ||
removeInvalidChars | ||
@@ -58,2 +57,3 @@ } from '../common/utils' | ||
this.sampled = Math.random() <= this.options.transactionSampleRate | ||
this.browserResponsivenessCounter = 0 | ||
} | ||
@@ -135,6 +135,2 @@ | ||
} | ||
const metadata = getPageMetadata() | ||
this.addContext(metadata) | ||
this.callOnEnd() | ||
@@ -141,0 +137,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
389261
110
11117