Skip to content

Commit feb24d9

Browse files
committed
feat: Add VueRouterInstrumentation
1 parent 18041b3 commit feb24d9

File tree

5 files changed

+81
-6
lines changed

5 files changed

+81
-6
lines changed

packages/vue/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"rollup-plugin-terser": "^4.0.4",
4343
"rollup-plugin-typescript2": "^0.21.0",
4444
"typescript": "3.7.5",
45-
"vue": "^2.6"
45+
"vue": "^2.6",
46+
"vue-router": "^3.0.1"
4647
},
4748
"scripts": {
4849
"build": "run-p build:es5 build:esm build:bundle",

packages/vue/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ export {
2222
} from '@sentry/browser';
2323

2424
export { init } from './sdk';
25+
export { vueRouterInstrumentation } from './vuerouter';
2526

2627
createVueEventProcessor();

packages/vue/src/sdk.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export function init(
146146
tracing: false,
147147
...options,
148148
tracingOptions: {
149-
hooks: ['mount', 'update'],
149+
hooks: ['activate', 'mount', 'update'],
150150
timeout: 2000,
151151
trackComponents: false,
152152
...options.tracingOptions,
@@ -270,22 +270,23 @@ export class VueHelper {
270270
? this._options.tracingOptions.trackComponents.indexOf(name) > -1
271271
: this._options.tracingOptions.trackComponents;
272272

273-
if (!this._rootSpan || !shouldTrack) {
273+
const childOf = this._rootSpan || getActiveTransaction(getCurrentHub());
274+
275+
if (!childOf || !shouldTrack) {
274276
return;
275277
}
276278

277279
const now = timestampWithMs();
278280
const span = spans[operation];
279-
280281
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
281282
// However, on the second call (after), it'll be already in place.
282283
if (span) {
283284
span.finish();
284285
this._finishRootSpan(now);
285286
} else {
286287
vm.$once(`hook:${hook}`, () => {
287-
if (this._rootSpan) {
288-
spans[operation] = this._rootSpan.startChild({
288+
if (childOf) {
289+
spans[operation] = childOf.startChild({
289290
description: `Vue <${name}>`,
290291
op: operation,
291292
});
@@ -332,6 +333,7 @@ export class VueHelper {
332333
// We should always finish the span, only should pop activity if using @sentry/apm
333334
if (this._rootSpan) {
334335
this._rootSpan.finish(timestamp);
336+
this._rootSpan = undefined;
335337
}
336338
}, this._options.tracingOptions.timeout);
337339
}

packages/vue/src/vuerouter.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { captureException } from '@sentry/browser';
2+
import { Transaction, TransactionContext } from '@sentry/types';
3+
import VueRouter from 'vue-router';
4+
5+
export type Action = 'PUSH' | 'REPLACE' | 'POP';
6+
7+
export type Location = {
8+
pathname: string;
9+
action?: Action;
10+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11+
} & Record<string, any>;
12+
13+
export type VueRouterInstrumentation = <T extends Transaction>(
14+
startTransaction: (context: TransactionContext) => T | undefined,
15+
startTransactionOnPageLoad?: boolean,
16+
startTransactionOnLocationChange?: boolean,
17+
) => void;
18+
19+
let firstLoad = true;
20+
21+
/**
22+
* Creates routing instrumentation for Vue Router v2
23+
*
24+
* @param router The Vue Router instance that is used
25+
*/
26+
export function vueRouterInstrumentation(router: VueRouter): VueRouterInstrumentation {
27+
return (
28+
startTransaction: (context: TransactionContext) => Transaction | undefined,
29+
startTransactionOnPageLoad: boolean = true,
30+
startTransactionOnLocationChange: boolean = true,
31+
) => {
32+
router.onError(error => captureException(error));
33+
34+
const tags = {
35+
'routing.instrumentation': 'vue-router',
36+
};
37+
router.beforeEach((to, _from, next) => {
38+
const data = {
39+
params: to.params,
40+
query: to.query,
41+
};
42+
43+
if (startTransactionOnPageLoad && firstLoad) {
44+
startTransaction({
45+
name: to.name || to.path,
46+
op: 'pageload',
47+
tags,
48+
data,
49+
});
50+
firstLoad = false;
51+
next();
52+
return;
53+
}
54+
if (startTransactionOnLocationChange && !firstLoad) {
55+
startTransaction({
56+
name: to.name || to.matched[0].path || to.path,
57+
op: 'navigation',
58+
tags,
59+
data,
60+
});
61+
next();
62+
return;
63+
}
64+
});
65+
};
66+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19083,6 +19083,11 @@ void-elements@^2.0.0:
1908319083
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
1908419084
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
1908519085

19086+
vue-router@^3.0.1:
19087+
version "3.4.9"
19088+
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.9.tgz#c016f42030ae2932f14e4748b39a1d9a0e250e66"
19089+
integrity sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA==
19090+
1908619091
vue@^2.6:
1908719092
version "2.6.12"
1908819093
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"

0 commit comments

Comments
 (0)