Socket
Socket
Sign inDemoInstall

dd-trace

Package Overview
Dependencies
Maintainers
1
Versions
574
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dd-trace - npm Package Compare versions

Comparing version 5.20.0 to 5.21.0

packages/datadog-instrumentations/src/nyc.js

8

package.json
{
"name": "dd-trace",
"version": "5.20.0",
"version": "5.21.0",
"description": "Datadog APM tracing client for JavaScript",

@@ -76,4 +76,4 @@ "main": "index.js",

"@datadog/native-appsec": "8.0.1",
"@datadog/native-iast-rewriter": "2.4.0",
"@datadog/native-iast-taint-tracking": "3.0.0",
"@datadog/native-iast-rewriter": "2.4.1",
"@datadog/native-iast-taint-tracking": "3.1.0",
"@datadog/native-metrics": "^2.0.0",

@@ -107,3 +107,3 @@ "@datadog/pprof": "5.3.0",

"devDependencies": {
"@types/node": ">=18",
"@types/node": "^16.18.103",
"autocannon": "^4.5.2",

@@ -110,0 +110,0 @@ "aws-sdk": "^2.1446.0",

'use strict'
const shimmer = require('../../datadog-shimmer')
const { channel, addHook } = require('./helpers/instrument')
const { channel, addHook, AsyncResource } = require('./helpers/instrument')

@@ -26,5 +26,17 @@ const bodyParserReadCh = channel('datadog:body-parser:read:finish')

file: 'lib/read.js',
versions: ['>=1.4.0']
versions: ['>=1.4.0 <1.20.0']
}, read => {
return shimmer.wrap(read, function (req, res, next) {
const nextResource = new AsyncResource('bound-anonymous-fn')
arguments[2] = nextResource.bind(publishRequestBodyAndNext(req, res, next))
return read.apply(this, arguments)
})
})
addHook({
name: 'body-parser',
file: 'lib/read.js',
versions: ['>=1.20.0']
}, read => {
return shimmer.wrap(read, function (req, res, next) {
arguments[2] = publishRequestBodyAndNext(req, res, next)

@@ -31,0 +43,0 @@ return read.apply(this, arguments)

@@ -31,2 +31,4 @@ 'use strict'

const getCodeCoverageCh = channel('ci:nyc:get-coverage')
const {

@@ -360,2 +362,7 @@ getCoveredFilenamesFromCoverage,

let untestedCoverage
if (getCodeCoverageCh.hasSubscribers) {
untestedCoverage = await getChannelPromise(getCodeCoverageCh)
}
let testCodeCoverageLinesTotal

@@ -365,2 +372,5 @@

try {
if (untestedCoverage) {
originalCoverageMap.merge(fromCoverageMapToCoverage(untestedCoverage))
}
testCodeCoverageLinesTotal = originalCoverageMap.getCoverageSummary().lines.pct

@@ -367,0 +377,0 @@ } catch (e) {

@@ -75,3 +75,2 @@ 'use strict'

'mocha-each': () => require('../mocha'),
workerpool: () => require('../mocha'),
moleculer: () => require('../moleculer'),

@@ -93,2 +92,3 @@ mongodb: () => require('../mongodb'),

'node:net': () => require('../net'),
nyc: () => require('../nyc'),
oracledb: () => require('../oracledb'),

@@ -118,3 +118,4 @@ openai: () => require('../openai'),

when: () => require('../when'),
winston: () => require('../winston')
winston: () => require('../winston'),
workerpool: () => require('../mocha')
}

@@ -93,3 +93,10 @@ 'use strict'

if (matchesFile) {
const version = moduleVersion || getVersion(moduleBaseDir)
let version = moduleVersion
try {
version = version || getVersion(moduleBaseDir)
} catch (e) {
log.error(`Error getting version for "${name}": ${e.message}`)
log.error(e)
continue
}
if (!Object.hasOwnProperty(namesAndSuccesses, name)) {

@@ -96,0 +103,0 @@ namesAndSuccesses[`${name}@${version}`] = false

@@ -50,2 +50,3 @@ 'use strict'

const originalCoverageMap = createCoverageMap()
let untestedCoverage

@@ -70,2 +71,4 @@ // test channels

const getCodeCoverageCh = channel('ci:nyc:get-coverage')
function getFilteredSuites (originalSuites) {

@@ -136,2 +139,5 @@ return originalSuites.reduce((acc, suite) => {

try {
if (untestedCoverage) {
originalCoverageMap.merge(fromCoverageMapToCoverage(untestedCoverage))
}
testCodeCoverageLinesTotal = originalCoverageMap.getCoverageSummary().lines.pct

@@ -159,2 +165,79 @@ } catch (e) {

function getExecutionConfiguration (runner, onFinishRequest) {
const mochaRunAsyncResource = new AsyncResource('bound-anonymous-fn')
const onReceivedSkippableSuites = ({ err, skippableSuites, itrCorrelationId: responseItrCorrelationId }) => {
if (err) {
suitesToSkip = []
} else {
suitesToSkip = skippableSuites
itrCorrelationId = responseItrCorrelationId
}
// We remove the suites that we skip through ITR
const filteredSuites = getFilteredSuites(runner.suite.suites)
const { suitesToRun } = filteredSuites
isSuitesSkipped = suitesToRun.length !== runner.suite.suites.length
log.debug(
() => `${suitesToRun.length} out of ${runner.suite.suites.length} suites are going to run.`
)
runner.suite.suites = suitesToRun
skippedSuites = Array.from(filteredSuites.skippedSuites)
onFinishRequest()
}
const onReceivedKnownTests = ({ err, knownTests: receivedKnownTests }) => {
if (err) {
knownTests = []
isEarlyFlakeDetectionEnabled = false
} else {
knownTests = receivedKnownTests
}
if (isSuitesSkippingEnabled) {
skippableSuitesCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedSkippableSuites)
})
} else {
onFinishRequest()
}
}
const onReceivedConfiguration = ({ err, libraryConfig }) => {
if (err || !skippableSuitesCh.hasSubscribers || !knownTestsCh.hasSubscribers) {
return onFinishRequest()
}
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
config.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
config.isSuitesSkippingEnabled = isSuitesSkippingEnabled
config.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
config.isFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
if (isEarlyFlakeDetectionEnabled) {
knownTestsCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedKnownTests)
})
} else if (isSuitesSkippingEnabled) {
skippableSuitesCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedSkippableSuites)
})
} else {
onFinishRequest()
}
}
libraryConfigurationCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedConfiguration)
})
}
// In this hook we delay the execution with options.delay to grab library configuration,

