From 5a49a46caaee533628bbe4101394ca33d25b6ce7 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 10:53:42 +0200 Subject: [PATCH 1/8] Add support for Datadog Real User Monitoring (RUM) --- airbyte-webapp/package-lock.json | 53 +++++++++++++++++++++++++++++ airbyte-webapp/package.json | 5 ++- airbyte-webapp/src/config/types.ts | 4 +++ airbyte-webapp/src/index.tsx | 3 ++ airbyte-webapp/src/utils/datadog.ts | 29 ++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 airbyte-webapp/src/utils/datadog.ts diff --git a/airbyte-webapp/package-lock.json b/airbyte-webapp/package-lock.json index 3e520af63247..12dbb3e0b9ac 100644 --- a/airbyte-webapp/package-lock.json +++ b/airbyte-webapp/package-lock.json @@ -8,6 +8,7 @@ "name": "airbyte-webapp", "version": "0.40.14", "dependencies": { + "@datadog/browser-rum": "^4.21.2", "@floating-ui/react-dom": "^1.0.0", "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/free-brands-svg-icons": "^6.1.1", @@ -2498,6 +2499,36 @@ "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==", "dev": true }, + "node_modules/@datadog/browser-core": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-4.21.2.tgz", + "integrity": "sha512-o3UvCPBF0OdCInCbiC9j79K0F7/wThARZFq8+wnAOitZu64VT5XNpHFQqFP+9c+zzcxmwlTIINHmWLdkpKEECg==" + }, + "node_modules/@datadog/browser-rum": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-4.21.2.tgz", + "integrity": "sha512-qvC7sRrZ5yy7siCHeGPnBsM6sKoU+jc1YGy/5WgRSs24WUt9trgBoRcVR1KwU/aK8xn6hUOKRdEIxkrss5JaiA==", + "dependencies": { + "@datadog/browser-core": "4.21.2", + "@datadog/browser-rum-core": "4.21.2" + }, + "peerDependencies": { + "@datadog/browser-logs": "4.21.2" + }, + "peerDependenciesMeta": { + "@datadog/browser-logs": { + "optional": true + } + } + }, + "node_modules/@datadog/browser-rum-core": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-4.21.2.tgz", + "integrity": "sha512-8hNiNygHY8Jt2APtm4nvciGyRKIEniaupe7Uj5Bq6OFZIFNgf6qj88bRXwOdPsP9ksBNNK18Hol1oI4EdxdkkQ==", + "dependencies": { + "@datadog/browser-core": "4.21.2" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -49338,6 +49369,28 @@ "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==", "dev": true }, + "@datadog/browser-core": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-4.21.2.tgz", + "integrity": "sha512-o3UvCPBF0OdCInCbiC9j79K0F7/wThARZFq8+wnAOitZu64VT5XNpHFQqFP+9c+zzcxmwlTIINHmWLdkpKEECg==" + }, + "@datadog/browser-rum": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-4.21.2.tgz", + "integrity": "sha512-qvC7sRrZ5yy7siCHeGPnBsM6sKoU+jc1YGy/5WgRSs24WUt9trgBoRcVR1KwU/aK8xn6hUOKRdEIxkrss5JaiA==", + "requires": { + "@datadog/browser-core": "4.21.2", + "@datadog/browser-rum-core": "4.21.2" + } + }, + "@datadog/browser-rum-core": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-4.21.2.tgz", + "integrity": "sha512-8hNiNygHY8Jt2APtm4nvciGyRKIEniaupe7Uj5Bq6OFZIFNgf6qj88bRXwOdPsP9ksBNNK18Hol1oI4EdxdkkQ==", + "requires": { + "@datadog/browser-core": "4.21.2" + } + }, "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", diff --git a/airbyte-webapp/package.json b/airbyte-webapp/package.json index 7354e7bc034e..a6fa2a1a9db4 100644 --- a/airbyte-webapp/package.json +++ b/airbyte-webapp/package.json @@ -24,6 +24,7 @@ "validate-links": "ts-node --skip-project ./scripts/validate-links.ts" }, "dependencies": { + "@datadog/browser-rum": "^4.21.2", "@floating-ui/react-dom": "^1.0.0", "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/free-brands-svg-icons": "^6.1.1", @@ -162,7 +163,9 @@ }, "jest": { "transformIgnorePatterns": [], - "snapshotSerializers": ["./scripts/classname-serializer.js"], + "snapshotSerializers": [ + "./scripts/classname-serializer.js" + ], "coveragePathIgnorePatterns": [ ".stories.tsx" ] diff --git a/airbyte-webapp/src/config/types.ts b/airbyte-webapp/src/config/types.ts index cb97cee2f51a..387d8e51e21d 100644 --- a/airbyte-webapp/src/config/types.ts +++ b/airbyte-webapp/src/config/types.ts @@ -6,6 +6,10 @@ declare global { AIRBYTE_VERSION?: string; API_URL?: string; CLOUD?: string; + REACT_APP_DATADOG_APPLICATION_ID: string; + REACT_APP_DATADOG_CLIENT_TOKEN: string; + REACT_APP_DATADOG_SITE: string; + REACT_APP_DATADOG_SERVICE: string; REACT_APP_SENTRY_DSN?: string; REACT_APP_WEBAPP_TAG?: string; REACT_APP_INTERCOM_APP_ID?: string; diff --git a/airbyte-webapp/src/index.tsx b/airbyte-webapp/src/index.tsx index 84e3678e5f54..3a4015460e12 100644 --- a/airbyte-webapp/src/index.tsx +++ b/airbyte-webapp/src/index.tsx @@ -5,6 +5,7 @@ import ReactDOM from "react-dom"; import "react-reflex/styles.css"; import { isCloudApp } from "utils/app"; +import { loadDatadogRum } from "utils/datadog"; import { loadOsano } from "utils/dataPrivacy"; import "./globals"; @@ -17,6 +18,8 @@ Sentry.init({ tracesSampleRate: 1.0, // may need to adjust this in the future }); +loadDatadogRum(); + // In Cloud load the Osano script (GDPR consent tool before anything else) if (isCloudApp()) { loadOsano(); diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts new file mode 100644 index 000000000000..6e93563c10bc --- /dev/null +++ b/airbyte-webapp/src/utils/datadog.ts @@ -0,0 +1,29 @@ +import { datadogRum } from "@datadog/browser-rum"; + +export const loadDatadogRum = () => { + const applicationId = process.env.REACT_APP_DATADOG_APPLICATION_ID ?? window.REACT_APP_DATADOG_APPLICATION_ID; + if (!applicationId) { + return; + } + + const clientToken = process.env.REACT_APP_DATADOG_CLIENT_TOKEN ?? window.REACT_APP_DATADOG_CLIENT_TOKEN; + const site = process.env.REACT_APP_DATADOG_SITE ?? window.REACT_APP_DATADOG_SITE; + const service = process.env.REACT_APP_DATADOG_SERVICE ?? window.REACT_APP_DATADOG_SERVICE; + const version = window.AIRBYTE_VERSION; + + datadogRum.init({ + applicationId, + clientToken, + site, + service, + version, + sampleRate: 100, + sessionReplaySampleRate: 0, + trackInteractions: false, + trackResources: true, + trackLongTasks: true, + defaultPrivacyLevel: "mask-user-input", + }); + + datadogRum.startSessionReplayRecording(); +}; From 1be2e8b461700b245d91a88fec336ace00673444 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 10:55:01 +0200 Subject: [PATCH 2/8] Move sentry init to its own util --- airbyte-webapp/src/index.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/airbyte-webapp/src/index.tsx b/airbyte-webapp/src/index.tsx index 3a4015460e12..cfa01bdd80e3 100644 --- a/airbyte-webapp/src/index.tsx +++ b/airbyte-webapp/src/index.tsx @@ -1,5 +1,3 @@ -import * as Sentry from "@sentry/react"; -import { Integrations } from "@sentry/tracing"; import { lazy, Suspense } from "react"; import ReactDOM from "react-dom"; @@ -7,17 +5,11 @@ import "react-reflex/styles.css"; import { isCloudApp } from "utils/app"; import { loadDatadogRum } from "utils/datadog"; import { loadOsano } from "utils/dataPrivacy"; +import { initSentry } from "utils/sentry"; import "./globals"; -// We do not follow default config approach since we want to init sentry asap -Sentry.init({ - dsn: process.env.REACT_APP_SENTRY_DSN || window.REACT_APP_SENTRY_DSN, - release: process.env.REACT_APP_WEBAPP_TAG || window.REACT_APP_WEBAPP_TAG || "dev", - integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // may need to adjust this in the future -}); - +initSentry(); loadDatadogRum(); // In Cloud load the Osano script (GDPR consent tool before anything else) From fcdb3a713caaaaa7820f0e30c6ce36c35d11eb57 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 10:55:33 +0200 Subject: [PATCH 3/8] loadDatadogRum -> initDatadogRum --- airbyte-webapp/src/index.tsx | 4 ++-- airbyte-webapp/src/utils/datadog.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/airbyte-webapp/src/index.tsx b/airbyte-webapp/src/index.tsx index cfa01bdd80e3..f64717d7df4c 100644 --- a/airbyte-webapp/src/index.tsx +++ b/airbyte-webapp/src/index.tsx @@ -3,14 +3,14 @@ import ReactDOM from "react-dom"; import "react-reflex/styles.css"; import { isCloudApp } from "utils/app"; -import { loadDatadogRum } from "utils/datadog"; +import { initDatadogRum } from "utils/datadog"; import { loadOsano } from "utils/dataPrivacy"; import { initSentry } from "utils/sentry"; import "./globals"; initSentry(); -loadDatadogRum(); +initDatadogRum(); // In Cloud load the Osano script (GDPR consent tool before anything else) if (isCloudApp()) { diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts index 6e93563c10bc..f0a474a6b93c 100644 --- a/airbyte-webapp/src/utils/datadog.ts +++ b/airbyte-webapp/src/utils/datadog.ts @@ -1,6 +1,6 @@ import { datadogRum } from "@datadog/browser-rum"; -export const loadDatadogRum = () => { +export const initDatadogRum = () => { const applicationId = process.env.REACT_APP_DATADOG_APPLICATION_ID ?? window.REACT_APP_DATADOG_APPLICATION_ID; if (!applicationId) { return; From 117cc3d1d36adea3ec3bd722f590d6da6e055562 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 10:56:07 +0200 Subject: [PATCH 4/8] Move comment back to app index --- airbyte-webapp/src/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/airbyte-webapp/src/index.tsx b/airbyte-webapp/src/index.tsx index f64717d7df4c..46946397c00c 100644 --- a/airbyte-webapp/src/index.tsx +++ b/airbyte-webapp/src/index.tsx @@ -9,6 +9,7 @@ import { initSentry } from "utils/sentry"; import "./globals"; +// We do not follow default config approach since we want to init sentry/datadog asap initSentry(); initDatadogRum(); From 6bd8c8b5cfea8b8472d18c98fc6bad15d11a7200 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 11:16:56 +0200 Subject: [PATCH 5/8] Lazy load Sentry and Datadog --- airbyte-webapp/src/index.tsx | 8 ++++---- airbyte-webapp/src/utils/datadog.ts | 6 +++--- airbyte-webapp/src/utils/sentry.ts | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 airbyte-webapp/src/utils/sentry.ts diff --git a/airbyte-webapp/src/index.tsx b/airbyte-webapp/src/index.tsx index 46946397c00c..751cd8a448c4 100644 --- a/airbyte-webapp/src/index.tsx +++ b/airbyte-webapp/src/index.tsx @@ -3,15 +3,15 @@ import ReactDOM from "react-dom"; import "react-reflex/styles.css"; import { isCloudApp } from "utils/app"; -import { initDatadogRum } from "utils/datadog"; +import { loadDatadog } from "utils/datadog"; import { loadOsano } from "utils/dataPrivacy"; -import { initSentry } from "utils/sentry"; +import { loadSentry } from "utils/sentry"; import "./globals"; // We do not follow default config approach since we want to init sentry/datadog asap -initSentry(); -initDatadogRum(); +loadSentry(); +loadDatadog(); // In Cloud load the Osano script (GDPR consent tool before anything else) if (isCloudApp()) { diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts index f0a474a6b93c..4971d4f9e3b0 100644 --- a/airbyte-webapp/src/utils/datadog.ts +++ b/airbyte-webapp/src/utils/datadog.ts @@ -1,11 +1,11 @@ -import { datadogRum } from "@datadog/browser-rum"; - -export const initDatadogRum = () => { +export const loadDatadog = async (): Promise => { const applicationId = process.env.REACT_APP_DATADOG_APPLICATION_ID ?? window.REACT_APP_DATADOG_APPLICATION_ID; if (!applicationId) { return; } + const { datadogRum } = await import("@datadog/browser-rum"); + const clientToken = process.env.REACT_APP_DATADOG_CLIENT_TOKEN ?? window.REACT_APP_DATADOG_CLIENT_TOKEN; const site = process.env.REACT_APP_DATADOG_SITE ?? window.REACT_APP_DATADOG_SITE; const service = process.env.REACT_APP_DATADOG_SERVICE ?? window.REACT_APP_DATADOG_SERVICE; diff --git a/airbyte-webapp/src/utils/sentry.ts b/airbyte-webapp/src/utils/sentry.ts new file mode 100644 index 000000000000..b6c7725a3807 --- /dev/null +++ b/airbyte-webapp/src/utils/sentry.ts @@ -0,0 +1,18 @@ +export const loadSentry = async (): Promise => { + const dsn = process.env.REACT_APP_SENTRY_DSN ?? window.REACT_APP_SENTRY_DSN; + if (!dsn) { + return; + } + + const [Sentry, { Integrations }] = await Promise.all([import("@sentry/react"), import("@sentry/tracing")]); + + const release = process.env.REACT_APP_WEBAPP_TAG ?? window.REACT_APP_WEBAPP_TAG ?? "dev"; + const integrations = [new Integrations.BrowserTracing()]; + + Sentry.init({ + dsn, + release, + integrations, + tracesSampleRate: 1.0, + }); +}; From 5ab31a0a92ffa5396953c001fbf006413ce53436 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 11:31:12 +0200 Subject: [PATCH 6/8] Update version value for Datadog to match Sentry --- airbyte-webapp/src/utils/datadog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts index 4971d4f9e3b0..99d41479288d 100644 --- a/airbyte-webapp/src/utils/datadog.ts +++ b/airbyte-webapp/src/utils/datadog.ts @@ -9,7 +9,7 @@ export const loadDatadog = async (): Promise => { const clientToken = process.env.REACT_APP_DATADOG_CLIENT_TOKEN ?? window.REACT_APP_DATADOG_CLIENT_TOKEN; const site = process.env.REACT_APP_DATADOG_SITE ?? window.REACT_APP_DATADOG_SITE; const service = process.env.REACT_APP_DATADOG_SERVICE ?? window.REACT_APP_DATADOG_SERVICE; - const version = window.AIRBYTE_VERSION; + const version = process.env.REACT_APP_WEBAPP_TAG ?? window.REACT_APP_WEBAPP_TAG ?? "dev"; datadogRum.init({ applicationId, From b2976f96f512d23d8ebed93384c759ca3353816d Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 17:05:51 +0200 Subject: [PATCH 7/8] Switch process.env with window for sentry and datadog init --- airbyte-webapp/src/utils/datadog.ts | 10 +++++----- airbyte-webapp/src/utils/sentry.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts index 99d41479288d..66cd7ec5bf26 100644 --- a/airbyte-webapp/src/utils/datadog.ts +++ b/airbyte-webapp/src/utils/datadog.ts @@ -1,15 +1,15 @@ export const loadDatadog = async (): Promise => { - const applicationId = process.env.REACT_APP_DATADOG_APPLICATION_ID ?? window.REACT_APP_DATADOG_APPLICATION_ID; + const applicationId = window.REACT_APP_DATADOG_APPLICATION_ID ?? process.env.REACT_APP_DATADOG_APPLICATION_ID; if (!applicationId) { return; } const { datadogRum } = await import("@datadog/browser-rum"); - const clientToken = process.env.REACT_APP_DATADOG_CLIENT_TOKEN ?? window.REACT_APP_DATADOG_CLIENT_TOKEN; - const site = process.env.REACT_APP_DATADOG_SITE ?? window.REACT_APP_DATADOG_SITE; - const service = process.env.REACT_APP_DATADOG_SERVICE ?? window.REACT_APP_DATADOG_SERVICE; - const version = process.env.REACT_APP_WEBAPP_TAG ?? window.REACT_APP_WEBAPP_TAG ?? "dev"; + const clientToken = window.REACT_APP_DATADOG_CLIENT_TOKEN ?? process.env.REACT_APP_DATADOG_CLIENT_TOKEN; + const site = window.REACT_APP_DATADOG_SITE ?? process.env.REACT_APP_DATADOG_SITE; + const service = window.REACT_APP_DATADOG_SERVICE ?? process.env.REACT_APP_DATADOG_SERVICE; + const version = window.REACT_APP_WEBAPP_TAG ?? process.env.REACT_APP_WEBAPP_TAG ?? "dev"; datadogRum.init({ applicationId, diff --git a/airbyte-webapp/src/utils/sentry.ts b/airbyte-webapp/src/utils/sentry.ts index b6c7725a3807..2e9515d6bd88 100644 --- a/airbyte-webapp/src/utils/sentry.ts +++ b/airbyte-webapp/src/utils/sentry.ts @@ -1,12 +1,12 @@ export const loadSentry = async (): Promise => { - const dsn = process.env.REACT_APP_SENTRY_DSN ?? window.REACT_APP_SENTRY_DSN; + const dsn = window.REACT_APP_SENTRY_DSN ?? process.env.REACT_APP_SENTRY_DSN; if (!dsn) { return; } const [Sentry, { Integrations }] = await Promise.all([import("@sentry/react"), import("@sentry/tracing")]); - const release = process.env.REACT_APP_WEBAPP_TAG ?? window.REACT_APP_WEBAPP_TAG ?? "dev"; + const release = window.REACT_APP_WEBAPP_TAG ?? process.env.REACT_APP_WEBAPP_TAG ?? "dev"; const integrations = [new Integrations.BrowserTracing()]; Sentry.init({ From e59a5828ecc6cc8a3f4416af8cd71c27a9013e51 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Tue, 11 Oct 2022 17:17:52 +0200 Subject: [PATCH 8/8] Remove import optimizations from Sentry and Datadog --- airbyte-webapp/src/utils/datadog.ts | 5 ++--- airbyte-webapp/src/utils/sentry.ts | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/airbyte-webapp/src/utils/datadog.ts b/airbyte-webapp/src/utils/datadog.ts index 66cd7ec5bf26..4fa03ed73500 100644 --- a/airbyte-webapp/src/utils/datadog.ts +++ b/airbyte-webapp/src/utils/datadog.ts @@ -1,11 +1,10 @@ -export const loadDatadog = async (): Promise => { +import { datadogRum } from "@datadog/browser-rum"; +export const loadDatadog = (): void => { const applicationId = window.REACT_APP_DATADOG_APPLICATION_ID ?? process.env.REACT_APP_DATADOG_APPLICATION_ID; if (!applicationId) { return; } - const { datadogRum } = await import("@datadog/browser-rum"); - const clientToken = window.REACT_APP_DATADOG_CLIENT_TOKEN ?? process.env.REACT_APP_DATADOG_CLIENT_TOKEN; const site = window.REACT_APP_DATADOG_SITE ?? process.env.REACT_APP_DATADOG_SITE; const service = window.REACT_APP_DATADOG_SERVICE ?? process.env.REACT_APP_DATADOG_SERVICE; diff --git a/airbyte-webapp/src/utils/sentry.ts b/airbyte-webapp/src/utils/sentry.ts index 2e9515d6bd88..d8f63339f019 100644 --- a/airbyte-webapp/src/utils/sentry.ts +++ b/airbyte-webapp/src/utils/sentry.ts @@ -1,11 +1,12 @@ -export const loadSentry = async (): Promise => { +import * as Sentry from "@sentry/react"; +import { Integrations } from "@sentry/tracing"; + +export const loadSentry = (): void => { const dsn = window.REACT_APP_SENTRY_DSN ?? process.env.REACT_APP_SENTRY_DSN; if (!dsn) { return; } - const [Sentry, { Integrations }] = await Promise.all([import("@sentry/react"), import("@sentry/tracing")]); - const release = window.REACT_APP_WEBAPP_TAG ?? process.env.REACT_APP_WEBAPP_TAG ?? "dev"; const integrations = [new Integrations.BrowserTracing()];