Skip to content

Commit

Permalink
Simplify configuration validation
Browse files Browse the repository at this point in the history
  • Loading branch information
amortemousque committed Jul 22, 2024
1 parent 6c184ba commit 7d552bd
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 79 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/domain/configuration/configuration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { RumEvent } from '../../../../rum-core/src'
import { EXHAUSTIVE_INIT_CONFIGURATION, SERIALIZED_EXHAUSTIVE_INIT_CONFIGURATION } from '../../../test'
import type { ExtractTelemetryConfiguration, MapInitConfigurationKey } from '../../../test'
import { DOCS_ORIGIN, display } from '../../tools/display'
import { DOCS_ORIGIN, MORE_DETAILS, display } from '../../tools/display'
import {
ExperimentalFeature,
isExperimentalFeatureEnabled,
Expand Down Expand Up @@ -209,7 +209,7 @@ describe('validateAndBuildConfiguration', () => {
it('should validate the site parameter', () => {
validateAndBuildConfiguration({ clientToken, site: 'foo.com' })
expect(displaySpy).toHaveBeenCalledOnceWith(
`Site should be a valid Datadog site. Learn more here: ${DOCS_ORIGIN}/getting_started/site/.`
`Site should be a valid Datadog site. ${MORE_DETAILS} ${DOCS_ORIGIN}/getting_started/site/.`
)
})
})
Expand Down
66 changes: 24 additions & 42 deletions packages/core/src/domain/configuration/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { catchUserErrors } from '../../tools/catchUserErrors'
import { DOCS_ORIGIN, display } from '../../tools/display'
import { DOCS_ORIGIN, MORE_DETAILS, display } from '../../tools/display'
import type { RawTelemetryConfiguration } from '../telemetry'
import type { Duration } from '../../tools/utils/timeUtils'
import { ONE_SECOND } from '../../tools/utils/timeUtils'
Expand Down Expand Up @@ -191,16 +191,28 @@ export interface Configuration extends TransportConfiguration {
messageBytesLimit: number
}

function checkIfString(tag: unknown, tagName: string): tag is string | undefined | null {
function isString(tag: unknown, tagName: string): tag is string | undefined | null {
if (tag !== undefined && tag !== null && typeof tag !== 'string') {
display.error(`${tagName} must be defined as a string`)
return false
}
return true
}

function isDatadogSite(site: string) {
return /(datadog|ddog|datad0g|dd0g)/.test(site)
function isDatadogSite(site: unknown) {
if (site && typeof site === 'string' && !/(datadog|ddog|datad0g|dd0g)/.test(site)) {
display.error(`Site should be a valid Datadog site. ${MORE_DETAILS} ${DOCS_ORIGIN}/getting_started/site/.`)
return false
}
return true
}

export function isSampleRate(sampleRate: unknown, name: string) {
if (sampleRate !== undefined && !isPercentage(sampleRate)) {
display.error(`${name} Sample Rate should be a number between 0 and 100`)
return false
}
return true
}

export function validateAndBuildConfiguration(initConfiguration: InitConfiguration): Configuration | undefined {
Expand All @@ -209,41 +221,16 @@ export function validateAndBuildConfiguration(initConfiguration: InitConfigurati
return
}

if (initConfiguration.sessionSampleRate !== undefined && !isPercentage(initConfiguration.sessionSampleRate)) {
display.error('Session Sample Rate should be a number between 0 and 100')
return
}

if (initConfiguration.telemetrySampleRate !== undefined && !isPercentage(initConfiguration.telemetrySampleRate)) {
display.error('Telemetry Sample Rate should be a number between 0 and 100')
return
}

if (
initConfiguration.telemetryConfigurationSampleRate !== undefined &&
!isPercentage(initConfiguration.telemetryConfigurationSampleRate)
!isDatadogSite(initConfiguration.site) ||
!isSampleRate(initConfiguration.sessionSampleRate, 'Session') ||
!isSampleRate(initConfiguration.telemetrySampleRate, 'Telemetry') ||
!isSampleRate(initConfiguration.telemetryConfigurationSampleRate, 'Telemetry Configuration') ||
!isSampleRate(initConfiguration.telemetryUsageSampleRate, 'Telemetry Usage') ||
!isString(initConfiguration.version, 'Version') ||
!isString(initConfiguration.env, 'Env') ||
!isString(initConfiguration.service, 'Service')
) {
display.error('Telemetry Configuration Sample Rate should be a number between 0 and 100')
return
}

if (
initConfiguration.telemetryUsageSampleRate !== undefined &&
!isPercentage(initConfiguration.telemetryUsageSampleRate)
) {
display.error('Telemetry Usage Sample Rate should be a number between 0 and 100')
return
}

if (!checkIfString(initConfiguration.version, 'Version')) {
return
}

if (!checkIfString(initConfiguration.env, 'Env')) {
return
}

if (!checkIfString(initConfiguration.service, 'Service')) {
return
}

Expand All @@ -255,11 +242,6 @@ export function validateAndBuildConfiguration(initConfiguration: InitConfigurati
return
}

if (initConfiguration.site && !isDatadogSite(initConfiguration.site)) {
display.error(`Site should be a valid Datadog site. Learn more here: ${DOCS_ORIGIN}/getting_started/site/.`)
return
}

return assign(
{
beforeSend:
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/domain/configuration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export {
InitConfiguration,
DefaultPrivacyLevel,
TraceContextInjection,
isSampleRate,
validateAndBuildConfiguration,
serializeConfiguration,
} from './configuration'
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export {
TraceContextInjection,
EndpointBuilder,
serializeConfiguration,
isSampleRate,
INTAKE_SITE_STAGING,
INTAKE_SITE_US1,
INTAKE_SITE_US1_FED,
Expand Down
63 changes: 28 additions & 35 deletions packages/rum-core/src/domain/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
DefaultPrivacyLevel,
TraceContextInjection,
display,
isPercentage,
objectHasValue,
validateAndBuildConfiguration,
isSampleRate,
} from '@datadog/browser-core'
import type { RumEventDomainContext } from '../../domainContext.types'
import type { RumEvent } from '../../rumEvent.types'
Expand Down Expand Up @@ -167,15 +167,9 @@ export function validateAndBuildRumConfiguration(
}

if (
initConfiguration.sessionReplaySampleRate !== undefined &&
!isPercentage(initConfiguration.sessionReplaySampleRate)
!isSampleRate(initConfiguration.sessionReplaySampleRate, 'Session Replay') ||
!isSampleRate(initConfiguration.traceSampleRate, 'Trace')
) {
display.error('Session Replay Sample Rate should be a number between 0 and 100')
return
}

if (initConfiguration.traceSampleRate !== undefined && !isPercentage(initConfiguration.traceSampleRate)) {
display.error('Trace Sample Rate should be a number between 0 and 100')
return
}

Expand Down Expand Up @@ -229,34 +223,33 @@ export function validateAndBuildRumConfiguration(
* Validates allowedTracingUrls and converts match options to tracing options
*/
function validateAndBuildTracingOptions(initConfiguration: RumInitConfiguration): TracingOption[] | undefined {
if (initConfiguration.allowedTracingUrls !== undefined) {
if (!Array.isArray(initConfiguration.allowedTracingUrls)) {
display.error('Allowed Tracing URLs should be an array')
return
}
if (initConfiguration.allowedTracingUrls.length !== 0 && initConfiguration.service === undefined) {
display.error('Service needs to be configured when tracing is enabled')
return
}
// Convert from (MatchOption | TracingOption) to TracingOption, remove unknown properties
const tracingOptions: TracingOption[] = []
initConfiguration.allowedTracingUrls.forEach((option) => {
if (isMatchOption(option)) {
tracingOptions.push({ match: option, propagatorTypes: DEFAULT_PROPAGATOR_TYPES })
} else if (isTracingOption(option)) {
tracingOptions.push(option)
} else {
display.warn(
'Allowed Tracing Urls parameters should be a string, RegExp, function, or an object. Ignoring parameter',
option
)
}
})

return tracingOptions
if (initConfiguration.allowedTracingUrls === undefined) {
return []
}
if (!Array.isArray(initConfiguration.allowedTracingUrls)) {
display.error('Allowed Tracing URLs should be an array')
return
}
if (initConfiguration.allowedTracingUrls.length !== 0 && initConfiguration.service === undefined) {
display.error('Service needs to be configured when tracing is enabled')
return
}
// Convert from (MatchOption | TracingOption) to TracingOption, remove unknown properties
const tracingOptions: TracingOption[] = []
initConfiguration.allowedTracingUrls.forEach((option) => {
if (isMatchOption(option)) {
tracingOptions.push({ match: option, propagatorTypes: DEFAULT_PROPAGATOR_TYPES })
} else if (isTracingOption(option)) {
tracingOptions.push(option)
} else {
display.warn(
'Allowed Tracing Urls parameters should be a string, RegExp, function, or an object. Ignoring parameter',
option
)
}
})

return []
return tracingOptions
}

/**
Expand Down

0 comments on commit 7d552bd

Please sign in to comment.