@@ -168,3 +251,2 @@ // skippable and known tests.

}, (Mocha) => {
const mochaRunAsyncResource = new AsyncResource('bound-anonymous-fn')
shimmer.wrap(Mocha.prototype, 'run', run => function () {

@@ -189,37 +271,9 @@ // Workers do not need to request any data, just run the tests

const onReceivedSkippableSuites = ({ err, skippableSuites, itrCorrelationId: responseItrCorrelationId }) => {
if (err) {
suitesToSkip = []
} else {
suitesToSkip = skippableSuites
itrCorrelationId = responseItrCorrelationId
}
// We remove the suites that we skip through ITR
const filteredSuites = getFilteredSuites(runner.suite.suites)
const { suitesToRun } = filteredSuites
isSuitesSkipped = suitesToRun.length !== runner.suite.suites.length
log.debug(
() => `${suitesToRun.length} out of ${runner.suite.suites.length} suites are going to run.`
)
runner.suite.suites = suitesToRun
skippedSuites = Array.from(filteredSuites.skippedSuites)
global.run()
}
const onReceivedKnownTests = ({ err, knownTests: receivedKnownTests }) => {
if (err) {
knownTests = []
isEarlyFlakeDetectionEnabled = false
} else {
knownTests = receivedKnownTests
}
if (isSuitesSkippingEnabled) {
skippableSuitesCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedSkippableSuites)
getExecutionConfiguration(runner, () => {
if (getCodeCoverageCh.hasSubscribers) {
getCodeCoverageCh.publish({
onDone: (receivedCodeCoverage) => {
untestedCoverage = receivedCodeCoverage
global.run()
}
})

@@ -229,36 +283,2 @@ } else {

}
}
const onReceivedConfiguration = ({ err, libraryConfig }) => {
if (err || !skippableSuitesCh.hasSubscribers || !knownTestsCh.hasSubscribers) {
return global.run()
}
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
isSuitesSkippingEnabled = libraryConfig.isSuitesSkippingEnabled
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
config.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
config.isSuitesSkippingEnabled = isSuitesSkippingEnabled
config.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
config.isFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
if (isEarlyFlakeDetectionEnabled) {
knownTestsCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedKnownTests)
})
} else if (isSuitesSkippingEnabled) {
skippableSuitesCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedSkippableSuites)
})
} else {
global.run()
}
}
mochaRunAsyncResource.runInAsyncScope(() => {
libraryConfigurationCh.publish({
onDone: mochaRunAsyncResource.bind(onReceivedConfiguration)
})
})

@@ -265,0 +285,0 @@

@@ -124,2 +124,17 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')

let testCodeCoverageLinesTotal
if (this.ctx.coverageProvider?.generateCoverage) {
shimmer.wrap(this.ctx.coverageProvider, 'generateCoverage', generateCoverage => async function () {
const totalCodeCoverage = await generateCoverage.apply(this, arguments)
try {
testCodeCoverageLinesTotal = totalCodeCoverage.getCoverageSummary().lines.pct
} catch (e) {
// ignore errors
}
return totalCodeCoverage
})
}
shimmer.wrap(this.ctx, 'exit', exit => async function () {

@@ -140,4 +155,5 @@ let onFinish

status: getSessionStatus(this.state),
onFinish,
error
testCodeCoverageLinesTotal,
error,
onFinish
})

@@ -144,0 +160,0 @@ })

@@ -40,3 +40,6 @@ 'use strict'

TELEMETRY_ITR_UNSKIPPABLE,
TELEMETRY_CODE_COVERAGE_NUM_FILES
TELEMETRY_CODE_COVERAGE_NUM_FILES,
TEST_IS_RUM_ACTIVE,
TEST_BROWSER_DRIVER,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/ci-visibility/telemetry')

@@ -111,2 +114,3 @@ const id = require('../../dd-trace/src/id')

finishAllTraceSpans(this.testSessionSpan)
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })

@@ -290,6 +294,12 @@ this.libraryConfig = null

if (!isStep) {
const spanTags = span.context()._tags
this.telemetry.ciVisEvent(
TELEMETRY_EVENT_FINISHED,
'test',
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
{
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
isNew,
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
browserDriver: spanTags[TEST_BROWSER_DRIVER]
}
)

@@ -296,0 +306,0 @@ finishAllTraceSpans(span)

@@ -47,3 +47,5 @@ const {

incrementCountMetric,
distributionMetric
distributionMetric,
TELEMETRY_ITR_SKIPPED,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/ci-visibility/telemetry')

@@ -183,3 +185,3 @@

this.repositoryRoot = repositoryRoot
this.isUnsupportedCIProvider = !ciProviderName
this.ciProviderName = ciProviderName
this.codeOwnersEntries = getCodeOwnersFileEntries(repositoryRoot)

@@ -326,3 +328,3 @@

testFramework: 'cypress',
isUnsupportedCIProvider: this.isUnsupportedCIProvider,
isUnsupportedCIProvider: !this.ciProviderName,
...tags

@@ -369,2 +371,3 @@ })

this.itrCorrelationId = correlationId
incrementCountMetric(TELEMETRY_ITR_SKIPPED, { testLevel: 'test' }, this.testsToSkip.length)
}

@@ -443,2 +446,5 @@ }

this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
incrementCountMetric(TELEMETRY_TEST_SESSION, {
provider: this.ciProviderName
})

@@ -676,4 +682,10 @@ finishAllTraceSpans(this.testSessionSpan)

}
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
hasCodeOwners: !!this.activeTestSpan.context()._tags[TEST_CODE_OWNERS],
isNew,
isRum: isRUMActive,
browserDriver: 'cypress'
})
this.activeTestSpan = null
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test')
return null

@@ -680,0 +692,0 @@ },

@@ -23,3 +23,5 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')

TEST_EARLY_FLAKE_ABORT_REASON,
JEST_DISPLAY_NAME
JEST_DISPLAY_NAME,
TEST_IS_RUM_ACTIVE,
TEST_BROWSER_DRIVER
} = require('../../dd-trace/src/plugins/util/test')

