Skip to content

Commit 9118d31

Browse files
committed
feat: Auto tracking XHR
1 parent 00dcc7d commit 9118d31

File tree

2 files changed

+112
-32
lines changed

2 files changed

+112
-32
lines changed

packages/integrations/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ export { RewriteFrames } from './rewriteframes';
1010
export { SessionTiming } from './sessiontiming';
1111
export { Tracing } from './tracing';
1212
export { Transaction } from './transaction';
13-
export { TransactionActivity } from './transactionactivity';
13+
export { TransactionActivity, TransactionActivityHandlers } from './transactionactivity';
1414
export { Vue } from './vue';

packages/integrations/src/transactionactivity.ts

+111-31
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class TransactionActivity implements Integration {
3939
private static _enabled?: boolean;
4040

4141
/** JSDoc */
42-
private static _options: TransactionActivityOptions;
42+
public static options: TransactionActivityOptions;
4343

4444
/**
4545
* Returns current hub.
@@ -65,7 +65,7 @@ export class TransactionActivity implements Integration {
6565
startTransactionOnLocationChange: true,
6666
tracesSampleRate: 1,
6767
};
68-
TransactionActivity._options = {
68+
TransactionActivity.options = {
6969
...defaults,
7070
..._options,
7171
};
@@ -84,32 +84,6 @@ export class TransactionActivity implements Integration {
8484
op: 'pageload',
8585
sampled: true,
8686
});
87-
88-
// tslint:disable: no-unsafe-any
89-
if (global.history && this._options && this._options.patchHistory) {
90-
// tslint:disable-next-line: typedef only-arrow-functions
91-
(function(history: any) {
92-
const pushState = history.pushState;
93-
// tslint:disable-next-line: typedef only-arrow-functions
94-
history.pushState = function(state: any) {
95-
if (typeof history.onpushstate === 'function') {
96-
history.onpushstate({ state });
97-
}
98-
// ... whatever else you want to do
99-
// maybe call onhashchange e.handler
100-
return pushState.apply(history, arguments);
101-
};
102-
})(global.history);
103-
global.onpopstate = (history as any).onpushstate = (_state: any) => {
104-
if (this._options && this._options.startTransactionOnLocationChange) {
105-
TransactionActivity.startIdleTransaction(`${global.location.href}`, {
106-
op: 'navigation',
107-
sampled: true,
108-
});
109-
}
110-
};
111-
}
112-
// tslint:enable: no-unsafe-any
11387
}
11488

11589
/**
@@ -119,7 +93,7 @@ export class TransactionActivity implements Integration {
11993
if (TransactionActivity._enabled !== undefined) {
12094
return TransactionActivity._enabled;
12195
}
122-
TransactionActivity._enabled = Math.random() > TransactionActivity._options.tracesSampleRate ? false : true;
96+
TransactionActivity._enabled = Math.random() > TransactionActivity.options.tracesSampleRate ? false : true;
12397
return TransactionActivity._enabled;
12498
}
12599

@@ -169,7 +143,7 @@ export class TransactionActivity implements Integration {
169143
const id = TransactionActivity.pushActivity('idleTransactionStarted');
170144
setTimeout(() => {
171145
TransactionActivity.popActivity(id);
172-
}, (TransactionActivity._options && TransactionActivity._options.idleTimeout) || 100);
146+
}, (TransactionActivity.options && TransactionActivity.options.idleTimeout) || 100);
173147

174148
return span;
175149
}
@@ -244,10 +218,116 @@ export class TransactionActivity implements Integration {
244218
clearTimeout(TransactionActivity._debounce);
245219

246220
if (count === 0) {
247-
const timeout = TransactionActivity._options && TransactionActivity._options.idleTimeout;
221+
const timeout = TransactionActivity.options && TransactionActivity.options.idleTimeout;
248222
TransactionActivity._debounce = (setTimeout(() => {
249223
TransactionActivity.finishIdleTransaction();
250224
}, timeout) as any) as number;
251225
}
252226
}
253227
}
228+
229+
/**
230+
* Creates breadcrumbs from XHR API calls
231+
*/
232+
function xhrCallback(handlerData: { [key: string]: any }): void {
233+
// tslint:disable: no-unsafe-any
234+
if (handlerData.requestComplete && handlerData.xhr.__sentry_xhr_activity_id__) {
235+
TransactionActivity.popActivity(handlerData.xhr.__sentry_xhr_activity_id__);
236+
return;
237+
}
238+
// We only capture complete, non-sentry requests
239+
if (handlerData.xhr.__sentry_own_request__) {
240+
return;
241+
}
242+
243+
const xhr = handlerData.xhr.__sentry_xhr__;
244+
handlerData.xhr.__sentry_xhr_activity_id__ = TransactionActivity.pushActivity('xhr', {
245+
data: {
246+
request_data: xhr.data,
247+
},
248+
description: `${xhr.method} ${xhr.url}`,
249+
op: 'http',
250+
});
251+
// tslint:enable: no-unsafe-any
252+
}
253+
254+
/**
255+
* Creates breadcrumbs from fetch API calls
256+
*/
257+
// function fetchHandler(handlerData: { [key: string]: any }): void {
258+
// // We only capture complete fetch requests
259+
// if (!handlerData.requestComplete) {
260+
// return;
261+
// }
262+
263+
// const client = getCurrentHub().getClient<BrowserClient>();
264+
// const dsn = client && client.getDsn();
265+
266+
// if (dsn) {
267+
// const filterUrl = new API(dsn).getStoreEndpoint();
268+
// // if Sentry key appears in URL, don't capture it as a request
269+
// // but rather as our own 'sentry' type breadcrumb
270+
// if (
271+
// filterUrl &&
272+
// handlerData.fetchData.url.indexOf(filterUrl) !== -1 &&
273+
// handlerData.fetchData.method === 'POST' &&
274+
// handlerData.args[1] &&
275+
// handlerData.args[1].body
276+
// ) {
277+
// addSentryBreadcrumb(handlerData.args[1].body);
278+
// return;
279+
// }
280+
// }
281+
282+
// if (handlerData.error) {
283+
// getCurrentHub().addBreadcrumb(
284+
// {
285+
// category: 'fetch',
286+
// data: handlerData.fetchData,
287+
// level: Severity.Error,
288+
// type: 'http',
289+
// },
290+
// {
291+
// data: handlerData.error,
292+
// input: handlerData.args,
293+
// },
294+
// );
295+
// } else {
296+
// getCurrentHub().addBreadcrumb(
297+
// {
298+
// category: 'fetch',
299+
// data: handlerData.fetchData,
300+
// type: 'http',
301+
// },
302+
// {
303+
// input: handlerData.args,
304+
// response: handlerData.response,
305+
// },
306+
// );
307+
// }
308+
// }
309+
310+
/**
311+
* Creates transaction from navigation changes
312+
*/
313+
function historyCallback(_: { [key: string]: any }): void {
314+
if (TransactionActivity.options.startTransactionOnLocationChange) {
315+
TransactionActivity.startIdleTransaction(global.location.href, {
316+
op: 'navigation',
317+
sampled: true,
318+
});
319+
}
320+
}
321+
322+
const historyHandler = {
323+
callback: historyCallback,
324+
type: 'history',
325+
};
326+
327+
const xhrHandler = {
328+
callback: xhrCallback,
329+
type: 'xhr',
330+
};
331+
332+
// tslint:disable-next-line: variable-name
333+
export const TransactionActivityHandlers = [historyHandler, xhrHandler];

0 commit comments

Comments
 (0)