Skip to content

Commit

Permalink
Lazy loaded plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
amortemousque committed Sep 12, 2024
1 parent 0e1eafc commit 1e8ce41
Show file tree
Hide file tree
Showing 30 changed files with 784 additions and 173 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"connect-busboy": "1.0.0",
"cors": "2.8.5",
"emoji-name-map": "1.2.9",
"esbuild": "0.23.1",
"esbuild-plugin-tsc": "0.4.0",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-module-utils": "2.11.0",
Expand Down
42 changes: 21 additions & 21 deletions packages/core/src/domain/telemetry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const enum TelemetryService {
}

export interface Telemetry {
setContextProvider: (provider: () => Context) => void
onTelemetryEvent: (callback: (event: TelemetryEvent) => void) => void
observable: Observable<TelemetryEvent & Context>
enabled: boolean
}
Expand All @@ -59,7 +59,7 @@ let onRawTelemetryEventCollected = (event: RawTelemetryEvent) => {
}

export function startTelemetry(telemetryService: TelemetryService, configuration: Configuration): Telemetry {
let contextProvider: () => Context
let telemetryEventCallback: (event: TelemetryEvent) => void
const observable = new Observable<TelemetryEvent & Context>()
const alreadySentEvents = new Set<string>()

Expand Down Expand Up @@ -93,29 +93,29 @@ export function startTelemetry(telemetryService: TelemetryService, configuration
event: RawTelemetryEvent,
runtimeEnvInfo: RuntimeEnvInfo
): TelemetryEvent & Context {
return combine(
{
type: 'telemetry' as const,
date: timeStampNow(),
service: telemetryService,
version: __BUILD_ENV__SDK_VERSION__,
source: 'browser' as const,
_dd: {
format_version: 2 as const,
},
telemetry: combine(event, {
runtime_env: runtimeEnvInfo,
connectivity: getConnectivity(),
}),
experimental_features: arrayFrom(getExperimentalFeatures()),
const telemetryEvent = {
type: 'telemetry' as const,
date: timeStampNow(),
service: telemetryService,
version: __BUILD_ENV__SDK_VERSION__,
source: 'browser' as const,
_dd: {
format_version: 2 as const,
},
contextProvider !== undefined ? contextProvider() : {}
) as TelemetryEvent & Context
telemetry: combine(event, {
runtime_env: runtimeEnvInfo,
connectivity: getConnectivity(),
}),
experimental_features: arrayFrom(getExperimentalFeatures()),
} as TelemetryEvent & Context
telemetryEventCallback(telemetryEvent)

return telemetryEvent
}

return {
setContextProvider: (provider: () => Context) => {
contextProvider = provider
onTelemetryEvent: (callback: (event: TelemetryEvent) => void) => {
telemetryEventCallback = callback
},
observable,
enabled: telemetryEnabled,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"module": "es6",
"module": "es2020",
"rootDir": "./src/",
"outDir": "./esm/"
},
Expand Down
31 changes: 17 additions & 14 deletions packages/logs/src/domain/logsTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
isTelemetryReplicationAllowed,
addTelemetryConfiguration,
drainPreStartTelemetry,
assign,
} from '@datadog/browser-core'
import type { LogsConfiguration, LogsInitConfiguration } from './configuration'
import { getRUMInternalContext } from './contexts/rumInternalContext'
Expand All @@ -23,20 +24,22 @@ export function startLogsTelemetry(
session: LogsSessionManager
) {
const telemetry = startTelemetry(TelemetryService.LOGS, configuration)
telemetry.setContextProvider(() => ({
application: {
id: getRUMInternalContext()?.application_id,
},
session: {
id: session.findTrackedSession()?.id,
},
view: {
id: (getRUMInternalContext()?.view as Context)?.id,
},
action: {
id: (getRUMInternalContext()?.user_action as Context)?.id,
},
}))
telemetry.onTelemetryEvent((telemetryEvent) =>
assign(telemetryEvent, {
application: {
id: getRUMInternalContext()?.application_id,
},
session: {
id: session.findTrackedSession()?.id,
},
view: {
id: (getRUMInternalContext()?.view as Context)?.id,
},
action: {
id: (getRUMInternalContext()?.user_action as Context)?.id,
},
})
)
const cleanupTasks: Array<() => void> = []
if (canUseEventBridge()) {
const bridge = getEventBridge<'internal_telemetry', TelemetryEvent>()!
Expand Down
2 changes: 1 addition & 1 deletion packages/logs/tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"module": "es6",
"module": "es2020",
"rootDir": "./src/",
"outDir": "./esm/"
},
Expand Down
44 changes: 29 additions & 15 deletions packages/rum-core/src/boot/preStartRum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import type { ViewOptions } from '../domain/view/trackViews'
import type { DurationVital, CustomVitalsState } from '../domain/vital/vitalCollection'
import { startDurationVital, stopDurationVital } from '../domain/vital/vitalCollection'
import { fetchAndApplyRemoteConfiguration, serializeRumConfiguration } from '../domain/configuration'
import { callPluginsMethod } from '../domain/plugins'
import type { RumPublicApiOptions, Strategy } from './rumPublicApi'
import type { RumPlugin } from '../domain/plugins'
import { callPluginsMethod, loadLazyPlugins } from '../domain/plugins'
import type { RumPublicApi, RumPublicApiOptions, Strategy } from './rumPublicApi'
import type { StartRumResult } from './startRum'

export function createPreStartStrategy(
Expand All @@ -38,7 +39,8 @@ export function createPreStartStrategy(
doStartRum: (
configuration: RumConfiguration,
deflateWorker: DeflateWorker | undefined,
initialViewOptions?: ViewOptions
initialViewOptions?: ViewOptions,
plugins?: RumPlugin[]
) => StartRumResult
): Strategy {
const bufferApiCalls = createBoundedBuffer<StartRumResult>()
Expand All @@ -50,6 +52,7 @@ export function createPreStartStrategy(

let cachedInitConfiguration: RumInitConfiguration | undefined
let cachedConfiguration: RumConfiguration | undefined
let plugins: RumPlugin[] = []

const trackingConsentStateSubscription = trackingConsentState.observable.subscribe(tryStartRum)

Expand All @@ -76,12 +79,12 @@ export function createPreStartStrategy(
initialViewOptions = firstStartViewCall.options
}

const startRumResult = doStartRum(cachedConfiguration, deflateWorker, initialViewOptions)
const startRumResult = doStartRum(cachedConfiguration, deflateWorker, initialViewOptions, plugins)

bufferApiCalls.drain(startRumResult)
}

function doInit(initConfiguration: RumInitConfiguration) {
async function doInit(initConfiguration: RumInitConfiguration, publicApi: RumPublicApi) {
const eventBridgeAvailable = canUseEventBridge()
if (eventBridgeAvailable) {
initConfiguration = overrideInitConfigurationForBridge(initConfiguration)
Expand Down Expand Up @@ -121,11 +124,19 @@ export function createPreStartStrategy(
}
}

const lazyLoadedPlugins = await loadLazyPlugins(['action']) // look at how to pass the required plugins from the init config
if (!lazyLoadedPlugins) {
return
}
plugins = lazyLoadedPlugins.concat(configuration.plugins ?? [])

callPluginsMethod(plugins, 'onInit', { initConfiguration, publicApi })

cachedConfiguration = configuration
// Instrumuent fetch to track network requests
// This is needed in case the consent is not granted and some cutsomer
// library (Apollo Client) is storing uninstrumented fetch to be used later
// The subscrption is needed so that the instrumentation process is completed
// Instrument fetch to track network requests
// This is needed in case the consent is not granted and some customer
// library (Apollo Client) is storing un-instrumented fetch to be used later
// The subscription is needed so that the instrumentation process is completed
initFetchObservable().subscribe(noop)

trackingConsentState.tryToInit(configuration.trackingConsent)
Expand All @@ -137,7 +148,8 @@ export function createPreStartStrategy(
}

return {
init(initConfiguration, publicApi) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async init(initConfiguration, publicApi) {
if (!initConfiguration) {
display.error('Missing configuration')
return
Expand All @@ -156,16 +168,18 @@ export function createPreStartStrategy(
return
}

callPluginsMethod(initConfiguration.betaPlugins, 'onInit', { initConfiguration, publicApi })

if (
initConfiguration.remoteConfigurationId &&
isExperimentalFeatureEnabled(ExperimentalFeature.REMOTE_CONFIGURATION)
) {
fetchAndApplyRemoteConfiguration(initConfiguration, doInit)
} else {
doInit(initConfiguration)
const overriddenConfiguration = await fetchAndApplyRemoteConfiguration(initConfiguration)
if (!overriddenConfiguration) {
return
}
initConfiguration = overriddenConfiguration
}

await doInit(initConfiguration, publicApi)
},

get initConfiguration() {
Expand Down
5 changes: 3 additions & 2 deletions packages/rum-core/src/boot/rumPublicApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ export function makeRumPublicApi(
getCommonContext,
trackingConsentState,
customVitalsState,
(configuration, deflateWorker, initialViewOptions) => {
(configuration, deflateWorker, initialViewOptions, plugins) => {
if (isExperimentalFeatureEnabled(ExperimentalFeature.UPDATE_VIEW_NAME)) {
/**
* Update View Name.
Expand Down Expand Up @@ -390,7 +390,8 @@ export function makeRumPublicApi(
? (streamId) => options.createDeflateEncoder!(configuration, deflateWorker, streamId)
: createIdentityEncoder,
trackingConsentState,
customVitalsState
customVitalsState,
plugins
)

recorderApi.onRumStart(
Expand Down
Loading

0 comments on commit 1e8ce41

Please sign in to comment.