@@ -36,3 +38,4 @@ const { COMPONENT } = require('../../dd-trace/src/constants')

TELEMETRY_ITR_UNSKIPPABLE,
TELEMETRY_CODE_COVERAGE_NUM_FILES
TELEMETRY_CODE_COVERAGE_NUM_FILES,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/ci-visibility/telemetry')

@@ -134,2 +137,4 @@

this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
this.tracer._exporter.flush(() => {

@@ -293,8 +298,16 @@ if (onDone) {

}
span.finish()
const spanTags = span.context()._tags
this.telemetry.ciVisEvent(
TELEMETRY_EVENT_FINISHED,
'test',
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
{
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
isNew: spanTags[TEST_IS_NEW] === 'true',
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
browserDriver: spanTags[TEST_BROWSER_DRIVER]
}
)
span.finish()
finishAllTraceSpans(span)

@@ -301,0 +314,0 @@ })

@@ -30,3 +30,5 @@ 'use strict'

TEST_SUITE,
MOCHA_IS_PARALLEL
MOCHA_IS_PARALLEL,
TEST_IS_RUM_ACTIVE,
TEST_BROWSER_DRIVER
} = require('../../dd-trace/src/plugins/util/test')

@@ -42,3 +44,4 @@ const { COMPONENT } = require('../../dd-trace/src/constants')

TELEMETRY_ITR_UNSKIPPABLE,
TELEMETRY_CODE_COVERAGE_NUM_FILES
TELEMETRY_CODE_COVERAGE_NUM_FILES,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/ci-visibility/telemetry')

@@ -189,8 +192,16 @@ const id = require('../../dd-trace/src/id')

}
span.finish()
const spanTags = span.context()._tags
this.telemetry.ciVisEvent(
TELEMETRY_EVENT_FINISHED,
'test',
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
{
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
isNew: spanTags[TEST_IS_NEW] === 'true',
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
browserDriver: spanTags[TEST_BROWSER_DRIVER]
}
)
span.finish()
finishAllTraceSpans(span)

@@ -232,8 +243,15 @@ }

span.finish()
const spanTags = span.context()._tags
this.telemetry.ciVisEvent(
TELEMETRY_EVENT_FINISHED,
'test',
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
{
hasCodeOwners: !!spanTags[TEST_CODE_OWNERS],
isNew: spanTags[TEST_IS_NEW] === 'true',
isRum: spanTags[TEST_IS_RUM_ACTIVE] === 'true',
browserDriver: spanTags[TEST_BROWSER_DRIVER]
}
)
span.finish()
finishAllTraceSpans(span)

@@ -296,2 +314,3 @@ }

finishAllTraceSpans(this.testSessionSpan)
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
}

@@ -298,0 +317,0 @@ this.libraryConfig = null

@@ -17,3 +17,4 @@ 'use strict'

TEST_IS_RETRY,
TEST_EARLY_FLAKE_ENABLED
TEST_EARLY_FLAKE_ENABLED,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/plugins/util/test')

@@ -63,2 +64,3 @@ const { RESOURCE_NAME } = require('../../../ext/tags')

finishAllTraceSpans(this.testSessionSpan)
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
appClosingTelemetry()

@@ -165,4 +167,2 @@ this.tracer._exporter.flush(onDone)

span.finish()
if (testStatus === 'fail') {

@@ -175,4 +175,9 @@ this.numFailedTests++

'test',
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
{
hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS],
isNew,
browserDriver: 'playwright'
}
)
span.finish()

@@ -179,0 +184,0 @@ finishAllTraceSpans(span)

@@ -10,5 +10,12 @@ const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')

TEST_SOURCE_FILE,
TEST_IS_RETRY
TEST_IS_RETRY,
TEST_CODE_COVERAGE_LINES_PCT,
TEST_CODE_OWNERS
} = require('../../dd-trace/src/plugins/util/test')
const { COMPONENT } = require('../../dd-trace/src/constants')
const {
TELEMETRY_EVENT_CREATED,
TELEMETRY_EVENT_FINISHED,
TELEMETRY_TEST_SESSION
} = require('../../dd-trace/src/ci-visibility/telemetry')

@@ -68,2 +75,5 @@ // Milliseconds that we subtract from the error test duration

if (span) {
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
hasCodeowners: !!span.context()._tags[TEST_CODE_OWNERS]
})
span.setTag(TEST_STATUS, 'pass')

@@ -80,2 +90,5 @@ span.finish(this.taskToFinishTime.get(task))

if (span) {
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
hasCodeowners: !!span.context()._tags[TEST_CODE_OWNERS]
})
span.setTag(TEST_STATUS, 'fail')

@@ -97,3 +110,3 @@

const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
this.startTestSpan(
const testSpan = this.startTestSpan(
testName,

@@ -106,3 +119,7 @@ testSuite,

}
).finish()
)
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', {
hasCodeowners: !!testSpan.context()._tags[TEST_CODE_OWNERS]
})
testSpan.finish()
})

@@ -132,2 +149,3 @@

})
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
const store = storage.getStore()

@@ -146,2 +164,3 @@ this.enter(testSuiteSpan, store)

}
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
// TODO: too frequent flush - find for method in worker to decrease frequency

@@ -160,3 +179,3 @@ this.tracer._exporter.flush(onFinish)

