Browse Source

feat(replays): Enable Sentry Replays for `session-replay-sdk` flag (#37761)

This removes `@sentry/rrweb` in favor of `@sentry/replay`. The integration will only be enabled for the `session-replay-sdk` feature flag which is currently limited to the ET team. We will slowly expand to other employees.
Billy Vong 2 years ago
parent
commit
0cbdfe40ab

+ 1 - 1
package.json

@@ -40,7 +40,7 @@
     "@sentry/node": "7.8.0",
     "@sentry/react": "7.8.0",
     "@sentry/release-parser": "^1.3.1",
-    "@sentry/rrweb": "^0.3.3",
+    "@sentry/replay": "0.5.2",
     "@sentry/tracing": "7.8.0",
     "@sentry/utils": "7.8.0",
     "@testing-library/jest-dom": "^5.16.4",

+ 3 - 23
static/app/bootstrap/initializeSdk.tsx

@@ -1,11 +1,10 @@
 import {browserHistory, createRoutes, match} from 'react-router';
 import {ExtraErrorData} from '@sentry/integrations';
 import * as Sentry from '@sentry/react';
-import SentryRRWeb from '@sentry/rrweb';
 import {Integrations} from '@sentry/tracing';
 import {_browserPerformanceTimeOriginMode} from '@sentry/utils';
 
-import {DISABLE_RR_WEB, SENTRY_RELEASE_VERSION, SPA_DSN} from 'sentry/constants';
+import {SENTRY_RELEASE_VERSION, SPA_DSN} from 'sentry/constants';
 import {Config} from 'sentry/types';
 import {
   initializeMeasureAssetsTimeout,
@@ -25,11 +24,7 @@ const SPA_MODE_ALLOW_URLS = [
  * having routing instrumentation in order to have a smaller bundle size.
  * (e.g.  `static/views/integrationPipeline`)
  */
-function getSentryIntegrations(
-  sentryConfig: Config['sentryConfig'],
-  hasReplays: boolean = false,
-  routes?: Function
-) {
+function getSentryIntegrations(sentryConfig: Config['sentryConfig'], routes?: Function) {
   const extraTracingOrigins = SPA_DSN
     ? SPA_MODE_ALLOW_URLS
     : [...sentryConfig?.whitelistUrls];
@@ -59,19 +54,7 @@ function getSentryIntegrations(
       ...partialTracingOptions,
     }),
   ];
-  if (hasReplays) {
-    // eslint-disable-next-line no-console
-    console.log('[sentry] Instrumenting session with rrweb');
 
-    // TODO(ts): The type returned by SentryRRWeb seems to be somewhat
-    // incompatible. It's a newer plugin, so this can be expected, but we
-    // should fix.
-    integrations.push(
-      new SentryRRWeb({
-        checkoutEveryNms: 60 * 1000, // 60 seconds
-      }) as any
-    );
-  }
   return integrations;
 }
 
@@ -85,8 +68,6 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
   const {apmSampling, sentryConfig, userIdentity} = config;
   const tracesSampleRate = apmSampling ?? 0;
 
-  const hasReplays = userIdentity?.isStaff && !DISABLE_RR_WEB;
-
   Sentry.init({
     ...sentryConfig,
     /**
@@ -101,7 +82,7 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
      */
     release: SENTRY_RELEASE_VERSION ?? sentryConfig?.release,
     allowUrls: SPA_DSN ? SPA_MODE_ALLOW_URLS : sentryConfig?.whitelistUrls,
-    integrations: getSentryIntegrations(sentryConfig, hasReplays, routes),
+    integrations: getSentryIntegrations(sentryConfig, routes),
     tracesSampleRate,
     /**
      * There is a bug in Safari, that causes `AbortError` when fetch is
@@ -129,7 +110,6 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
   if (window.__SENTRY__VERSION) {
     Sentry.setTag('sentry_version', window.__SENTRY__VERSION);
   }
-  Sentry.setTag('rrweb.active', hasReplays ? 'yes' : 'no');
 
   LongTaskObserver.startPerformanceObserver();
   initializeMeasureAssetsTimeout();

+ 36 - 0
static/app/components/sentryReplayInit.tsx

@@ -0,0 +1,36 @@
+import {useEffect} from 'react';
+
+import {Organization} from 'sentry/types';
+
+async function initSentryReplays() {
+  const {SentryReplay} = await import('@sentry/replay');
+
+  const replays = new SentryReplay({
+    stickySession: true,
+  });
+
+  replays.setup();
+}
+
+/**
+ * Load the Sentry Replay integration based on the feature flag.
+ *
+ *  Can't use `useOrganization` because it throws on
+ * `/settings/account/api/auth-token/` because organization is not *immediately*
+ * set in context
+ */
+export function SentryReplayInit({organization}: {organization: Organization | null}) {
+  useEffect(() => {
+    if (!organization) {
+      return;
+    }
+
+    if (!organization.features.includes('session-replay-sdk')) {
+      return;
+    }
+
+    initSentryReplays();
+  }, [organization]);
+
+  return null;
+}

+ 0 - 1
static/app/constants/index.tsx

@@ -262,7 +262,6 @@ export const DISCOVER2_DOCS_URL = 'https://docs.sentry.io/product/discover-queri
 
 export const IS_ACCEPTANCE_TEST = !!process.env.IS_ACCEPTANCE_TEST;
 export const NODE_ENV = process.env.NODE_ENV;
-export const DISABLE_RR_WEB = !!process.env.DISABLE_RR_WEB;
 export const SPA_DSN = process.env.SPA_DSN;
 export const SENTRY_RELEASE_VERSION = process.env.SENTRY_RELEASE_VERSION;
 

+ 2 - 0
static/app/views/organizationContextContainer.tsx

@@ -11,6 +11,7 @@ import Alert from 'sentry/components/alert';
 import LoadingError from 'sentry/components/loadingError';
 import LoadingTriangle from 'sentry/components/loadingTriangle';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
+import {SentryReplayInit} from 'sentry/components/sentryReplayInit';
 import Sidebar from 'sentry/components/sidebar';
 import {ORGANIZATION_FETCH_ERROR_TYPES} from 'sentry/constants';
 import {t} from 'sentry/locale';
@@ -328,6 +329,7 @@ class OrganizationContextContainer extends Component<Props, State> {
       <SentryDocumentTitle noSuffix title={this.getTitle()}>
         <OrganizationContext.Provider value={this.state.organization}>
           <div className="app">
+            <SentryReplayInit organization={this.state.organization} />
             {this.state.hooks}
             {this.renderSidebar()}
             {this.props.children}

+ 42 - 4
yarn.lock

@@ -2255,6 +2255,25 @@
     "@sentry/utils" "7.8.0"
     tslib "^1.9.3"
 
+"@sentry/core@^7.7.0":
+  version "7.7.0"
+  resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.7.0.tgz#1a2d477897552d179380f7c54c7d81a4e98ea29a"
+  integrity sha512-Z15ACiuiFINFcK4gbMrnejLn4AVjKBPJOWKrrmpIe8mh+Y9diOuswt5mMUABs+jhpZvqht3PBLLGBL0WMsYMYA==
+  dependencies:
+    "@sentry/hub" "7.7.0"
+    "@sentry/types" "7.7.0"
+    "@sentry/utils" "7.7.0"
+    tslib "^1.9.3"
+
+"@sentry/hub@7.7.0":
+  version "7.7.0"
+  resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.7.0.tgz#9ad3471cf5ecaf1a9d3a3a04ca2515ffec9e2c09"
+  integrity sha512-6gydK234+a0nKhBRDdIJ7Dp42CaiW2juTiHegUVDq+482balVzbZyEAmESCmuzKJhx5BhlCElVxs/cci1NjMpg==
+  dependencies:
+    "@sentry/types" "7.7.0"
+    "@sentry/utils" "7.7.0"
+    tslib "^1.9.3"
+
 "@sentry/hub@7.8.0":
   version "7.8.0"
   resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.8.0.tgz#ba261fff11f389511b2a2f7ccd4466dc781d1a8d"
@@ -2304,10 +2323,16 @@
   resolved "https://registry.yarnpkg.com/@sentry/release-parser/-/release-parser-1.3.1.tgz#0ab8be23fd494d80dd0e4ec8ae5f3d13f805b13d"
   integrity sha512-/dGpCq+j3sJhqQ14RNEEL45Ot/rgq3jAlZDD/8ufeqq+W8p4gUhSrbGWCRL82NEIWY9SYwxYXGXjRcVPSHiA1Q==
 
-"@sentry/rrweb@^0.3.3":
-  version "0.3.3"
-  resolved "https://registry.yarnpkg.com/@sentry/rrweb/-/rrweb-0.3.3.tgz#cbc55e6a99f88e98616a7141210b3f4544427b2a"
-  integrity sha512-GaPHoCpzUMW+SCyK/ZMxzZJb4snWE2VSj8vYddHcPnboIG2xH+V4XEGxpKbEXc5s0WGDuhPTQv1j1Q44/gt/kA==
+"@sentry/replay@0.5.2":
+  version "0.5.2"
+  resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-0.5.2.tgz#2f586624cde6cef85d5873a13e68947168708757"
+  integrity sha512-hHk/BTt338XfGhioXdpYGogX5ffxVBnC/MEVvk9MRu7iTl2hCsngvAVRLw7PtT+ywvIYMiPF6iRAfaunPlJD/g==
+  dependencies:
+    "@sentry/core" "^7.7.0"
+    "@sentry/types" "^7.7.0"
+    "@sentry/utils" "^7.7.0"
+    pako "^2.0.4"
+    rrweb "^1.1.3"
 
 "@sentry/tracing@7.8.0":
   version "7.8.0"
@@ -2319,11 +2344,24 @@
     "@sentry/utils" "7.8.0"
     tslib "^1.9.3"
 
+"@sentry/types@7.7.0", "@sentry/types@^7.7.0":
+  version "7.7.0"
+  resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.7.0.tgz#dd6bd3d119d7efea0e85dbaa4b17de1c22b63c7a"
+  integrity sha512-4x8O7uerSGLnYC10krHl9t8h7xXHn5FextqKYbTCXCnx2hC8D+9lz8wcbQAFo0d97wiUYqI8opmEgFVGx7c5hQ==
+
 "@sentry/types@7.8.0":
   version "7.8.0"
   resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.8.0.tgz#009ee9c53b474030a6b14025a8904b6260d57484"
   integrity sha512-X9D2jlcAzbJdCHA+eCMv2t5HI9769Qpx48e+sZiK7Oasy1jwQtqzQRaiI9fy/zZ+p7Fyerj/4WjW/E2c4dJ63w==
 
+"@sentry/utils@7.7.0", "@sentry/utils@^7.7.0":
+  version "7.7.0"
+  resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.7.0.tgz#013e3097c4268a76de578494c7df999635fb0ad4"
+  integrity sha512-fD+ROSFpeJlK7bEvUT2LOW7QqgjBpXJwVISKZ0P2fuzclRC3KoB2pbZgBM4PXMMTiSzRGWhvfRRjBiBvQJBBJQ==
+  dependencies:
+    "@sentry/types" "7.7.0"
+    tslib "^1.9.3"
+
 "@sentry/utils@7.8.0":
   version "7.8.0"
   resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.8.0.tgz#ed9b9a607fa51125a48140b1ea836603202d3cc2"