From c5960a1709f69b202fcdf4e67a70c06fc5bc3518 Mon Sep 17 00:00:00 2001 From: Mel <97147377+MelissaAutumn@users.noreply.github.com> Date: Thu, 18 Jul 2024 08:49:19 -0700 Subject: [PATCH] Add some initial user metric collection points (#556) * Add some initial user metric collection points * Fix environment mapping on Sentry. --- frontend/package-lock.json | 29 ++++++++++++++++++++++ frontend/package.json | 2 ++ frontend/src/main.ts | 49 +++++++++++++++++++++++++++++++++++--- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index adf91eb54..2a57945d4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "@sentry/vue": "^8.13.0", "@tabler/icons-vue": "^3.7.0", "@tailwindcss/forms": "^0.5.3", + "@types/ua-parser-js": "^0.7.39", "@vitejs/plugin-vue": "^5.0.4", "@vueuse/components": "^10.4.1", "@vueuse/core": "^10.7.0", @@ -22,6 +23,7 @@ "pinia": "^2.1.6", "qalendar": "^3.7.0", "tailwindcss": "^3.4.3", + "ua-parser-js": "^1.0.38", "vite": "^5.0.13", "vue": "^3.2.13", "vue-i18n": "^9.2.2", @@ -2068,6 +2070,11 @@ "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", "dev": true }, + "node_modules/@types/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==" + }, "node_modules/@types/web-bluetooth": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", @@ -7623,6 +7630,28 @@ "node": ">=14.17" } }, + "node_modules/ua-parser-js": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/ufo": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 45bac7618..baad2205d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "@sentry/vue": "^8.13.0", "@tabler/icons-vue": "^3.7.0", "@tailwindcss/forms": "^0.5.3", + "@types/ua-parser-js": "^0.7.39", "@vitejs/plugin-vue": "^5.0.4", "@vueuse/components": "^10.4.1", "@vueuse/core": "^10.7.0", @@ -25,6 +26,7 @@ "pinia": "^2.1.6", "qalendar": "^3.7.0", "tailwindcss": "^3.4.3", + "ua-parser-js": "^1.0.38", "vite": "^5.0.13", "vue": "^3.2.13", "vue-i18n": "^9.2.2", diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 94fe26cfd..636955fef 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,6 +1,7 @@ // init app import App from '@/App.vue'; import { createApp } from 'vue'; +import { getPreferredTheme } from '@/utils'; // pinia state management import { createPinia } from 'pinia'; @@ -18,21 +19,34 @@ import '@/assets/styles/main.css'; // init sentry // eslint-disable-next-line import/no-extraneous-dependencies import * as Sentry from '@sentry/vue'; +import UAParser from 'ua-parser-js'; const app = createApp(App); +const useSentry = !!import.meta.env.VITE_SENTRY_DSN; -if (import.meta.env.VITE_SENTRY_DSN) { +// The modes we use -> short names for sorting +const environmentMap = { + // Development is used by vite in dev mode... + development: 'dev', + // We set these correctly :) + stage: 'stage', + prod: 'prod', +}; +const environment = environmentMap[import.meta.env.MODE] ?? 'unknown'; + +if (useSentry) { Sentry.init({ app, + environment, dsn: import.meta.env.VITE_SENTRY_DSN, integrations: [ Sentry.browserTracingIntegration({ // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled - tracePropagationTargets: ['localhost', 'stage.appointment.day'], router, }), Sentry.replayIntegration(), ], + // Performance Monitoring // Capture 100% of the transactions, reduce in production! tracesSampleRate: 1.0, @@ -43,12 +57,12 @@ if (import.meta.env.VITE_SENTRY_DSN) { // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where // errors occur. replaysOnErrorSampleRate: 1.0, + tracePropagationTargets: ['localhost:8080', 'stage.appointment.day'], }); } const pinia = createPinia(); app.use(pinia); - app.use(router); // init urls @@ -62,5 +76,34 @@ const loc = localStorage?.getItem('locale') ?? navigator.language; app.use(i18ninstance); useDayJS(app, loc); +if (useSentry) { + /** + * Metric collection for development purposes. + * This data will be used to help guide development, design, and user experience decisions. + */ + const parser = new UAParser(navigator.userAgent); + const browser = parser.getBrowser(); + const os = parser.getOS(); + const device = parser.getDevice(); + const deviceRes = `${window?.screen?.width ?? -1}x${window?.screen?.height ?? -1}`; + const effectiveDeviceRes = `${window?.screen?.availWidth ?? -1}x${window?.screen?.availHeight ?? -1}`; + + Sentry.metrics.increment('page_load', 1, { + tags: { + browser: browser.name, + browserVersion: `${browser.name}:${browser.version}`, + os: os.name, + osVersion: `${os.name}:${os.version}`, + device: device.model, + deviceModel: `${device.vendor}:${device.model}`, + resolution: deviceRes, + effectiveResolution: effectiveDeviceRes, + userAgent: navigator.userAgent, + locale: loc, + theme: getPreferredTheme(), + }, + }); +} + // ready? let's go! app.mount('#app');