this.addSub('ci:vitest:session:finish', ({ status, onFinish, error }) => {
this.addSub('ci:vitest:session:finish', ({ status, onFinish, error, testCodeCoverageLinesTotal }) => {
this.testSessionSpan.setTag(TEST_STATUS, status)

@@ -168,5 +187,12 @@ this.testModuleSpan.setTag(TEST_STATUS, status)

}
if (testCodeCoverageLinesTotal) {
this.testModuleSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
this.testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
}
this.testModuleSpan.finish()
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
this.testSessionSpan.finish()
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
finishAllTraceSpans(this.testSessionSpan)
this.telemetry.count(TELEMETRY_TEST_SESSION, { provider: this.ciProviderName })
this.tracer._exporter.flush(onFinish)

@@ -173,0 +199,0 @@ })

const request = require('../../exporters/common/request')
const id = require('../../id')
const log = require('../../log')
const {
incrementCountMetric,
distributionMetric,
TELEMETRY_KNOWN_TESTS,
TELEMETRY_KNOWN_TESTS_MS,
TELEMETRY_KNOWN_TESTS_ERRORS,
TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS,
TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES
} = require('../../ci-visibility/telemetry')
function getNumTests (knownTests) {
let totalNumTests = 0
for (const testModule of Object.values(knownTests)) {
for (const testSuite of Object.values(testModule)) {
for (const testList of Object.values(testSuite)) {
totalNumTests += testList.length
}
}
}
return totalNumTests
}
function getKnownTests ({

@@ -67,4 +92,10 @@ url,

request(data, options, (err, res) => {
incrementCountMetric(TELEMETRY_KNOWN_TESTS)
const startTime = Date.now()
request(data, options, (err, res, statusCode) => {
distributionMetric(TELEMETRY_KNOWN_TESTS_MS, {}, Date.now() - startTime)
if (err) {
incrementCountMetric(TELEMETRY_KNOWN_TESTS_ERRORS, { statusCode })
done(err)

@@ -74,2 +105,10 @@ } else {

const { data: { attributes: { tests: knownTests } } } = JSON.parse(res)
const numTests = getNumTests(knownTests)
incrementCountMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS, {}, numTests)
distributionMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES, {}, res.length)
log.debug(() => `Number of received known tests: ${numTests}`)
done(null, knownTests)

@@ -76,0 +115,0 @@ } catch (err) {

@@ -15,4 +15,3 @@ 'use strict'

TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
getErrorTypeFromStatusCode
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED
} = require('../../../ci-visibility/telemetry')

@@ -60,6 +59,5 @@

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
{ endpoint: 'code_coverage', errorType }
{ endpoint: 'code_coverage', statusCode }
)

@@ -66,0 +64,0 @@ incrementCountMetric(

@@ -15,4 +15,3 @@ 'use strict'

TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
getErrorTypeFromStatusCode
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED
} = require('../../../ci-visibility/telemetry')

@@ -61,6 +60,5 @@

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
{ endpoint: 'test_cycle', errorType }
{ endpoint: 'test_cycle', statusCode }
)

@@ -67,0 +65,0 @@ incrementCountMetric(

@@ -14,3 +14,4 @@ const fs = require('fs')

isShallowRepository,
unshallowRepository
unshallowRepository,
isGitAvailable
} = require('../../../plugins/util/git')

@@ -28,4 +29,3 @@

TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS,
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES,
getErrorTypeFromStatusCode
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES
} = require('../../../ci-visibility/telemetry')

@@ -97,4 +97,3 @@

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType })
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { statusCode })
const error = new Error(`Error fetching commits to exclude: ${err.message}`)

@@ -184,4 +183,3 @@ return callback(error)

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { errorType })
incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { statusCode })
const error = new Error(`Could not upload packfiles: status code ${statusCode}: ${err.message}`)

@@ -252,2 +250,5 @@ return callback(error, uploadSize)

function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryUrl, callback) {
if (!isGitAvailable()) {
return callback(new Error('Git is not available'))
}
let repositoryUrl = configRepositoryUrl

@@ -254,0 +255,0 @@ if (!repositoryUrl) {

@@ -11,4 +11,3 @@ const request = require('../../exporters/common/request')

TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
getErrorTypeFromStatusCode
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES
} = require('../../ci-visibility/telemetry')

@@ -87,4 +86,3 @@

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS, { errorType })
incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS, { statusCode })
done(err)

@@ -91,0 +89,0 @@ } else {

@@ -10,4 +10,3 @@ const request = require('../../exporters/common/request')

TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS,
TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
getErrorTypeFromStatusCode
TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE
} = require('../telemetry')

@@ -85,4 +84,3 @@

if (err) {
const errorType = getErrorTypeFromStatusCode(statusCode)
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { errorType })
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { statusCode })
done(err)

@@ -89,0 +87,0 @@ } else {

@@ -13,3 +13,6 @@ const telemetryMetrics = require('../telemetry/metrics')

hasCodeOwners: 'has_code_owners',
isUnsupportedCIProvider: 'is_unsupported_ci'
isUnsupportedCIProvider: 'is_unsupported_ci',
isNew: 'is_new',
isRum: 'is_rum',
browserDriver: 'browser_driver'
}

@@ -21,2 +24,10 @@

