-
Notifications
You must be signed in to change notification settings - Fork 162
✨ [RUM-8780] Make developer extension capable of injecting the browser SDK #3877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3573f90
4b6ee32
19b2379
f5f25cf
cee62a6
0252280
7f5c5da
fb2fd7e
5e9f9ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,13 @@ export const DEV_LOGS_URL = `${DEV_SERVER_ORIGIN}/datadog-logs.js` | |
| export const DEV_RUM_SLIM_URL = `${DEV_SERVER_ORIGIN}/datadog-rum-slim.js` | ||
| export const DEV_RUM_URL = `${DEV_SERVER_ORIGIN}/datadog-rum.js` | ||
|
|
||
| export const CDN_BASE_URL = 'https://www.datadoghq-browser-agent.com' | ||
| // This version corresponds to the major version of the Browser SDK and needs to be manually updated when bumping major versions | ||
| export const CDN_VERSION = 'v6' | ||
| export const CDN_RUM_URL = `${CDN_BASE_URL}/${CDN_VERSION}/datadog-rum.js` | ||
| export const CDN_RUM_SLIM_URL = `${CDN_BASE_URL}/${CDN_VERSION}/datadog-rum-slim.js` | ||
| export const CDN_LOGS_URL = `${CDN_BASE_URL}/${CDN_VERSION}/datadog-logs.js` | ||
|
Comment on lines
+9
to
+11
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like those constants aren't used |
||
|
|
||
| // To follow web-ui development, this version will need to be manually updated from time to time. | ||
| // When doing that, be sure to update types and implement any protocol changes. | ||
| export const PROD_REPLAY_SANDBOX_VERSION = '0.119.0' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| import type { Settings } from '../common/extension.types' | ||
| import { EventListeners } from '../common/eventListeners' | ||
| import { DEV_LOGS_URL, DEV_RUM_SLIM_URL, DEV_RUM_URL } from '../common/packagesUrlConstants' | ||
| import { CDN_BASE_URL, CDN_VERSION, DEV_LOGS_URL, DEV_RUM_SLIM_URL, DEV_RUM_URL } from '../common/packagesUrlConstants' | ||
| import { SESSION_STORAGE_SETTINGS_KEY } from '../common/sessionKeyConstant' | ||
| import { createLogger } from '../common/logger' | ||
|
|
||
| declare global { | ||
| interface Window extends EventTarget { | ||
|
|
@@ -11,6 +12,8 @@ declare global { | |
| } | ||
| } | ||
|
|
||
| const logger = createLogger('content-script-main') | ||
|
|
||
| interface SdkPublicApi { | ||
| [key: string]: (...args: any[]) => unknown | ||
| } | ||
|
|
@@ -22,7 +25,6 @@ function main() { | |
| } | ||
|
|
||
| sendEventsToExtension() | ||
|
|
||
| const settings = getSettings() | ||
|
|
||
| if ( | ||
|
|
@@ -47,9 +49,11 @@ function main() { | |
| overrideInitConfiguration(ddLogsGlobal, settings.logsConfigurationOverride) | ||
| } | ||
|
|
||
| if (settings.useDevBundles === 'npm') { | ||
| if (settings.injectionVariant === 'local-dev' && settings.useDevBundles === 'npm') { | ||
| injectDevBundle(settings.useRumSlim ? DEV_RUM_SLIM_URL : DEV_RUM_URL, ddRumGlobal) | ||
| injectDevBundle(DEV_LOGS_URL, ddLogsGlobal) | ||
| } else if (settings.injectionVariant === 'cdn' && settings.datadogMode) { | ||
| injectCdnBundle(settings) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -126,8 +130,7 @@ function loadSdkScriptFromURL(url: string) { | |
| xhr.open('GET', url, false) // `false` makes the request synchronous | ||
| xhr.send() | ||
| } catch (error) { | ||
| // eslint-disable-next-line no-console | ||
| console.error(`[DD Browser SDK extension] Error while loading ${url}:`, error) | ||
| logger.error(`Error while loading ${url}:`, error) | ||
| return | ||
| } | ||
| if (xhr.status === 200) { | ||
|
|
@@ -184,3 +187,109 @@ function instrumentGlobal(global: 'DD_RUM' | 'DD_LOGS') { | |
| function proxySdk(target: SdkPublicApi, root: SdkPublicApi) { | ||
| Object.assign(target, root) | ||
| } | ||
|
|
||
| function injectCdnBundle(settings: Settings) { | ||
| const injectWhenReady = () => { | ||
| if (settings.sdkInjectionType === 'RUM' || settings.sdkInjectionType === 'BOTH') { | ||
| const rumSite = (settings.rumConfigurationOverride as any)?.site as string | undefined | ||
| const rumUrl = getRumBundleUrl(settings.useRumSlim ? 'rum-slim' : 'rum', rumSite) | ||
| const rumConfig = | ||
| settings.rumConfigurationOverride || | ||
| (settings.datadogMode | ||
| ? { | ||
| applicationId: 'xxx', | ||
| clientToken: 'xxx', | ||
| site: 'datad0g.com', | ||
| allowedTrackingOrigins: [location.origin], | ||
| sessionReplaySampleRate: 100, | ||
| } | ||
BeltranBulbarellaDD marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| : null) | ||
| injectAndInitializeSDK(rumUrl, 'DD_RUM', rumConfig as any) | ||
| } | ||
|
|
||
| if (settings.sdkInjectionType === 'LOGS' || settings.sdkInjectionType === 'BOTH') { | ||
| const logsSite = (settings.logsConfigurationOverride as any)?.site as string | undefined | ||
| const logsUrl = getLogsBundleUrl(logsSite) | ||
| const logsConfig = | ||
| settings.logsConfigurationOverride || | ||
| (settings.datadogMode | ||
| ? { | ||
| clientToken: 'xxx', | ||
| site: 'datad0g.com', | ||
| allowedTrackingOrigins: [location.origin], | ||
| } | ||
| : null) | ||
| injectAndInitializeSDK(logsUrl, 'DD_LOGS', logsConfig as any) | ||
| } | ||
| } | ||
|
|
||
| if (document.readyState === 'loading') { | ||
| document.addEventListener('DOMContentLoaded', injectWhenReady, { once: true }) | ||
| } else { | ||
| injectWhenReady() | ||
| } | ||
| } | ||
|
|
||
| function getRumBundleUrl(bundle: 'rum' | 'rum-slim', site?: string): string { | ||
| const region = getCdnRegion(site) | ||
| return `${CDN_BASE_URL}/${region}/${CDN_VERSION}/datadog-${bundle}.js` | ||
| } | ||
|
|
||
| function getLogsBundleUrl(site?: string) { | ||
| const region = getCdnRegion(site) | ||
| return `${CDN_BASE_URL}/${region}/${CDN_VERSION}/datadog-logs.js` | ||
| } | ||
|
Comment on lines
+233
to
+241
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💬 suggestion: Just include us1 prod rum and logs. No need to worry about regions, staging, etc. |
||
|
|
||
| function getCdnRegion(site?: string) { | ||
| if (!site || site === 'datadoghq.com') { | ||
| return 'us1' | ||
| } | ||
| if (site === 'datadoghq.eu') { | ||
| return 'eu1' | ||
| } | ||
| if (site?.startsWith('us3.')) { | ||
| return 'us3' | ||
| } | ||
| if (site?.startsWith('us5.')) { | ||
| return 'us5' | ||
| } | ||
| if (site?.endsWith('datad0g.com')) { | ||
| return 'us3' | ||
| } | ||
|
Comment on lines
+256
to
+258
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔨 warning: this seems incorrect |
||
|
|
||
| return 'us1' | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can probably remove this, the thing is that I was getting 403 so this was the fallback. |
||
|
|
||
| function injectAndInitializeSDK(url: string, globalName: 'DD_RUM' | 'DD_LOGS', config: object | null) { | ||
| // If the SDK is already loaded, don't try to load it again | ||
| if (window[globalName]) { | ||
| logger.log(`${globalName} already exists, skipping injection`) | ||
| return | ||
| } | ||
|
|
||
| if (url.includes('datadoghq-browser-agent.com')) { | ||
| const script = document.createElement('script') | ||
| script.src = url | ||
| script.async = true | ||
| script.onload = () => { | ||
| if (config && window[globalName] && 'init' in window[globalName]) { | ||
| try { | ||
| window[globalName].init(config) | ||
| } catch (e) { | ||
| logger.error(`Error initializing ${globalName}:`, e) | ||
| } | ||
| } else { | ||
| logger.log(`${globalName} loaded. No init called (no config provided).`) | ||
| } | ||
| } | ||
| script.onerror = (e) => { | ||
| logger.error(`Error loading ${globalName} script:`, e) | ||
| } | ||
| try { | ||
| document.head.appendChild(script) | ||
| } catch (appendErr) { | ||
| logger.error('failed to append script to head, retrying on documentElement', appendErr) | ||
| document.documentElement.appendChild(script) | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔨 warning: The
settingsshould be redesigned to make it more explicit and ideally avoid forbidden states. Things that should be clarified at the settings level:useDevBundles: npmwon't work ifinjectionVariantis notcdn.datadogMode?injectionVariantandsdkInjectionTypejust by looking at property names?My suggestion: keep things simple. Always inject both RUM and Logs CDN bundles with a default config. If dev bundle override is enabled, those bundles will be overridden (including rum-slim override). If config override is enabled, the config will be overridden. No need to do anything at the injection level.
So in the end you have a single option,
inject: boolean. No need to enforcedatadogModeusage, people can use it it's fine.