From 431620acac40dfe43d9c14f213539bba9c2a7c54 Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 5 Apr 2024 10:17:20 -0600 Subject: [PATCH 1/3] feat: Integrate Grafana Faro Adds the react integrations and Faro error boundary around the app and initializes the default tracing/web integrations Signed-off-by: John McBride --- .env | 6 + lib/utils/grafana.ts | 31 ++ npm-shrinkwrap.json | 745 ++++++++++++++++++++++++++++++++++++++++++- package.json | 3 + pages/_app.tsx | 70 ++-- 5 files changed, 821 insertions(+), 34 deletions(-) create mode 100644 lib/utils/grafana.ts diff --git a/.env b/.env index 721b39c1c..bac5a2bc0 100644 --- a/.env +++ b/.env @@ -9,6 +9,12 @@ NEXT_PUBLIC_STRIPE_SUB_CANCEL_URL=https://billing.stripe.com/p/login/test_bIY8xy NEXT_PUBLIC_OPENGRAPH_URL=https://beta.opengraph.opensauced.pizza/v1 SENTRY_DSN=https://3f5bb9023ff0407299dd22a6454558f9@o4504872488927232.ingest.sentry.io/4505082236960768 +# Grafana Faro web tracing and frontend observability +# should only send metric points from beta and prod deployments +NEXT_PUBLIC_FARO_COLLECTOR_URL="" +NEXT_PUBLIC_FARO_APP_NAME="OpenSauced App" +NEXT_PUBLIC_FARO_APP_ENVIRONMENT=local + # -------------- # For running the API local, use your devices localhost address: # diff --git a/lib/utils/grafana.ts b/lib/utils/grafana.ts new file mode 100644 index 000000000..1223b1a3c --- /dev/null +++ b/lib/utils/grafana.ts @@ -0,0 +1,31 @@ +import { getWebInstrumentations, initializeFaro, ReactIntegration } from "@grafana/faro-react"; +import { TracingInstrumentation } from "@grafana/faro-web-tracing"; + +export const initGrafanaFaro = () => { + const faro = initializeFaro({ + url: process.env.NEXT_PUBLIC_FARO_COLLECTOR_URL, + + app: { + name: process.env.NEXT_PUBLIC_FARO_APP_NAME, + version: "1.0.0", + environment: process.env.NEXT_PUBLIC_FARO_ENVIRONMENT, + }, + + instrumentations: [ + // load the mandatory web instrumentation + ...getWebInstrumentations(), + + // add tracing instrumentation which should include the React Profiler + new TracingInstrumentation(), + + new ReactIntegration({ + // In the future, we may choose to integrate with the router integration to + // get deeper metrics on matched routes, navigation types, etc. + // Reference: https://github.com/grafana/faro-web-sdk/tree/main/packages/react + // router: {} + }), + ], + }); + + return faro; +}; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 53af491ef..5fe3a9195 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -10,6 +10,9 @@ "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { + "@grafana/faro-react": "^1.5.1", + "@grafana/faro-web-sdk": "^1.5.1", + "@grafana/faro-web-tracing": "^1.5.1", "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.14", "@nivo/bar": "^0.83.0", @@ -3161,6 +3164,60 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" }, + "node_modules/@grafana/faro-core": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-core/-/faro-core-1.5.1.tgz", + "integrity": "sha512-85z70ry+atnZxdT/w33cl+/6LdOTyt4/vomKWOwk0kzQlJKcH5ll1be1SXL5RbpexbVpBrr09+7kre6+eZkgww==", + "dependencies": { + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/otlp-transformer": "^0.48.0" + } + }, + "node_modules/@grafana/faro-react": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-react/-/faro-react-1.5.1.tgz", + "integrity": "sha512-0/emKZ3OwRzvMUCLHESFgCqQ/yUizhVsosGlrFj+KFbovk8OYxtgtWEtnBFq4XsNSYm5BffVtvx43XNj9xCAFA==", + "dependencies": { + "@grafana/faro-web-sdk": "^1.5.1", + "@grafana/faro-web-tracing": "^1.5.1", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-router-dom": "^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@grafana/faro-web-sdk": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-web-sdk/-/faro-web-sdk-1.5.1.tgz", + "integrity": "sha512-vGv3xQp9/lI+LChCj1LLzYqCXZ0bPpZCFvNRYNmPU/5ARhZ03Oa2NzBFogHua57C0Xog04ln1BmnYRirpTeQ/w==", + "dependencies": { + "@grafana/faro-core": "^1.5.1", + "ua-parser-js": "^1.0.32", + "web-vitals": "^3.1.1" + } + }, + "node_modules/@grafana/faro-web-tracing": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-web-tracing/-/faro-web-tracing-1.5.1.tgz", + "integrity": "sha512-R6au2sFAD4kRzfv99BykKEeNXIgAUHTO9G2dVENHWpLvoheII731sg1C2STLWX2nfzNdDnAm9VetKqPUoF+YAg==", + "dependencies": { + "@grafana/faro-web-sdk": "^1.5.1", + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/context-zone": "^1.18.1", + "@opentelemetry/core": "^1.18.1", + "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", + "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation-document-load": "^0.35.0", + "@opentelemetry/instrumentation-fetch": "^0.48.0", + "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", + "@opentelemetry/otlp-transformer": "^0.48.0", + "@opentelemetry/resources": "^1.18.1", + "@opentelemetry/sdk-trace-web": "^1.18.1", + "@opentelemetry/semantic-conventions": "^1.18.1" + } + }, "node_modules/@headlessui/react": { "version": "1.7.8", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.8.tgz", @@ -5003,6 +5060,584 @@ "npm": ">=6" } }, + "node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.48.0.tgz", + "integrity": "sha512-1/aMiU4Eqo3Zzpfwu51uXssp5pzvHFObk8S9pKAiXb1ne8pvg1qxBQitYL1XUiAMEXFzgjaidYG2V6624DRhhw==", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-zone": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-zone/-/context-zone-1.23.0.tgz", + "integrity": "sha512-7piNTrpH+gZNMDDOHIJXCSwp0Xslh3R96HWH5HwXw+4PykR4+jVoXvd6jziQxudX9rFAfu2B64A10DHs4ZWrfA==", + "dependencies": { + "@opentelemetry/context-zone-peer-dep": "1.23.0", + "zone.js": "^0.11.0 || ^0.13.0 || ^0.14.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-zone-peer-dep": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-zone-peer-dep/-/context-zone-peer-dep-1.23.0.tgz", + "integrity": "sha512-3ia5w2y3CGHIhMSggttliGbeRBWclIyMMXdfRCcit1NHg1ocieA9qYxyUEetbOvPrQpoti3O3k+5eyQUv7r8nw==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "zone.js": "^0.10.2 || ^0.11.0 || ^0.13.0 || ^0.14.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.23.0.tgz", + "integrity": "sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.23.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.48.0.tgz", + "integrity": "sha512-QEZKbfWqXrbKVpr2PHd4KyKI0XVOhUYC+p2RPV8s+2K5QzZBE3+F9WlxxrXDfkrvGmpQAZytBoHQQYA3AGOtpw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/otlp-exporter-base": "0.48.0", + "@opentelemetry/otlp-transformer": "0.48.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz", + "integrity": "sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==", + "dependencies": { + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.35.0.tgz", + "integrity": "sha512-U3zQBjbAF0rm7GT7YJ8DPqgiCdBoshmld4c1pZe3tAGAMa5QPIjonIfSMSvJ2XMh6Nvi+8Rfe3XFCe0cuWIjsQ==", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/sdk-trace-base": "^1.0.0", + "@opentelemetry/sdk-trace-web": "^1.15.0", + "@opentelemetry/semantic-conventions": "^1.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.48.0.tgz", + "integrity": "sha512-y4Zw9VeUUMaowg3aXYZXcaUJQ7IKfpR6sjClrAQOJwWG8LYFpM6NIRSoAeJv/ShfxWWCPWC0P4zgXcKRqpURFQ==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", + "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.48.0.tgz", + "integrity": "sha512-YJ9d1sR28hcEVtP4/tHtPX5Hhu0w2LsAMp3M+75YGTHkkunsN8PwcY/1FcSHUP9xwy7Z2myQvT7fTpL3g4tn4A==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", + "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.48.0.tgz", + "integrity": "sha512-T4LJND+Ugl87GUONoyoQzuV9qCn4BFIPOnCH1biYqdGhc2JahjuLqVD9aefwLzGBW638iLAo88Lh68h2F1FLiA==", + "dependencies": { + "@opentelemetry/core": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.48.0.tgz", + "integrity": "sha512-yuoS4cUumaTK/hhxW3JUy3wl2U4keMo01cFDrUOmjloAdSSXvv1zyQ920IIH4lymp5Xd21Dj2/jq2LOro56TJg==", + "dependencies": { + "@opentelemetry/api-logs": "0.48.0", + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-logs": "0.48.0", + "@opentelemetry/sdk-metrics": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.23.0.tgz", + "integrity": "sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==", + "dependencies": { + "@opentelemetry/core": "1.23.0", + "@opentelemetry/semantic-conventions": "1.23.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.48.0.tgz", + "integrity": "sha512-lRcA5/qkSJuSh4ItWCddhdn/nNbVvnzM+cm9Fg1xpZUeTeozjJDBcHnmeKoOaWRnrGYBdz6UTY6bynZR9aBeAA==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.8.0", + "@opentelemetry/api-logs": ">=0.39.1" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz", + "integrity": "sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.21.0.tgz", + "integrity": "sha512-yrElGX5Fv0umzp8Nxpta/XqU71+jCAyaLk34GmBzNcrW43nqbrqvdPs4gj4MVy/HcTjr6hifCDCYA3rMkajxxA==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.23.0.tgz", + "integrity": "sha512-tx9N3hIkd6k567BeujBnpXYdhu3ptYVk0ZkhdcjyQ3I8ZDJ+/JkVtaVNLAuf8hp1buTqNDmxSipALMxEmK2fnw==", + "dependencies": { + "@opentelemetry/core": "1.23.0", + "@opentelemetry/sdk-trace-base": "1.23.0", + "@opentelemetry/semantic-conventions": "1.23.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.23.0.tgz", + "integrity": "sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==", + "dependencies": { + "@opentelemetry/core": "1.23.0", + "@opentelemetry/resources": "1.23.0", + "@opentelemetry/semantic-conventions": "1.23.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz", + "integrity": "sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==", + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -13361,6 +13996,11 @@ "@types/node": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz", + "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==" + }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", @@ -14307,7 +14947,6 @@ "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -14319,7 +14958,6 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, "peerDependencies": { "acorn": "^8" } @@ -15613,6 +16251,11 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", @@ -20722,6 +21365,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz", + "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -22616,8 +23270,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -23206,6 +23859,11 @@ "ufo": "^1.3.0" } }, + "node_modules/module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -25999,6 +26657,40 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.3.0.tgz", + "integrity": "sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==", + "dependencies": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/require-in-the-middle/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -26562,6 +27254,11 @@ "node": ">=8" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -28448,6 +29145,28 @@ "node": ">=8" } }, + "node_modules/ua-parser-js": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", + "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "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.3.2", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", @@ -29840,6 +30559,11 @@ "defaults": "^1.0.3" } }, + "node_modules/web-vitals": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -30454,6 +31178,19 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/zone.js": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.4.tgz", + "integrity": "sha512-NtTUvIlNELez7Q1DzKVIFZBzNb646boQMgpATo9z3Ftuu/gWvzxCW7jdjcUDoRGxRikrhVHB/zLXh1hxeJawvw==", + "dependencies": { + "tslib": "^2.3.0" + } + }, + "node_modules/zone.js/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/zrender": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.4.1.tgz", diff --git a/package.json b/package.json index b3c83c136..de575fe21 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,9 @@ "e2e:ui": "npm run e2e -- --ui" }, "dependencies": { + "@grafana/faro-react": "^1.5.1", + "@grafana/faro-web-sdk": "^1.5.1", + "@grafana/faro-web-tracing": "^1.5.1", "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.14", "@nivo/bar": "^0.83.0", diff --git a/pages/_app.tsx b/pages/_app.tsx index 1f542bf56..8d6948b8e 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -12,6 +12,7 @@ import NextNProgress from "nextjs-progressbar"; import posthog from "posthog-js"; import { PostHogProvider } from "posthog-js/react"; +import { FaroErrorBoundary, withFaroProfiler } from "@grafana/faro-react"; import { TipProvider } from "components/atoms/Tooltip/tooltip"; import { publicApiFetcher } from "lib/utils/public-api-fetcher"; @@ -25,6 +26,7 @@ import useSession from "lib/hooks/useSession"; import { FeatureFlag } from "lib/utils/server/feature-flags"; import { APP_CACHE_KEY } from "lib/utils/caching"; +import { initGrafanaFaro } from "lib/utils/grafana"; import type { AppProps } from "next/app"; // Clear any service workers present @@ -62,6 +64,12 @@ type ComponentWithPageLayout = AppProps & { }; function MyApp({ Component, pageProps }: ComponentWithPageLayout) { + useEffect(() => { + if (process.env.NEXT_PUBLIC_FARO_COLLECTOR_URL && process.env.NEXT_PUBLIC_FARO_APP_ENVIRONMENT != "local") { + initGrafanaFaro(); + } + }, []); + useSession(true); const router = useRouter(); const [seo, updateSEO] = useState(Component.SEO || {}); @@ -132,38 +140,40 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { return ( <> - - - - - - - - - - - - - {Component.PageLayout ? ( - + + + + + + + + + + + + + + {Component.PageLayout ? ( + + + + ) : ( - - ) : ( - - )} - - - - + )} + + + + + ); } -export default MyApp; +export default withFaroProfiler(MyApp); From 785e32786581ff7fc164a702d822f571c3dae797 Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 5 Apr 2024 11:48:03 -0600 Subject: [PATCH 2/3] fix: Add the package version to faro and useRef for getting initing faro Signed-off-by: John McBride --- lib/utils/grafana.ts | 14 ++++++---- pages/_app.tsx | 64 ++++++++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/lib/utils/grafana.ts b/lib/utils/grafana.ts index 1223b1a3c..be2bee183 100644 --- a/lib/utils/grafana.ts +++ b/lib/utils/grafana.ts @@ -1,13 +1,16 @@ import { getWebInstrumentations, initializeFaro, ReactIntegration } from "@grafana/faro-react"; import { TracingInstrumentation } from "@grafana/faro-web-tracing"; +// Get the current, runtime version of the App to surface to Faro +import packageJson from "../../package.json"; + export const initGrafanaFaro = () => { - const faro = initializeFaro({ + return initializeFaro({ url: process.env.NEXT_PUBLIC_FARO_COLLECTOR_URL, app: { name: process.env.NEXT_PUBLIC_FARO_APP_NAME, - version: "1.0.0", + version: packageJson.version, environment: process.env.NEXT_PUBLIC_FARO_ENVIRONMENT, }, @@ -19,13 +22,14 @@ export const initGrafanaFaro = () => { new TracingInstrumentation(), new ReactIntegration({ - // In the future, we may choose to integrate with the router integration to + // In the future, we may choose to integrate with the router instrumentation to // get deeper metrics on matched routes, navigation types, etc. + // Next/router doesn't seem to be supported which won't give us route metrics. + // // Reference: https://github.com/grafana/faro-web-sdk/tree/main/packages/react + // // router: {} }), ], }); - - return faro; }; diff --git a/pages/_app.tsx b/pages/_app.tsx index 8d6948b8e..34a86dc8a 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -3,7 +3,7 @@ import "../styles/globals.css"; import "react-loading-skeleton/dist/skeleton.css"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import Head from "next/head"; import { useRouter } from "next/router"; import { SessionContextProvider } from "@supabase/auth-helpers-react"; @@ -12,7 +12,7 @@ import NextNProgress from "nextjs-progressbar"; import posthog from "posthog-js"; import { PostHogProvider } from "posthog-js/react"; -import { FaroErrorBoundary, withFaroProfiler } from "@grafana/faro-react"; +import { Faro, FaroErrorBoundary, withFaroProfiler } from "@grafana/faro-react"; import { TipProvider } from "components/atoms/Tooltip/tooltip"; import { publicApiFetcher } from "lib/utils/public-api-fetcher"; @@ -64,9 +64,15 @@ type ComponentWithPageLayout = AppProps & { }; function MyApp({ Component, pageProps }: ComponentWithPageLayout) { + const faroRef = useRef(null); + useEffect(() => { - if (process.env.NEXT_PUBLIC_FARO_COLLECTOR_URL && process.env.NEXT_PUBLIC_FARO_APP_ENVIRONMENT != "local") { - initGrafanaFaro(); + if ( + process.env.NEXT_PUBLIC_FARO_COLLECTOR_URL && + process.env.NEXT_PUBLIC_FARO_APP_ENVIRONMENT != "local" && + !faroRef.current + ) { + faroRef.current = initGrafanaFaro(); } }, []); @@ -140,26 +146,26 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { return ( <> - - - - - - - - - - - - - + + + + + + + + + + + + + {Component.PageLayout ? ( @@ -167,11 +173,11 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { ) : ( )} - - - - - + + + + + ); } From 15a056772ba2a3acabdec54eb2a340191aaf37a4 Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 5 Apr 2024 15:25:51 -0600 Subject: [PATCH 3/3] chore: Small refactor and validated that a throwing an error is propagated up Signed-off-by: John McBride --- .env | 3 ++- lib/utils/grafana.ts | 6 ++++-- next.config.js | 3 +++ pages/_app.tsx | 50 ++++++++++++++++++++++---------------------- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/.env b/.env index bac5a2bc0..28a5b6b6b 100644 --- a/.env +++ b/.env @@ -10,7 +10,8 @@ NEXT_PUBLIC_OPENGRAPH_URL=https://beta.opengraph.opensauced.pizza/v1 SENTRY_DSN=https://3f5bb9023ff0407299dd22a6454558f9@o4504872488927232.ingest.sentry.io/4505082236960768 # Grafana Faro web tracing and frontend observability -# should only send metric points from beta and prod deployments +# should only be configured to send metric points from beta and prod deployments. +# For testing purposes, use a valid collector URL and set the environment to "beta" NEXT_PUBLIC_FARO_COLLECTOR_URL="" NEXT_PUBLIC_FARO_APP_NAME="OpenSauced App" NEXT_PUBLIC_FARO_APP_ENVIRONMENT=local diff --git a/lib/utils/grafana.ts b/lib/utils/grafana.ts index be2bee183..f85861e3f 100644 --- a/lib/utils/grafana.ts +++ b/lib/utils/grafana.ts @@ -16,13 +16,15 @@ export const initGrafanaFaro = () => { instrumentations: [ // load the mandatory web instrumentation - ...getWebInstrumentations(), + ...getWebInstrumentations({ + captureConsole: true, + }), // add tracing instrumentation which should include the React Profiler new TracingInstrumentation(), new ReactIntegration({ - // In the future, we may choose to integrate with the router instrumentation to + // In the future, we may choose to integrate with React router instrumentation to // get deeper metrics on matched routes, navigation types, etc. // Next/router doesn't seem to be supported which won't give us route metrics. // diff --git a/next.config.js b/next.config.js index 9ed78bf8d..e07d14ab2 100644 --- a/next.config.js +++ b/next.config.js @@ -24,6 +24,9 @@ const interests = [ /** @type {import('next').NextConfig} */ module.exports = { + experimental: { + instrumentationHook: true, + }, productionBrowserSourceMaps: true, reactStrictMode: true, images: { diff --git a/pages/_app.tsx b/pages/_app.tsx index 34a86dc8a..afa3e798a 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -146,26 +146,26 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { return ( <> - - - - - - - - - - - - - + + + + + + + + + + + + + {Component.PageLayout ? ( @@ -173,11 +173,11 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { ) : ( )} - - - - - + + + + + ); }