return Object.keys(tagsDictionary).reduce((acc, tagKey) => {
if (tagKey === 'statusCode') {
const statusCode = tagsDictionary[tagKey]
if (isStatusCode400(statusCode)) {
acc.push(`status_code:${statusCode}`)
}
acc.push(`error_type:${getErrorTypeFromStatusCode(statusCode)}`)
return acc
}
const formattedTagKey = formattedTags[tagKey] || tagKey

@@ -41,2 +52,3 @@ if (tagsDictionary[tagKey] === true) {

// CI Visibility telemetry events
const TELEMETRY_TEST_SESSION = 'test_session'
const TELEMETRY_EVENT_CREATED = 'event_created'

@@ -80,3 +92,13 @@ const TELEMETRY_EVENT_FINISHED = 'event_finished'

const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES = 'itr_skippable_tests.response_bytes'
// early flake detection
const TELEMETRY_KNOWN_TESTS = 'early_flake_detection.request'
const TELEMETRY_KNOWN_TESTS_MS = 'early_flake_detection.request_ms'
const TELEMETRY_KNOWN_TESTS_ERRORS = 'early_flake_detection.request_errors'
const TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS = 'early_flake_detection.response_tests'
const TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES = 'early_flake_detection.response_bytes'
function isStatusCode400 (statusCode) {
return statusCode >= 400 && statusCode < 500
}
function getErrorTypeFromStatusCode (statusCode) {

@@ -95,2 +117,3 @@ if (statusCode >= 400 && statusCode < 500) {

distributionMetric,
TELEMETRY_TEST_SESSION,
TELEMETRY_EVENT_CREATED,

@@ -134,3 +157,7 @@ TELEMETRY_EVENT_FINISHED,

TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
getErrorTypeFromStatusCode
TELEMETRY_KNOWN_TESTS,
TELEMETRY_KNOWN_TESTS_MS,
TELEMETRY_KNOWN_TESTS_ERRORS,
TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS,
TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES
}

@@ -186,3 +186,3 @@ 'use strict'

function propagationStyle (key, option, defaultValue) {
function propagationStyle (key, option) {
// Extract by key if in object-form value

@@ -210,4 +210,12 @@ if (option !== null && typeof option === 'object' && !Array.isArray(option)) {

}
}
return defaultValue
function reformatSpanSamplingRules (rules) {
if (!rules) return rules
return rules.map(rule => {
return remapify(rule, {
sample_rate: 'sampleRate',
max_per_second: 'maxPerSecond'
})
})
}

@@ -234,16 +242,2 @@

const DD_TRACE_MEMCACHED_COMMAND_ENABLED = coalesce(
process.env.DD_TRACE_MEMCACHED_COMMAND_ENABLED,
false
)
const DD_SERVICE_MAPPING = coalesce(
options.serviceMapping,
process.env.DD_SERVICE_MAPPING
? fromEntries(
process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
)
: {}
)
const DD_API_KEY = coalesce(

@@ -254,13 +248,2 @@ process.env.DATADOG_API_KEY,

// TODO: Remove the experimental env vars as a major?
const DD_TRACE_B3_ENABLED = coalesce(
options.experimental && options.experimental.b3,
process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
false
)
const defaultPropagationStyle = ['datadog', 'tracecontext']
if (isTrue(DD_TRACE_B3_ENABLED)) {
defaultPropagationStyle.push('b3')
defaultPropagationStyle.push('b3 single header')
}
if (process.env.DD_TRACE_PROPAGATION_STYLE && (

@@ -279,17 +262,7 @@ process.env.DD_TRACE_PROPAGATION_STYLE_INJECT ||

options.tracePropagationStyle,
defaultPropagationStyle
this._getDefaultPropagationStyle(options)
)
const PROPAGATION_STYLE_EXTRACT = propagationStyle(
'extract',
options.tracePropagationStyle,
defaultPropagationStyle
)
validateOtelPropagators(PROPAGATION_STYLE_INJECT)
const DD_TRACE_PROPAGATION_EXTRACT_FIRST = coalesce(
process.env.DD_TRACE_PROPAGATION_EXTRACT_FIRST,
false
)
if (typeof options.appsec === 'boolean') {

@@ -303,29 +276,2 @@ options.appsec = {

const DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON = coalesce(
maybeFile(options.appsec.blockedTemplateGraphql),
maybeFile(process.env.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
)
const DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING = coalesce(
options.appsec.eventTracking && options.appsec.eventTracking.mode,
process.env.DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
'safe'
).toLowerCase()
const DD_API_SECURITY_ENABLED = coalesce(
options.appsec?.apiSecurity?.enabled,
process.env.DD_API_SECURITY_ENABLED && isTrue(process.env.DD_API_SECURITY_ENABLED),
process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED),
true
)
const DD_API_SECURITY_REQUEST_SAMPLE_RATE = coalesce(
options.appsec?.apiSecurity?.requestSampling,
parseFloat(process.env.DD_API_SECURITY_REQUEST_SAMPLE_RATE),
0.1
)
// 0: disabled, 1: logging, 2: garbage collection + logging
const DD_TRACE_SPAN_LEAK_DEBUG = coalesce(
process.env.DD_TRACE_SPAN_LEAK_DEBUG,
0
)
const DD_INSTRUMENTATION_INSTALL_ID = coalesce(

@@ -344,47 +290,6 @@ process.env.DD_INSTRUMENTATION_INSTALL_ID,

const sampler = {
spanSamplingRules: coalesce(
options.spanSamplingRules,
safeJsonParse(maybeFile(process.env.DD_SPAN_SAMPLING_RULES_FILE)),
safeJsonParse(process.env.DD_SPAN_SAMPLING_RULES),
[]
).map(rule => {
return remapify(rule, {
sample_rate: 'sampleRate',
max_per_second: 'maxPerSecond'
})
})
}
// TODO: refactor
this.apiKey = DD_API_KEY
this.serviceMapping = DD_SERVICE_MAPPING
this.tracePropagationStyle = {
inject: PROPAGATION_STYLE_INJECT,
extract: PROPAGATION_STYLE_EXTRACT,
otelPropagators: process.env.DD_TRACE_PROPAGATION_STYLE ||
process.env.DD_TRACE_PROPAGATION_STYLE_INJECT ||
process.env.DD_TRACE_PROPAGATION_STYLE_EXTRACT
? false
: !!process.env.OTEL_PROPAGATORS
}
this.tracePropagationExtractFirst = isTrue(DD_TRACE_PROPAGATION_EXTRACT_FIRST)
this.sampler = sampler
this.appsec = {
blockedTemplateGraphql: DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
eventTracking: {
enabled: ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING),
mode: DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING
},
apiSecurity: {
enabled: DD_API_SECURITY_ENABLED,
// Coerce value between 0 and 1
requestSampling: Math.min(1, Math.max(0, DD_API_SECURITY_REQUEST_SAMPLE_RATE))
}
}
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
this.isAzureFunction = getIsAzureFunction()
this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
// sent in telemetry event app-started
this.installSignature = {

@@ -463,2 +368,17 @@ id: DD_INSTRUMENTATION_INSTALL_ID,

_getDefaultPropagationStyle (options) {
// TODO: Remove the experimental env vars as a major?
const DD_TRACE_B3_ENABLED = coalesce(
options.experimental && options.experimental.b3,
process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
false
)
const defaultPropagationStyle = ['datadog', 'tracecontext']
if (isTrue(DD_TRACE_B3_ENABLED)) {
defaultPropagationStyle.push('b3')
defaultPropagationStyle.push('b3 single header')
}
return defaultPropagationStyle
}
_isInServerlessEnvironment () {

@@ -489,5 +409,10 @@ const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined

this._setValue(defaults, 'appsec.apiSecurity.enabled', true)
this._setValue(defaults, 'appsec.apiSecurity.requestSampling', 0.1)
this._setValue(defaults, 'appsec.blockedTemplateGraphql', undefined)
this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
this._setValue(defaults, 'appsec.enabled', undefined)
this._setValue(defaults, 'appsec.eventTracking.enabled', true)
this._setValue(defaults, 'appsec.eventTracking.mode', 'safe')
this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)

@@ -528,2 +453,3 @@ this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)

this._setValue(defaults, 'iast.telemetryVerbosity', 'INFORMATION')
this._setValue(defaults, 'isAzureFunction', false)
this._setValue(defaults, 'isCiVisibility', false)

@@ -537,2 +463,3 @@ this._setValue(defaults, 'isEarlyFlakeDetectionEnabled', false)

this._setValue(defaults, 'lookup', undefined)
this._setValue(defaults, 'memcachedCommandEnabled', false)
this._setValue(defaults, 'openAiLogsEnabled', false)

@@ -558,7 +485,10 @@ this._setValue(defaults, 'openaiSpanCharLimit', 128)

this._setValue(defaults, 'sampler.rules', [])
this._setValue(defaults, 'sampler.spanSamplingRules', [])
this._setValue(defaults, 'scope', undefined)
this._setValue(defaults, 'service', service)
this._setValue(defaults, 'serviceMapping', {})
this._setValue(defaults, 'site', 'datadoghq.com')
this._setValue(defaults, 'spanAttributeSchema', 'v0')
this._setValue(defaults, 'spanComputePeerService', false)
this._setValue(defaults, 'spanLeakDebug', 0)
this._setValue(defaults, 'spanRemoveIntegrationFromService', false)

@@ -577,2 +507,6 @@ this._setValue(defaults, 'startupLogs', false)

this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
this._setValue(defaults, 'tracePropagationExtractFirst', false)
this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext'])
this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext'])
this._setValue(defaults, 'tracePropagationStyle.otelPropagators', false)
this._setValue(defaults, 'tracing', true)

@@ -588,3 +522,7 @@ this._setValue(defaults, 'url', undefined)

DD_AGENT_HOST,
DD_API_SECURITY_ENABLED,
DD_API_SECURITY_REQUEST_SAMPLE_RATE,
DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
DD_APPSEC_ENABLED,
DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,

@@ -607,2 +545,3 @@ DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,

DD_ENV,
DD_EXPERIMENTAL_API_SECURITY_ENABLED,
DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,

@@ -634,4 +573,7 @@ DD_EXPERIMENTAL_PROFILING_ENABLED,

DD_SERVICE,
DD_SERVICE_MAPPING,
DD_SERVICE_NAME,
DD_SITE,
DD_SPAN_SAMPLING_RULES,
DD_SPAN_SAMPLING_RULES_FILE,
DD_TAGS,

@@ -656,5 +598,10 @@ DD_TELEMETRY_DEBUG,

DD_TRACE_HEADER_TAGS,
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
DD_TRACE_PEER_SERVICE_MAPPING,
DD_TRACE_PROPAGATION_EXTRACT_FIRST,
DD_TRACE_PROPAGATION_STYLE,
DD_TRACE_PROPAGATION_STYLE_INJECT,
DD_TRACE_PROPAGATION_STYLE_EXTRACT,
DD_TRACE_RATE_LIMIT,

@@ -667,2 +614,3 @@ DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,

DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
DD_TRACE_SPAN_LEAK_DEBUG,
DD_TRACE_STARTUP_LOGS,

@@ -674,7 +622,8 @@ DD_TRACE_TAGS,

DD_VERSION,
OTEL_METRICS_EXPORTER,
OTEL_PROPAGATORS,
OTEL_RESOURCE_ATTRIBUTES,
OTEL_SERVICE_NAME,
OTEL_RESOURCE_ATTRIBUTES,
OTEL_TRACES_SAMPLER,
OTEL_TRACES_SAMPLER_ARG,
OTEL_METRICS_EXPORTER
OTEL_TRACES_SAMPLER_ARG
} = process.env

@@ -691,2 +640,8 @@

this._setBoolean(env, 'appsec.apiSecurity.enabled', coalesce(
DD_API_SECURITY_ENABLED && isTrue(DD_API_SECURITY_ENABLED),
DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(DD_EXPERIMENTAL_API_SECURITY_ENABLED)
))
this._setUnit(env, 'appsec.apiSecurity.requestSampling', DD_API_SECURITY_REQUEST_SAMPLE_RATE)
this._setValue(env, 'appsec.blockedTemplateGraphql', maybeFile(DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON))
this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))

@@ -697,2 +652,7 @@ this._envUnprocessed['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML

this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
if (DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING) {
this._setValue(env, 'appsec.eventTracking.enabled',
['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING.toLowerCase()))
this._setValue(env, 'appsec.eventTracking.mode', DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING.toLowerCase())
}
this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)

@@ -745,4 +705,7 @@ this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)

this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
this._setBoolean(env, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)

@@ -787,2 +750,6 @@ this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))

otelSetRuntimeMetrics)
this._setArray(env, 'sampler.spanSamplingRules', reformatSpanSamplingRules(coalesce(
safeJsonParse(maybeFile(DD_SPAN_SAMPLING_RULES_FILE)),
safeJsonParse(DD_SPAN_SAMPLING_RULES)
)))
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE ||

@@ -795,2 +762,7 @@ getFromOtelSamplerMap(OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG))

this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service || OTEL_SERVICE_NAME)
if (DD_SERVICE_MAPPING) {
this._setValue(env, 'serviceMapping', fromEntries(
process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
))
}
this._setString(env, 'site', DD_SITE)

@@ -801,2 +773,4 @@ if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {

}
// 0: disabled, 1: logging, 2: garbage collection + logging
this._setValue(env, 'spanLeakDebug', maybeInt(DD_TRACE_SPAN_LEAK_DEBUG))
this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)

@@ -825,2 +799,9 @@ this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)

