Skip to content

Commit

Permalink
Merge 64156e4 in staging-36
Browse files Browse the repository at this point in the history
Co-authored-by: Benoît Zugmeyer <[email protected]>
  • Loading branch information
dd-mergequeue[bot] and BenoitZugmeyer authored Sep 5, 2023
2 parents 60e1c17 + 64156e4 commit bd2ac01
Show file tree
Hide file tree
Showing 39 changed files with 1,330 additions and 431 deletions.
84 changes: 60 additions & 24 deletions packages/core/src/domain/configuration/endpointBuilder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import {
addExperimentalFeatures,
} from '../../tools/experimentalFeatures'
import { startsWith } from '../../tools/utils/polyfills'
import type { Payload } from '../../transport'
import type { InitConfiguration } from './configuration'
import { createEndpointBuilder } from './endpointBuilder'

const DEFAULT_PAYLOAD = {} as Payload

describe('endpointBuilder', () => {
const clientToken = 'some_client_token'
let initConfiguration: InitConfiguration
Expand All @@ -20,23 +23,36 @@ describe('endpointBuilder', () => {

describe('query parameters', () => {
it('should add intake query parameters', () => {
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr')).toMatch(
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', DEFAULT_PAYLOAD)).toMatch(
`&dd-api-key=${clientToken}&dd-evp-origin-version=(.*)&dd-evp-origin=browser&dd-request-id=(.*)`
)
})

it('should add batch_time for rum endpoint', () => {
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr')).toContain('&batch_time=')
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', DEFAULT_PAYLOAD)).toContain(
'&batch_time='
)
})

it('should not add batch_time for logs and replay endpoints', () => {
expect(createEndpointBuilder(initConfiguration, 'logs', []).build('xhr')).not.toContain('&batch_time=')
expect(createEndpointBuilder(initConfiguration, 'sessionReplay', []).build('xhr')).not.toContain('&batch_time=')
expect(createEndpointBuilder(initConfiguration, 'logs', []).build('xhr', DEFAULT_PAYLOAD)).not.toContain(
'&batch_time='
)
expect(createEndpointBuilder(initConfiguration, 'sessionReplay', []).build('xhr', DEFAULT_PAYLOAD)).not.toContain(
'&batch_time='
)
})

it('should add the provided encoding', () => {
expect(
createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', { ...DEFAULT_PAYLOAD, encoding: 'deflate' })
).toContain('&dd-evp-encoding=deflate')
})

it('should not start with ddsource for internal analytics mode', () => {
const url = createEndpointBuilder({ ...initConfiguration, internalAnalyticsSubdomain: 'foo' }, 'rum', []).build(
'xhr'
'xhr',
DEFAULT_PAYLOAD
)
expect(url).not.toContain('/rum?ddsource')
expect(url).toContain('ddsource=browser')
Expand All @@ -46,7 +62,10 @@ describe('endpointBuilder', () => {
describe('proxy configuration', () => {
it('should replace the intake endpoint by the proxy and set the intake path and parameters in the attribute ddforward', () => {
expect(
createEndpointBuilder({ ...initConfiguration, proxy: 'https://proxy.io/path' }, 'rum', []).build('xhr')
createEndpointBuilder({ ...initConfiguration, proxy: 'https://proxy.io/path' }, 'rum', []).build(
'xhr',
DEFAULT_PAYLOAD
)
).toMatch(
`https://proxy.io/path\\?ddforward=${encodeURIComponent(
`/api/v2/rum?ddsource=(.*)&ddtags=(.*)&dd-api-key=${clientToken}` +
Expand All @@ -58,7 +77,7 @@ describe('endpointBuilder', () => {
it('normalizes the proxy url', () => {
expect(
startsWith(
createEndpointBuilder({ ...initConfiguration, proxy: '/path' }, 'rum', []).build('xhr'),
createEndpointBuilder({ ...initConfiguration, proxy: '/path' }, 'rum', []).build('xhr', DEFAULT_PAYLOAD),
`${location.origin}/path?ddforward`
)
).toBeTrue()
Expand All @@ -70,23 +89,26 @@ describe('endpointBuilder', () => {
{ ...initConfiguration, proxy: 'https://proxy.io/path', proxyUrl: 'https://legacy-proxy.io/path' },
'rum',
[]
).build('xhr')
).build('xhr', DEFAULT_PAYLOAD)
).toMatch(/^https:\/\/proxy.io\/path\?/)

expect(
createEndpointBuilder(
{ ...initConfiguration, proxy: false as any, proxyUrl: 'https://legacy-proxy.io/path' },
'rum',
[]
).build('xhr')
).build('xhr', DEFAULT_PAYLOAD)
).toMatch(/^https:\/\/rum.browser-intake-datadoghq.com\//)
})
})

describe('deprecated proxyUrl configuration', () => {
it('should replace the full intake endpoint by the proxyUrl and set it in the attribute ddforward', () => {
expect(
createEndpointBuilder({ ...initConfiguration, proxyUrl: 'https://proxy.io/path' }, 'rum', []).build('xhr')
createEndpointBuilder({ ...initConfiguration, proxyUrl: 'https://proxy.io/path' }, 'rum', []).build(
'xhr',
DEFAULT_PAYLOAD
)
).toMatch(
`https://proxy.io/path\\?ddforward=${encodeURIComponent(
`https://rum.browser-intake-datadoghq.com/api/v2/rum?ddsource=(.*)&ddtags=(.*)&dd-api-key=${clientToken}` +
Expand All @@ -98,7 +120,7 @@ describe('endpointBuilder', () => {
it('normalizes the proxy url', () => {
expect(
startsWith(
createEndpointBuilder({ ...initConfiguration, proxyUrl: '/path' }, 'rum', []).build('xhr'),
createEndpointBuilder({ ...initConfiguration, proxyUrl: '/path' }, 'rum', []).build('xhr', DEFAULT_PAYLOAD),
`${location.origin}/path?ddforward`
)
).toBeTrue()
Expand All @@ -107,39 +129,53 @@ describe('endpointBuilder', () => {

describe('tags', () => {
it('should contain sdk version', () => {
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr')).toContain('sdk_version%3Asome_version')
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', DEFAULT_PAYLOAD)).toContain(
'sdk_version%3Asome_version'
)
})

it('should contain api', () => {
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr')).toContain('api%3Axhr')
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', DEFAULT_PAYLOAD)).toContain('api%3Axhr')
})

it('should be encoded', () => {
expect(
createEndpointBuilder(initConfiguration, 'rum', ['service:bar:foo', 'datacenter:us1.prod.dog']).build('xhr')
createEndpointBuilder(initConfiguration, 'rum', ['service:bar:foo', 'datacenter:us1.prod.dog']).build(
'xhr',
DEFAULT_PAYLOAD
)
).toContain('service%3Abar%3Afoo%2Cdatacenter%3Aus1.prod.dog')
})

it('should contain retry infos', () => {
expect(
createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', 'bytes_limit', {
count: 5,
lastFailureStatus: 408,
createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', {
...DEFAULT_PAYLOAD,
retry: {
count: 5,
lastFailureStatus: 408,
},
})
).toContain('retry_count%3A5%2Cretry_after%3A408')
})

it('should contain flush reason when ff collect_flush_reason is enabled', () => {
addExperimentalFeatures([ExperimentalFeature.COLLECT_FLUSH_REASON])
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', 'bytes_limit')).toContain(
'flush_reason%3Abytes_limit'
)
expect(
createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', {
...DEFAULT_PAYLOAD,
flushReason: 'bytes_limit',
})
).toContain('flush_reason%3Abytes_limit')
})

it('should not contain flush reason when ff collect_flush_reason is disnabled', () => {
expect(createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', 'bytes_limit')).not.toContain(
'flush_reason'
)
it('should not contain flush reason when ff collect_flush_reason is disabled', () => {
expect(
createEndpointBuilder(initConfiguration, 'rum', []).build('xhr', {
...DEFAULT_PAYLOAD,
flushReason: 'bytes_limit',
})
).not.toContain('flush_reason')
})
})
})
22 changes: 10 additions & 12 deletions packages/core/src/domain/configuration/endpointBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RetryInfo, FlushReason } from '../../transport'
import type { Payload } from '../../transport'
import { timeStampNow } from '../../tools/utils/timeUtils'
import { normalizeUrl } from '../../tools/utils/urlPolyfill'
import { ExperimentalFeature, isExperimentalFeatureEnabled } from '../../tools/experimentalFeatures'
Expand Down Expand Up @@ -33,15 +33,8 @@ export function createEndpointBuilder(
const buildUrlWithParameters = createEndpointUrlWithParametersBuilder(initConfiguration, endpointType)

return {
build(api: 'xhr' | 'fetch' | 'beacon', flushReason?: FlushReason, retry?: RetryInfo) {
const parameters = buildEndpointParameters(
initConfiguration,
endpointType,
configurationTags,
api,
flushReason,
retry
)
build(api: 'xhr' | 'fetch' | 'beacon', payload: Payload) {
const parameters = buildEndpointParameters(initConfiguration, endpointType, configurationTags, api, payload)
return buildUrlWithParameters(parameters)
},
urlPrefix: buildUrlWithParameters(''),
Expand Down Expand Up @@ -100,8 +93,7 @@ function buildEndpointParameters(
endpointType: EndpointType,
configurationTags: string[],
api: 'xhr' | 'fetch' | 'beacon',
flushReason: FlushReason | undefined,
retry: RetryInfo | undefined
{ retry, flushReason, encoding }: Payload
) {
const tags = [`sdk_version:${__BUILD_ENV__SDK_VERSION__}`, `api:${api}`].concat(configurationTags)
if (flushReason && isExperimentalFeatureEnabled(ExperimentalFeature.COLLECT_FLUSH_REASON)) {
Expand All @@ -110,6 +102,7 @@ function buildEndpointParameters(
if (retry) {
tags.push(`retry_count:${retry.count}`, `retry_after:${retry.lastFailureStatus}`)
}

const parameters = [
'ddsource=browser',
`ddtags=${encodeURIComponent(tags.join(','))}`,
Expand All @@ -119,9 +112,14 @@ function buildEndpointParameters(
`dd-request-id=${generateUUID()}`,
]

if (encoding) {
parameters.push(`dd-evp-encoding=${encoding}`)
}

if (endpointType === 'rum') {
parameters.push(`batch_time=${timeStampNow()}`)
}

if (internalAnalyticsSubdomain) {
parameters.reverse()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import type { Payload } from '../../transport'
import { computeTransportConfiguration } from './transportConfiguration'

const DEFAULT_PAYLOAD = {} as Payload

describe('transportConfiguration', () => {
const clientToken = 'some_client_token'
const internalAnalyticsSubdomain = 'ia-rum-intake'
describe('site', () => {
it('should use US site by default', () => {
const configuration = computeTransportConfiguration({ clientToken })
expect(configuration.rumEndpointBuilder.build('xhr')).toContain('datadoghq.com')
expect(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD)).toContain('datadoghq.com')
expect(configuration.site).toBe('datadoghq.com')
})

it('should use site value when set', () => {
const configuration = computeTransportConfiguration({ clientToken, site: 'foo.com' })
expect(configuration.rumEndpointBuilder.build('xhr')).toContain('foo.com')
expect(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD)).toContain('foo.com')
expect(configuration.site).toBe('foo.com')
})
})
Expand All @@ -23,7 +26,7 @@ describe('transportConfiguration', () => {
clientToken,
internalAnalyticsSubdomain,
})
expect(configuration.rumEndpointBuilder.build('xhr')).toContain(internalAnalyticsSubdomain)
expect(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD)).toContain(internalAnalyticsSubdomain)
})

it('should not use internal analytics subdomain value when set for other sites', () => {
Expand All @@ -32,30 +35,42 @@ describe('transportConfiguration', () => {
site: 'foo.bar',
internalAnalyticsSubdomain,
})
expect(configuration.rumEndpointBuilder.build('xhr')).not.toContain(internalAnalyticsSubdomain)
expect(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD)).not.toContain(internalAnalyticsSubdomain)
})
})

describe('sdk_version, env, version and service', () => {
it('should not modify the logs and rum endpoints tags when not defined', () => {
const configuration = computeTransportConfiguration({ clientToken })
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr'))).not.toContain(',env:')
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr'))).not.toContain(',service:')
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr'))).not.toContain(',version:')
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr'))).not.toContain(',datacenter:')

expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr'))).not.toContain(',env:')
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr'))).not.toContain(',service:')
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr'))).not.toContain(',version:')
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr'))).not.toContain(',datacenter:')
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(',env:')
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',service:'
)
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',version:'
)
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',datacenter:'
)

expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(',env:')
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',service:'
)
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',version:'
)
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).not.toContain(
',datacenter:'
)
})

it('should be set as tags in the logs and rum endpoints', () => {
const configuration = computeTransportConfiguration({ clientToken, env: 'foo', service: 'bar', version: 'baz' })
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr'))).toContain(
expect(decodeURIComponent(configuration.rumEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).toContain(
'env:foo,service:bar,version:baz'
)
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr'))).toContain(
expect(decodeURIComponent(configuration.logsEndpointBuilder.build('xhr', DEFAULT_PAYLOAD))).toContain(
'env:foo,service:bar,version:baz'
)
})
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/domain/deflate/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Encoder } from '../../tools/encoder'

export type DeflateWorkerAction =
// Action to send when creating the worker to check if the communication is working correctly.
// The worker should respond with a 'initialized' response.
Expand Down Expand Up @@ -39,3 +41,15 @@ export type DeflateWorkerResponse =
streamId?: number
error: Error | string
}

export interface DeflateWorker extends Worker {
postMessage(message: DeflateWorkerAction): void
}

export type DeflateEncoder = Encoder<Uint8Array>

export const enum DeflateEncoderStreamId {
REPLAY = 1,
RUM = 2,
RUM_REPLICA = 3,
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export {
FlushReason,
} from './transport'
export * from './tools/display'
export { Encoder, EncoderResult } from './tools/encoder'
export * from './tools/utils/urlPolyfill'
export * from './tools/utils/timeUtils'
export * from './tools/utils/arrayUtils'
Expand Down
Loading

0 comments on commit bd2ac01

Please sign in to comment.