this._setBoolean(env, 'traceId128BitLoggingEnabled', DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
this._setBoolean(env, 'tracePropagationExtractFirst', DD_TRACE_PROPAGATION_EXTRACT_FIRST)
this._setBoolean(env, 'tracePropagationStyle.otelPropagators',
DD_TRACE_PROPAGATION_STYLE ||
DD_TRACE_PROPAGATION_STYLE_INJECT ||
DD_TRACE_PROPAGATION_STYLE_EXTRACT
? false
: !!OTEL_PROPAGATORS)
this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)

@@ -839,2 +820,5 @@ this._setString(env, 'version', DD_VERSION || tags.version)

this._setBoolean(opts, 'appsec.apiSecurity.enabled', options.appsec.apiSecurity?.enabled)
this._setUnit(opts, 'appsec.apiSecurity.requestSampling', options.appsec.apiSecurity?.requestSampling)
this._setValue(opts, 'appsec.blockedTemplateGraphql', maybeFile(options.appsec.blockedTemplateGraphql))
this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))

@@ -845,2 +829,8 @@ this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml

this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
let eventTracking = options.appsec.eventTracking?.mode
if (eventTracking) {
eventTracking = eventTracking.toLowerCase()
this._setValue(opts, 'appsec.eventTracking.enabled', ['extended', 'safe'].includes(eventTracking))
this._setValue(opts, 'appsec.eventTracking.mode', eventTracking)
}
this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)

@@ -911,2 +901,3 @@ this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)

this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
this._setArray(opts, 'sampler.spanSamplingRules', reformatSpanSamplingRules(options.spanSamplingRules))
this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))

@@ -917,2 +908,3 @@ const ingestion = options.ingestion || {}

this._setString(opts, 'service', options.service || tags.service)
this._setValue(opts, 'serviceMapping', options.serviceMapping)
this._setString(opts, 'site', options.site)

@@ -1027,3 +1019,4 @@ if (options.spanAttributeSchema) {

const {
DD_CIVISIBILITY_AGENTLESS_URL
DD_CIVISIBILITY_AGENTLESS_URL,
DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED
} = process.env

@@ -1038,3 +1031,3 @@

this._setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
coalesce(process.env.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
coalesce(DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))

@@ -1048,2 +1041,15 @@ this._setBoolean(calc, 'isManualApiEnabled', this._isCiVisibilityManualApiEnabled())

this._setBoolean(calc, 'stats.enabled', this._isTraceStatsComputationEnabled())
const defaultPropagationStyle = this._getDefaultPropagationStyle(this._optionsArg)
this._setValue(calc, 'tracePropagationStyle.inject', propagationStyle(
'inject',
this._optionsArg.tracePropagationStyle
))
this._setValue(calc, 'tracePropagationStyle.extract', propagationStyle(
'extract',
this._optionsArg.tracePropagationStyle
))
if (defaultPropagationStyle.length > 2) {
calc['tracePropagationStyle.inject'] = calc['tracePropagationStyle.inject'] || defaultPropagationStyle
calc['tracePropagationStyle.extract'] = calc['tracePropagationStyle.extract'] || defaultPropagationStyle
}
}

@@ -1050,0 +1056,0 @@

@@ -5,2 +5,3 @@ 'use strict'

const { trace, ROOT_CONTEXT } = require('@opentelemetry/api')
const DataDogSpanContext = require('../opentracing/span_context')

@@ -10,31 +11,2 @@ const SpanContext = require('./span_context')

// Horrible hack to acquire the otherwise inaccessible SPAN_KEY so we can redirect it...
// This is used for getting the current span context in OpenTelemetry, but the SPAN_KEY value is
// not exposed as it's meant to be read-only from outside the module. We want to hijack this logic
// so we can instead get the span context from the datadog context manager instead.
let SPAN_KEY
trace.getSpan({
getValue (key) {
SPAN_KEY = key
}
})
// Whenever a value is acquired from the context map we should mostly delegate to the real getter,
// but when accessing the current span we should hijack that access to instead provide a fake span
// which we can use to get an OTel span context wrapping the datadog active scope span context.
function wrappedGetValue (target) {
return (key) => {
if (key === SPAN_KEY) {
return {
spanContext () {
const activeSpan = tracer.scope().active()
const context = activeSpan && activeSpan.context()
return new SpanContext(context)
}
}
}
return target.getValue(key)
}
}
class ContextManager {

@@ -46,9 +18,18 @@ constructor () {

active () {
const active = this._store.getStore() || ROOT_CONTEXT
const activeSpan = tracer.scope().active()
const store = this._store.getStore()
const context = (activeSpan && activeSpan.context()) || store || ROOT_CONTEXT
return new Proxy(active, {
get (target, key) {
return key === 'getValue' ? wrappedGetValue(target) : target[key]
}
})
if (!(context instanceof DataDogSpanContext)) {
return context
}
if (!context._otelSpanContext) {
const newSpanContext = new SpanContext(context)
context._otelSpanContext = newSpanContext
}
if (store && trace.getSpanContext(store) === context._otelSpanContext) {
return store
}
return trace.setSpanContext(store || ROOT_CONTEXT, context._otelSpanContext)
}

@@ -59,6 +40,10 @@

const ddScope = tracer.scope()
return ddScope.activate(span._ddSpan, () => {
const run = () => {
const cb = thisArg == null ? fn : fn.bind(thisArg)
return this._store.run(context, cb, ...args)
})
}
if (span && span._ddSpan) {
return ddScope.activate(span._ddSpan, run)
}
return run()
}

@@ -73,7 +58,5 @@

// Not part of the spec but the Node.js API expects these
enable () {}
disable () {}
}
module.exports = ContextManager

@@ -27,7 +27,7 @@ 'use strict'

get traceId () {
return this._ddContext._traceId.toString(16)
return this._ddContext.toTraceId(true)
}
get spanId () {
return this._ddContext._spanId.toString(16)
return this._ddContext.toSpanId(true)
}

@@ -34,0 +34,0 @@

'use strict'
const { trace, context } = require('@opentelemetry/api')
const { trace, context, propagation } = require('@opentelemetry/api')
const { W3CTraceContextPropagator } = require('@opentelemetry/core')

@@ -55,2 +56,9 @@ const tracer = require('../../')

}
// The default propagator used is the W3C Trace Context propagator, users should be able to pass in others
// as needed
if (config.propagator) {
propagation.setGlobalPropagator(config.propagator)
} else {
propagation.setGlobalPropagator(new W3CTraceContextPropagator())
}
}

@@ -57,0 +65,0 @@

@@ -10,2 +10,3 @@ 'use strict'

const SpanContext = require('./span_context')
const TextMapPropagator = require('../opentracing/propagation/text_map')

@@ -26,2 +27,20 @@ class Tracer {

_createSpanContextFromParent (parentSpanContext) {
return new SpanContext({
traceId: parentSpanContext._traceId,
spanId: id(),
parentId: parentSpanContext._spanId,
sampling: parentSpanContext._sampling,
baggageItems: Object.assign({}, parentSpanContext._baggageItems),
trace: parentSpanContext._trace,
tracestate: parentSpanContext._tracestate
})
}
// Extracted method to create span context for a new span
_createSpanContextForNewSpan (context) {
const { traceId, spanId, traceFlags, traceState } = context
return TextMapPropagator._convertOtelContextToDatadog(traceId, spanId, traceFlags, traceState)
}
startSpan (name, options = {}, context = api.context.active()) {

@@ -34,17 +53,7 @@ // remove span from context in case a root span is requested via options

const parentSpanContext = parentSpan && parentSpan.spanContext()
let spanContext
// TODO: Need a way to get 128-bit trace IDs for the validity check API to work...
// if (parent && api.trace.isSpanContextValid(parent)) {
if (parentSpanContext && parentSpanContext.traceId) {
const parent = parentSpanContext._ddContext
spanContext = new SpanContext({
traceId: parent._traceId,
spanId: id(),
parentId: parent._spanId,
sampling: parent._sampling,
baggageItems: Object.assign({}, parent._baggageItems),
trace: parent._trace,
tracestate: parent._tracestate
})
if (parentSpanContext && api.trace.isSpanContextValid(parentSpanContext)) {
spanContext = parentSpanContext._ddContext
? this._createSpanContextFromParent(parentSpanContext._ddContext)
: this._createSpanContextForNewSpan(parentSpanContext)
} else {

@@ -51,0 +60,0 @@ spanContext = new SpanContext()

@@ -18,3 +18,3 @@ 'use strict'

if (this._config.traceId128BitLoggingEnabled && spanContext._trace.tags['_dd.p.tid']) {
carrier.dd.trace_id = spanContext._trace.tags['_dd.p.tid'] + spanContext._traceId.toString(16)
carrier.dd.trace_id = spanContext.toTraceId(true)
} else {

@@ -21,0 +21,0 @@ carrier.dd.trace_id = spanContext.toTraceId()

@@ -6,2 +6,3 @@ 'use strict'

const DatadogSpanContext = require('../span_context')
const OtelSpanContext = require('../../opentelemetry/span_context')
const log = require('../../log')

@@ -622,4 +623,63 @@ const TraceState = require('./tracestate')

}
static _convertOtelContextToDatadog (traceId, spanId, traceFlag, ts, meta = {}) {
const origin = null
let samplingPriority = traceFlag
ts = ts?.traceparent || null
if (ts) {
// Use TraceState.fromString to parse the tracestate header
const traceState = TraceState.fromString(ts)
let ddTraceStateData = null
// Extract Datadog specific trace state data
traceState.forVendor('dd', (state) => {
ddTraceStateData = state
return state // You might need to adjust this part based on actual logic needed
})
if (ddTraceStateData) {
// Assuming ddTraceStateData is now a Map or similar structure containing Datadog trace state data
// Extract values as needed, similar to the original logic
const samplingPriorityTs = ddTraceStateData.get('s')
const origin = ddTraceStateData.get('o')
// Convert Map to object for meta
const otherPropagatedTags = Object.fromEntries(ddTraceStateData.entries())
// Update meta and samplingPriority based on extracted values
Object.assign(meta, otherPropagatedTags)
samplingPriority = TextMapPropagator._getSamplingPriority(traceFlag, parseInt(samplingPriorityTs, 10), origin)
} else {
log.debug(`no dd list member in tracestate from incoming request: ${ts}`)
}
}
const spanContext = new OtelSpanContext({
traceId: id(traceId, 16), spanId: id(), tags: meta, parentId: id(spanId, 16)
})
spanContext._sampling = { priority: samplingPriority }
spanContext._trace = { origin }
return spanContext
}
static _getSamplingPriority (traceparentSampled, tracestateSamplingPriority, origin = null) {
const fromRumWithoutPriority = !tracestateSamplingPriority && origin === 'rum'
let samplingPriority
if (!fromRumWithoutPriority && traceparentSampled === 0 &&
(!tracestateSamplingPriority || tracestateSamplingPriority >= 0)) {
samplingPriority = 0
} else if (!fromRumWithoutPriority && traceparentSampled === 1 &&
(!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
samplingPriority = 1
} else {
samplingPriority = tracestateSamplingPriority
}
return samplingPriority
}
}
module.exports = TextMapPropagator

@@ -30,2 +30,3 @@ 'use strict'

}
this._otelSpanContext = undefined
}

@@ -32,0 +33,0 @@

@@ -148,3 +148,3 @@ const {

testFramework,
isUnsupportedCIProvider: this.isUnsupportedCIProvider,
isUnsupportedCIProvider: !this.ciProviderName,
...tags

@@ -183,3 +183,3 @@ })

this.isUnsupportedCIProvider = !ciProviderName
this.ciProviderName = ciProviderName

@@ -186,0 +186,0 @@ this.testConfiguration = {

@@ -72,2 +72,3 @@ 'use strict'

get 'node:net' () { return require('../../../datadog-plugin-net/src') },
get nyc () { return require('../../../datadog-plugin-nyc/src') },
get oracledb () { return require('../../../datadog-plugin-oracledb/src') },

@@ -74,0 +75,0 @@ get openai () { return require('../../../datadog-plugin-openai/src') },

@@ -80,2 +80,14 @@ const cp = require('child_process')

function isGitAvailable () {
const isWindows = os.platform() === 'win32'
const command = isWindows ? 'where' : 'which'
try {
cp.execFileSync(command, ['git'], { stdio: 'pipe' })
return true
} catch (e) {
incrementCountMetric(TELEMETRY_GIT_COMMAND_ERRORS, { command: 'check_git', exitCode: 'missing' })
return false
}
}
function isShallowRepository () {

@@ -346,3 +358,4 @@ return sanitizedExec(

isShallowRepository,
unshallowRepository
unshallowRepository,
isGitAvailable
}

@@ -320,3 +320,3 @@ 'use strict'

const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping'])
const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping', 'serviceMapping'])

@@ -323,0 +323,0 @@ const configuration = []

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc