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 4.45.0 to 4.46.0

6

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

@@ -75,3 +75,3 @@ "main": "index.js",

"dependencies": {
"@datadog/native-appsec": "8.0.1",
"@datadog/native-appsec": "8.1.1",
"@datadog/native-iast-rewriter": "2.4.1",

@@ -110,3 +110,3 @@ "@datadog/native-iast-taint-tracking": "3.1.0",

"aws-sdk": "^2.1446.0",
"axios": "^1.6.7",
"axios": "^1.7.4",
"benchmark": "^2.1.4",

@@ -113,0 +113,0 @@ "body-parser": "^1.20.2",

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

commandFactory => {
return shimmer.wrap(commandFactory, wrapCreateCommand(commandFactory))
return shimmer.wrapFunction(commandFactory, f => wrapCreateCommand(f))
})

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

return shimmer.wrap(originalMiddleware, function (req, res, next) {
return shimmer.wrapFunction(originalMiddleware, originalMiddleware => function (req, res, next) {
if (!graphqlMiddlewareChannel.start.hasSubscribers) {

@@ -61,0 +61,0 @@ return originalMiddleware.apply(this, arguments)

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

if (typeof cb === 'function') {
args[args.length - 1] = function (err, result) {
args[args.length - 1] = shimmer.wrapFunction(cb, cb => function (err, result) {
const message = getMessage(request, err, result)

@@ -93,3 +93,3 @@

})
}
})
} else { // always a promise

@@ -118,3 +118,3 @@ return send.call(this, command, ...args)

// eslint-disable-next-line n/handle-callback-err
return function wrappedCb (err, response) {
return shimmer.wrapFunction(cb, cb => function wrappedCb (err, response) {
const obj = { request, response }

@@ -147,3 +147,3 @@ return ar.runInAsyncScope(() => {

})
}
})
}

@@ -150,0 +150,0 @@

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

function publishRequestBodyAndNext (req, res, next) {
return function () {
return shimmer.wrapFunction(next, next => function () {
if (bodyParserReadCh.hasSubscribers && req) {

@@ -21,3 +21,3 @@ const abortController = new AbortController()

return next.apply(this, arguments)
}
})
}

@@ -30,3 +30,3 @@

}, read => {
return shimmer.wrap(read, function (req, res, next) {
return shimmer.wrapFunction(read, read => function (req, res, next) {
const nextResource = new AsyncResource('bound-anonymous-fn')

@@ -43,3 +43,3 @@ arguments[2] = nextResource.bind(publishRequestBodyAndNext(req, res, next))

}, read => {
return shimmer.wrap(read, function (req, res, next) {
return shimmer.wrapFunction(read, read => function (req, res, next) {
arguments[2] = publishRequestBodyAndNext(req, res, next)

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

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

function wrapCallback (finishCh, errorCh, asyncResource, callback) {
return asyncResource.bind(function (err) {
return shimmer.wrapFunction(callback, callback => asyncResource.bind(function (err) {
finish(finishCh, errorCh, err)

@@ -189,3 +189,3 @@ if (callback) {

}
})
}))
}

@@ -192,0 +192,0 @@

@@ -136,4 +136,4 @@ 'use strict'

const wrapedChildProcessCustomPromisifyMethod =
shimmer.wrap(childProcessMethod[util.promisify.custom],
wrapChildProcessCustomPromisifyMethod(childProcessMethod[util.promisify.custom]), shell)
shimmer.wrapFunction(childProcessMethod[util.promisify.custom],
promisify => wrapChildProcessCustomPromisifyMethod(promisify, shell))

@@ -140,0 +140,0 @@ // should do it in this way because the original property is readonly

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

return shimmer.wrap(original, function () {
return shimmer.wrapFunction(original, original => function () {
if (!enterChannel.hasSubscribers) return original.apply(this, arguments)

@@ -94,3 +94,3 @@

function wrapNext (req, next) {
return function (error) {
return shimmer.wrapFunction(next, next => function (error) {
if (error) {

@@ -104,7 +104,7 @@ errorChannel.publish({ req, error })

next.apply(this, arguments)
}
})
}
addHook({ name: 'connect', versions: ['>=3'] }, connect => {
return shimmer.wrap(connect, wrapConnect(connect))
return shimmer.wrapFunction(connect, connect => wrapConnect(connect))
})

@@ -111,0 +111,0 @@

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

function publishRequestCookieAndNext (req, res, next) {
return function cookieParserWrapper () {
return shimmer.wrapFunction(next, next => function cookieParserWrapper () {
if (cookieParserReadCh.hasSubscribers && req) {

@@ -22,3 +22,3 @@ const abortController = new AbortController()

return next.apply(this, arguments)
}
})
}

@@ -30,6 +30,6 @@

}, cookieParser => {
return shimmer.wrap(cookieParser, function () {
return shimmer.wrapFunction(cookieParser, cookieParser => function () {
const cookieMiddleware = cookieParser.apply(this, arguments)
return shimmer.wrap(cookieMiddleware, function (req, res, next) {
return shimmer.wrapFunction(cookieMiddleware, cookieMiddleware => function (req, res, next) {
arguments[2] = publishRequestCookieAndNext(req, res, next)

@@ -36,0 +36,0 @@ return cookieMiddleware.apply(this, arguments)

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

}
return shimmer.wrap(_maybeInvoke, wrapped)
return wrapped
}

@@ -55,3 +55,3 @@

}
return shimmer.wrap(query, wrapped)
return wrapped
}

@@ -81,3 +81,3 @@

arguments[callbackIndex] = asyncResource.bind(function (error, result) {
arguments[callbackIndex] = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (error, result) {
if (error) {

@@ -88,3 +88,3 @@ errorCh.publish(error)

return cb.apply(this, arguments)
})
}))

@@ -101,3 +101,3 @@ try {

}
return shimmer.wrap(fn, wrapped)
return wrapped
}

@@ -126,3 +126,3 @@

const cb = callbackResource.bind(args[cbIndex])
args[cbIndex] = asyncResource.bind(function (error, result) {
args[cbIndex] = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (error, result) {
if (error) {

@@ -133,3 +133,3 @@ errorCh.publish(error)

return cb.apply(thisArg, arguments)
})
}))
}

@@ -176,4 +176,4 @@ const res = fn.apply(thisArg, args)

Bucket.prototype._maybeInvoke = wrapMaybeInvoke(Bucket.prototype._maybeInvoke)
Bucket.prototype.query = wrapQuery(Bucket.prototype.query)
shimmer.wrap(Bucket.prototype, '_maybeInvoke', maybeInvoke => wrapMaybeInvoke(maybeInvoke))
shimmer.wrap(Bucket.prototype, 'query', query => wrapQuery(query))

@@ -214,3 +214,3 @@ shimmer.wrap(Bucket.prototype, '_n1qlReq', _n1qlReq => function (host, q, adhoc, emitter) {

wrapAllNames(['upsert', 'insert', 'replace', 'append', 'prepend'], name => {
Bucket.prototype[name] = wrap(`apm:couchbase:${name}`, Bucket.prototype[name])
shimmer.wrap(Bucket.prototype, name, fn => wrap(`apm:couchbase:${name}`, fn))
})

@@ -222,4 +222,4 @@

addHook({ name: 'couchbase', file: 'lib/cluster.js', versions: ['^2.6.12'] }, Cluster => {
Cluster.prototype._maybeInvoke = wrapMaybeInvoke(Cluster.prototype._maybeInvoke)
Cluster.prototype.query = wrapQuery(Cluster.prototype.query)
shimmer.wrap(Cluster.prototype, '_maybeInvoke', maybeInvoke => wrapMaybeInvoke(maybeInvoke))
shimmer.wrap(Cluster.prototype, 'query', query => wrapQuery(query))

@@ -226,0 +226,0 @@ shimmer.wrap(Cluster.prototype, 'openBucket', openBucket => {

'use strict'
const { createCoverageMap } = require('istanbul-lib-coverage')
const { NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')
const { addHook, channel, AsyncResource } = require('./helpers/instrument')

@@ -69,2 +68,3 @@ const shimmer = require('../../datadog-shimmer')

let isFlakyTestRetriesEnabled = false
let numTestRetries = 0
let knownTests = []

@@ -192,3 +192,3 @@ let skippedSuites = []

try {
this.eventBroadcaster.on('envelope', (testCase) => {
this.eventBroadcaster.on('envelope', shimmer.wrapFunction(null, () => (testCase) => {
// Only supported from >=8.0.0

@@ -211,3 +211,3 @@ if (testCase?.testCaseFinished) {

}
})
}))
let promise

@@ -313,2 +313,3 @@

isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
numTestRetries = configurationResponse.libraryConfig?.flakyTestRetriesCount

@@ -351,4 +352,4 @@ if (isEarlyFlakeDetectionEnabled) {

if (isFlakyTestRetriesEnabled && !this.options.retry) {
this.options.retry = NUM_FAILED_TEST_RETRIES
if (isFlakyTestRetriesEnabled && !this.options.retry && numTestRetries > 0) {
this.options.retry = numTestRetries
}

@@ -355,0 +356,0 @@

@@ -24,6 +24,6 @@ 'use strict'

addHook({ name: names }, dns => {
dns.lookup = wrap('apm:dns:lookup', dns.lookup, 2)
dns.lookupService = wrap('apm:dns:lookup_service', dns.lookupService, 3)
dns.resolve = wrap('apm:dns:resolve', dns.resolve, 2)
dns.reverse = wrap('apm:dns:reverse', dns.reverse, 2)
shimmer.wrap(dns, 'lookup', fn => wrap('apm:dns:lookup', fn, 2))
shimmer.wrap(dns, 'lookupService', fn => wrap('apm:dns:lookup_service', fn, 2))
shimmer.wrap(dns, 'resolve', fn => wrap('apm:dns:resolve', fn, 2))
shimmer.wrap(dns, 'reverse', fn => wrap('apm:dns:reverse', fn, 2))

@@ -33,4 +33,4 @@ patchResolveShorthands(dns)

if (dns.Resolver) {
dns.Resolver.prototype.resolve = wrap('apm:dns:resolve', dns.Resolver.prototype.resolve, 2)
dns.Resolver.prototype.reverse = wrap('apm:dns:reverse', dns.Resolver.prototype.reverse, 2)
shimmer.wrap(dns.Resolver.prototype, 'resolve', fn => wrap('apm:dns:resolve', fn, 2))
shimmer.wrap(dns.Resolver.prototype, 'reverse', fn => wrap('apm:dns:reverse', fn, 2))

@@ -48,3 +48,3 @@ patchResolveShorthands(dns.Resolver.prototype)

rrtypeMap.set(prototype[method], rrtypes[method])
prototype[method] = wrap('apm:dns:resolve', prototype[method], 2, rrtypes[method])
shimmer.wrap(prototype, method, fn => wrap('apm:dns:resolve', fn, 2, rrtypes[method]))
})

@@ -78,3 +78,3 @@ }

arguments[arguments.length - 1] = asyncResource.bind(function (error, result) {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (error, result) {
if (error) {

@@ -85,3 +85,3 @@ errorCh.publish(error)

cb.apply(this, arguments)
})
}))

@@ -100,3 +100,3 @@ try {

return shimmer.wrap(fn, wrapped)
return wrapped
}

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

const cb = arguments[0]
arguments[0] = function (err, connection) {
arguments[0] = shimmer.wrapFunction(cb, cb => function (err, connection) {
if (connectCh.hasSubscribers && connection && connection.host) {

@@ -57,3 +57,3 @@ connectCh.publish({ hostname: connection.host.host, port: connection.host.port })

cb(err, connection)
}
})
}

@@ -91,6 +91,6 @@ return request.apply(this, arguments)

arguments[lastIndex] = asyncResource.bind(function (error) {
arguments[lastIndex] = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (error) {
finish(params, error)
return cb.apply(null, arguments)
})
}))
return request.apply(this, arguments)

@@ -97,0 +97,0 @@ } else {

@@ -25,6 +25,6 @@ 'use strict'

return shimmer.wrap(expressMongoSanitize, function () {
return shimmer.wrapFunction(expressMongoSanitize, expressMongoSanitize => function () {
const middleware = expressMongoSanitize.apply(this, arguments)
return shimmer.wrap(middleware, function (req, res, next) {
return shimmer.wrapFunction(middleware, middleware => function (req, res, next) {
if (!sanitizeMiddlewareFinished.hasSubscribers) {

@@ -34,3 +34,3 @@ return middleware.apply(this, arguments)

const wrappedNext = shimmer.wrap(next, function () {
const wrappedNext = shimmer.wrapFunction(next, next => function () {
sanitizeMiddlewareFinished.publish({

@@ -37,0 +37,0 @@ sanitizedProperties: propertiesToSanitize,

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

function publishQueryParsedAndNext (req, res, next) {
return function () {
return shimmer.wrapFunction(next, next => function () {
if (queryParserReadCh.hasSubscribers && req) {

@@ -64,3 +64,3 @@ const abortController = new AbortController()

return next.apply(this, arguments)
}
})
}

@@ -73,6 +73,6 @@

}, query => {
return shimmer.wrap(query, function () {
return shimmer.wrapFunction(query, query => function () {
const queryMiddleware = query.apply(this, arguments)
return shimmer.wrap(queryMiddleware, function (req, res, next) {
return shimmer.wrapFunction(queryMiddleware, queryMiddleware => function (req, res, next) {
arguments[2] = publishQueryParsedAndNext(req, res, next)

@@ -79,0 +79,0 @@ return queryMiddleware.apply(this, arguments)

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

function wrapAddHook (addHook) {
return function addHookWithTrace (name, fn) {
return shimmer.wrapFunction(addHook, addHook => function addHookWithTrace (name, fn) {
fn = arguments[arguments.length - 1]

@@ -43,3 +43,3 @@

arguments[arguments.length - 1] = shimmer.wrap(fn, function (request, reply, done) {
arguments[arguments.length - 1] = shimmer.wrapFunction(fn, fn => function (request, reply, done) {
const req = getReq(request)

@@ -83,3 +83,3 @@

return addHook.apply(this, arguments)
}
})
}

@@ -157,3 +157,3 @@

addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
const wrapped = shimmer.wrap(fastify, wrapFastify(fastify, true))
const wrapped = shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true))

@@ -167,7 +167,7 @@ wrapped.fastify = wrapped

addHook({ name: 'fastify', versions: ['2'] }, fastify => {
return shimmer.wrap(fastify, wrapFastify(fastify, true))
return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true))
})
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
return shimmer.wrap(fastify, wrapFastify(fastify, false))
return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, false))
})

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

globalThis.fetch = shimmer.wrap(fetch, wrapFetch(fetch))
globalThis.fetch = shimmer.wrapFunction(fetch, fetch => wrapFetch(fetch))
}

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

const handler = arguments[index]
const wrapper = function (req) {
const wrapper = shimmer.wrapFunction(handler, handler => function (req) {
routeChannel.publish({ req, route: path })
return handler.apply(this, arguments)
}
})

@@ -19,0 +19,0 @@ if (typeof handler === 'function') {

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

arguments[lastIndex] = innerResource.bind(function (e) {
arguments[lastIndex] = shimmer.wrapFunction(cb, cb => innerResource.bind(function (e) {
if (e !== null && typeof e === 'object') { // fs.exists receives a boolean

@@ -283,3 +283,3 @@ errorChannel.publish(e)

return outerResource.runInAsyncScope(() => cb.apply(this, arguments))
})
}))
}

@@ -286,0 +286,0 @@

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

arguments[arguments.length - 1] = innerAsyncResource.bind(function (error) {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => innerAsyncResource.bind(function (error) {
if (error) {

@@ -88,3 +88,3 @@ requestErrorCh.publish(error)

return outerAsyncResource.runInAsyncScope(() => cb.apply(this, arguments))
})
}))

@@ -91,0 +91,0 @@ return method.apply(this, arguments)

@@ -91,9 +91,7 @@ 'use strict'

const wrapped = function () {
const wrapped = shimmer.wrapFunction(method, method => function () {
const args = ensureMetadata(this, arguments, 1)
return callMethod(this, method, args, path, args[1], type, hasPeer)
}
})
Object.assign(wrapped, method)
patched.add(wrapped)

@@ -105,3 +103,3 @@

function wrapCallback (ctx, callback = () => { }) {
return function (err) {
return shimmer.wrapFunction(callback, callback => function (err) {
if (err) {

@@ -116,3 +114,3 @@ ctx.error = err

})
}
})
}

@@ -119,0 +117,0 @@

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

function wrapCallback (callback = () => {}, call, ctx, onCancel) {
return function (err, value, trailer, flags) {
return shimmer.wrapFunction(callback, callback => function (err, value, trailer, flags) {
if (err) {

@@ -140,3 +140,3 @@ ctx.error = err

})
}
})
}

@@ -143,0 +143,0 @@

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

@@ -9,3 +10,3 @@ const handleChannel = channel('apm:hapi:request:handle')

const errorChannel = channel('apm:hapi:request:error')
const enterChannel = channel('apm:hapi:extension:enter')
const hapiTracingChannel = tracingChannel('apm:hapi:extension')

@@ -31,3 +32,3 @@ function wrapServer (server) {

function wrapStart (start) {
return function () {
return shimmer.wrapFunction(start, start => function () {
if (this && typeof this.ext === 'function') {

@@ -38,7 +39,7 @@ this.ext('onPreResponse', onPreResponse)

return start.apply(this, arguments)
}
})
}
function wrapExt (ext) {
return function (events, method, options) {
return shimmer.wrapFunction(ext, ext => function (events, method, options) {
if (events !== null && typeof events === 'object') {

@@ -51,3 +52,3 @@ arguments[0] = wrapEvents(events)

return ext.apply(this, arguments)
}
})
}

@@ -98,3 +99,3 @@

return function (request, h) {
return shimmer.wrapFunction(handler, handler => function (request, h) {
const req = request && request.raw && request.raw.req

@@ -104,10 +105,6 @@

const asyncResource = new AsyncResource('bound-anonymous-fn')
return asyncResource.runInAsyncScope(() => {
enterChannel.publish({ req })
return hapiTracingChannel.traceSync(() => {
return handler.apply(this, arguments)
})
}
})
}

@@ -114,0 +111,0 @@

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

}
if (!Object.hasOwnProperty(namesAndSuccesses, name)) {
if (typeof namesAndSuccesses[`${name}@${version}`] === 'undefined') {
namesAndSuccesses[`${name}@${version}`] = false

@@ -104,0 +104,0 @@ }

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

if (callback) {
callback = function () {
callback = shimmer.wrapFunction(args.callback, cb => function () {
return asyncStartChannel.runStores(ctx, () => {
return args.callback.apply(this, arguments)
return cb.apply(this, arguments)
})
}
})
}

@@ -62,0 +62,0 @@

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

removeEfdStringFromTestName,
getIsFaultyEarlyFlakeDetection,
NUM_FAILED_TEST_RETRIES
getIsFaultyEarlyFlakeDetection
} = require('../../dd-trace/src/plugins/util/test')

@@ -136,2 +135,3 @@ const {

this.isFlakyTestRetriesEnabled = this.testEnvironmentOptions._ddIsFlakyTestRetriesEnabled
this.flakyTestRetriesCount = this.testEnvironmentOptions._ddFlakyTestRetriesCount

@@ -154,3 +154,3 @@ if (this.isEarlyFlakeDetectionEnabled) {

if (!currentNumRetries) {
this.global[RETRY_TIMES] = NUM_FAILED_TEST_RETRIES
this.global[RETRY_TIMES] = this.flakyTestRetriesCount
}

@@ -644,3 +644,3 @@ }

const adapter = jestAdapter.default ? jestAdapter.default : jestAdapter
const newAdapter = shimmer.wrap(adapter, function () {
const newAdapter = shimmer.wrapFunction(adapter, adapter => function () {
const environment = arguments[2]

@@ -780,2 +780,3 @@ if (!environment) {

_ddIsFlakyTestRetriesEnabled,
_ddFlakyTestRetriesCount,
...restOfTestEnvironmentOptions

@@ -782,0 +783,0 @@ } = testEnvironmentOptions

@@ -84,6 +84,6 @@ 'use strict'

return function () {
return shimmer.wrapFunction(callback, callback => function () {
finish()
callback.apply(this, arguments)
}
})
}

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

const handler = shimmer.wrap(middleware, wrapMiddleware(middleware, layer))
const handler = shimmer.wrapFunction(middleware, middleware => wrapMiddleware(middleware, layer))

@@ -88,3 +88,3 @@ originals.set(handler, middleware)

return function (ctx, next) {
return shimmer.wrapFunction(fn, fn => function (ctx, next) {
if (!ctx || !enterChannel.hasSubscribers) return fn.apply(this, arguments)

@@ -127,3 +127,3 @@

}
}
})
}

@@ -148,7 +148,7 @@

function wrapNext (req, next) {
return function () {
return shimmer.wrapFunction(next, next => function () {
nextChannel.publish({ req })
return next.apply(this, arguments)
}
})
}

@@ -155,0 +155,0 @@

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

// eslint-disable-next-line n/handle-callback-err
arguments[callbackIndex] = shimmer.wrap(callback, function (err, corkedEmitter) {
arguments[callbackIndex] = shimmer.wrapFunction(callback, callback => function (err, corkedEmitter) {
if (corkedEmitter !== null && typeof corkedEmitter === 'object' && typeof corkedEmitter.on === 'function') {

@@ -83,0 +83,0 @@ wrapEmitter(corkedEmitter)

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

function wrapCommandStart (start, callbackResource) {
return function () {
return shimmer.wrapFunction(start, start => function () {
if (!startCh.hasSubscribers) return start.apply(this, arguments)

@@ -48,3 +48,3 @@

})
}
})
}

@@ -103,3 +103,3 @@

arguments[arguments.length - 1] = asyncResource.bind(function (err) {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (err) {
if (err) {

@@ -114,3 +114,3 @@ errorCh.publish(err)

}
})
}))

@@ -126,3 +126,3 @@ return asyncResource.runInAsyncScope(() => {

function wrapConnection (Connection, promiseMethod) {
function wrapConnection (promiseMethod, Connection) {
return function (options) {

@@ -178,11 +178,11 @@ Connection.apply(this, arguments)

addHook({ name, file: 'lib/connection.js', versions: ['>=2.5.2 <3'] }, (Connection) => {
return shimmer.wrap(Connection, wrapConnection(Connection, '_queryPromise'))
return shimmer.wrapFunction(Connection, wrapConnection.bind(null, '_queryPromise'))
})
addHook({ name, file: 'lib/connection.js', versions: ['>=2.0.4 <=2.5.1'] }, (Connection) => {
return shimmer.wrap(Connection, wrapConnection(Connection, 'query'))
return shimmer.wrapFunction(Connection, wrapConnection.bind(null, 'query'))
})
addHook({ name, file: 'lib/pool-base.js', versions: ['>=2.0.4 <3'] }, (PoolBase) => {
return shimmer.wrap(PoolBase, wrapPoolBase(PoolBase))
return shimmer.wrapFunction(PoolBase, wrapPoolBase)
})

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

query.callback = asyncResource.bind(function (err) {
query.callback = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (err) {
if (err) {

@@ -37,3 +37,3 @@ errorCh.publish(err)

return callback.apply(this, arguments)
})
}))
startCh.publish({ client, server, query })

@@ -40,0 +40,0 @@

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

function wrapNext (req, res, next) {
return function nextWithTrace (err) {
return shimmer.wrapFunction(next, next => function nextWithTrace (err) {
const requestResource = requestResources.get(req)

@@ -58,11 +58,11 @@

return next.apply(this, arguments)
}
})
}
addHook({ name, versions, file: 'lib/config-proxy-middleware.js' }, configProxyFactory => {
return shimmer.wrap(configProxyFactory, wrapConfigProxyFactory(configProxyFactory))
return shimmer.wrapFunction(configProxyFactory, wrapConfigProxyFactory)
})
addHook({ name, versions, file: 'lib/plugins-middleware.js' }, pluginsFactory => {
return shimmer.wrap(pluginsFactory, wrapPluginsFactory(pluginsFactory))
return shimmer.wrapFunction(pluginsFactory, wrapPluginsFactory)
})

@@ -6,1 +6,5 @@ if (process.env.MOCHA_WORKER_ID) {

}
// TODO add appropriate calls to wrapFunction whenever we're adding a callback
// wrapper. Right now this is less of an issue since that only has effect in
// SSI, where CI Vis isn't supported.

@@ -18,3 +18,3 @@ const { addHook, channel } = require('../helpers/instrument')

return shimmer.wrap(mochaEach, function () {
return shimmer.wrapFunction(mochaEach, mochaEach => function () {
const [params] = arguments

@@ -21,0 +21,0 @@ const { it, ...rest } = mochaEach.apply(this, arguments)

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

config.isFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
config.flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount

@@ -222,0 +223,0 @@ if (isEarlyFlakeDetectionEnabled) {

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

removeEfdStringFromTestName,
addEfdStringToTestName,
NUM_FAILED_TEST_RETRIES
addEfdStringToTestName
} = require('../../../dd-trace/src/plugins/util/test')

@@ -118,3 +117,3 @@ const { channel, AsyncResource } = require('../helpers/instrument')

if (libraryConfig?.isFlakyTestRetriesEnabled) {
this.retries(NUM_FAILED_TEST_RETRIES)
this.retries(libraryConfig?.flakyTestRetriesCount)
}

@@ -121,0 +120,0 @@ // The reason why the wrapping logic is here is because we need to cover

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

return function datadogMiddleware (ctx) {
return shimmer.wrapFunction(next, next => function datadogMiddleware (ctx) {
const actionResource = new AsyncResource('bound-anonymous-fn')

@@ -51,3 +51,3 @@

})
}
})
}

@@ -54,0 +54,0 @@ }

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

}
return shimmer.wrap(command, wrapped)
return wrapped
}

@@ -113,3 +113,3 @@

}
return shimmer.wrap(command, wrapped)
return wrapped
}

@@ -128,3 +128,3 @@

return shimmer.wrap(query, wrapped)
return wrapped
}

@@ -141,3 +141,3 @@

}
return shimmer.wrap(cursor, wrapped)
return wrapped
}

@@ -152,3 +152,3 @@

}
return shimmer.wrap(command, wrapped)
return wrapped
}

@@ -172,3 +172,3 @@

args[index] = asyncResource.bind(function (err, res) {
args[index] = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (err, res) {
if (err) {

@@ -183,3 +183,3 @@ errorCh.publish(err)

}
})
}))

@@ -186,0 +186,0 @@ try {

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

// not using shimmer here because resolve/reject could be empty
arguments[0] = function wrappedResolve () {
arguments[0] = shimmer.wrapFunction(resolve, resolve => function wrappedResolve () {
finish()

@@ -139,5 +138,5 @@

}
}
})
arguments[1] = function wrappedReject () {
arguments[1] = shimmer.wrapFunction(reject, reject => function wrappedReject () {
finish()

@@ -148,3 +147,3 @@

}
}
})

@@ -175,3 +174,3 @@ return originalThen.apply(this, arguments)

}, sanitizeFilter => {
return shimmer.wrap(sanitizeFilter, function wrappedSanitizeFilter () {
return shimmer.wrapFunction(sanitizeFilter, sanitizeFilter => function wrappedSanitizeFilter () {
const sanitizedObject = sanitizeFilter.apply(this, arguments)

@@ -178,0 +177,0 @@

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

const cb = callbackResource.bind(res._callback)
res._callback = asyncResource.bind(function (error, result) {
res._callback = shimmer.wrapFunction(cb, cb => asyncResource.bind(function (error, result) {
if (error) {

@@ -48,3 +48,3 @@ errorCh.publish(error)

return cb.apply(this, arguments)
})
}))
} else {

@@ -97,3 +97,3 @@ const cb = asyncResource.bind(function () {

if (typeof cb === 'function') {
arguments[arguments.length - 1] = shimmer.wrap(cb, function () {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => function () {
finish()

@@ -100,0 +100,0 @@ return cb.apply(this, arguments)

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

function bindExecute (cmd, execute, asyncResource) {
return asyncResource.bind(function executeWithTrace (packet, connection) {
return shimmer.wrapFunction(execute, execute => asyncResource.bind(function executeWithTrace (packet, connection) {
if (this.onResult) {

@@ -41,3 +41,3 @@ this.onResult = asyncResource.bind(this.onResult)

return execute.apply(this, arguments)
}, cmd)
}, cmd))
}

@@ -48,3 +48,3 @@

return asyncResource.bind(function executeWithTrace (packet, connection) {
return shimmer.wrapFunction(execute, execute => asyncResource.bind(function executeWithTrace (packet, connection) {
const sql = cmd.statement ? cmd.statement.query : cmd.sql

@@ -63,3 +63,3 @@ const payload = { sql, conf: config }

this.onResult = asyncResource.bind(function (error) {
this.onResult = shimmer.wrapFunction(onResult, onResult => asyncResource.bind(function (error) {
if (error) {

@@ -70,3 +70,3 @@ errorCh.publish(error)

onResult.apply(this, arguments)
}, 'bound-anonymous-fn', this)
}, 'bound-anonymous-fn', this))
} else {

@@ -84,4 +84,4 @@ this.on('error', asyncResource.bind(error => errorCh.publish(error)))

}
}, cmd)
}, cmd))
}
})

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

const emit = this.emit
this.emit = function (eventName) {
this.emit = shimmer.wrapFunction(emit, emit => function (eventName) {
switch (eventName) {

@@ -72,3 +72,3 @@ case 'ready':

}
}
})

@@ -75,0 +75,0 @@ try {

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

name: 'next',
versions: ['>=13.3.0'],
versions: ['>=13.3.0 <14.2.7'],
file: 'dist/server/web/spec-extension/adapters/next-request.js'

@@ -207,3 +207,3 @@ }, NextRequestAdapter => {

name: 'next',
versions: ['>=11.1'],
versions: ['>=11.1 <14.2.7'],
file: 'dist/server/serve-static.js'

@@ -218,3 +218,3 @@ }, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))

addHook({ name: 'next', versions: ['>=11.1'], file: 'dist/server/next-server.js' }, nextServer => {
addHook({ name: 'next', versions: ['>=11.1 <14.2.7'], file: 'dist/server/next-server.js' }, nextServer => {
const Server = nextServer.default

@@ -236,3 +236,3 @@

// `handleApiRequest` changes parameters/implementation at 13.2.0
addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js' }, nextServer => {
addHook({ name: 'next', versions: ['>=13.2 <14.2.7'], file: 'dist/server/next-server.js' }, nextServer => {
const Server = nextServer.default

@@ -271,3 +271,3 @@ shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)

name: 'next',
versions: ['>=13'],
versions: ['>=13 <14.2.7'],
file: 'dist/server/web/spec-extension/request.js'

@@ -274,0 +274,0 @@ }, request => {

'use strict'
const {
channel,
addHook
} = require('./helpers/instrument')
const { addHook } = require('./helpers/instrument')
const shimmer = require('../../datadog-shimmer')
const startCh = channel('apm:openai:request:start')
const finishCh = channel('apm:openai:request:finish')
const errorCh = channel('apm:openai:request:error')
const tracingChannel = require('dc-polyfill').tracingChannel
const ch = tracingChannel('apm:openai:request')

@@ -113,7 +109,7 @@ const V4_PACKAGE_SHIMS = [

shimmer.wrap(exports.OpenAIApi.prototype, methodName, fn => function () {
if (!startCh.hasSubscribers) {
if (!ch.start.hasSubscribers) {
return fn.apply(this, arguments)
}
startCh.publish({
const ctx = {
methodName,

@@ -123,20 +119,5 @@ args: arguments,

apiKey: this.configuration.apiKey
})
}
return fn.apply(this, arguments)
.then((response) => {
finish({
headers: response.headers,
body: response.data,
path: response.request.path,
method: response.request.method
})
return response
})
.catch(error => {
finish(undefined, error)
throw error
})
return ch.tracePromise(fn, ctx, this, ...arguments)
})

@@ -218,3 +199,3 @@ }

*/
function wrapStreamIterator (response, options, n) {
function wrapStreamIterator (response, options, n, ctx) {
let processChunksAsBuffers = false

@@ -259,7 +240,9 @@ let chunks = []

finish({
finish(ctx, {
headers: response.headers,
body,
path: response.url,
method: options.method
data: body,
request: {
path: response.url,
method: options.method
}
})

@@ -288,3 +271,3 @@ }

shimmer.wrap(targetPrototype, methodName, methodFn => function () {
if (!startCh.hasSubscribers) {
if (!ch.start.hasSubscribers) {
return methodFn.apply(this, arguments)

@@ -311,3 +294,3 @@ }

startCh.publish({
const ctx = {
methodName: `${baseResource}.${methodName}`,

@@ -317,45 +300,49 @@ args: arguments,

apiKey: client.apiKey
})
}
const apiProm = methodFn.apply(this, arguments)
return ch.start.runStores(ctx, () => {
const apiProm = methodFn.apply(this, arguments)
// wrapping `parse` avoids problematic wrapping of `then` when trying to call
// `withResponse` in userland code after. This way, we can return the whole `APIPromise`
shimmer.wrap(apiProm, 'parse', origApiPromParse => function () {
return origApiPromParse.apply(this, arguments)
// wrapping `parse` avoids problematic wrapping of `then` when trying to call
// `withResponse` in userland code after. This way, we can return the whole `APIPromise`
shimmer.wrap(apiProm, 'parse', origApiPromParse => function () {
return origApiPromParse.apply(this, arguments)
// the original response is wrapped in a promise, so we need to unwrap it
.then(body => Promise.all([this.responsePromise, body]))
.then(([{ response, options }, body]) => {
if (stream) {
if (body.iterator) {
shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options, n))
.then(body => Promise.all([this.responsePromise, body]))
.then(([{ response, options }, body]) => {
if (stream) {
if (body.iterator) {
shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options, n, ctx))
} else {
shimmer.wrap(
body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options, n, ctx)
)
}
} else {
shimmer.wrap(
body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options, n)
)
finish(ctx, {
headers: response.headers,
data: body,
request: {
path: response.url,
method: options.method
}
})
}
} else {
finish({
headers: response.headers,
body,
path: response.url,
method: options.method
})
}
return body
})
.catch(error => {
finish(undefined, error)
return body
})
.catch(error => {
finish(ctx, undefined, error)
throw error
})
.finally(() => {
throw error
})
.finally(() => {
// maybe we don't want to unwrap here in case the promise is re-used?
// other hand: we want to avoid resource leakage
shimmer.unwrap(apiProm, 'parse')
})
shimmer.unwrap(apiProm, 'parse')
})
})
return apiProm
})
return apiProm
})

@@ -367,8 +354,10 @@ }

function finish (response, error) {
function finish (ctx, response, error) {
if (error) {
errorCh.publish({ error })
ctx.error = error
ch.error.publish(ctx)
}
finishCh.publish(response)
ctx.result = response
ch.asyncEnd.publish(ctx)
}

@@ -375,0 +364,0 @@

@@ -34,6 +34,6 @@ 'use strict'

const outerAr = new AsyncResource('apm:oracledb:outer-scope')
arguments[arguments.length - 1] = function wrappedCb (err, result) {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => function wrappedCb (err, result) {
finish(err)
return outerAr.runInAsyncScope(() => cb.apply(this, arguments))
}
})
}

@@ -71,3 +71,3 @@

if (callback) {
arguments[1] = (err, connection) => {
arguments[1] = shimmer.wrapFunction(callback, callback => (err, connection) => {
if (connection) {

@@ -77,3 +77,3 @@ connectionAttributes.set(connection, connAttrs)

callback(err, connection)
}
})

@@ -92,3 +92,3 @@ getConnection.apply(this, arguments)

if (callback) {
arguments[1] = (err, pool) => {
arguments[1] = shimmer.wrapFunction(callback, callback => (err, pool) => {
if (pool) {

@@ -98,3 +98,3 @@ poolAttributes.set(pool, poolAttrs)

callback(err, pool)
}
})

@@ -117,3 +117,3 @@ createPool.apply(this, arguments)

if (callback) {
arguments[arguments.length - 1] = (err, connection) => {
arguments[arguments.length - 1] = shimmer.wrapFunction(callback, callback => (err, connection) => {
if (connection) {

@@ -123,3 +123,3 @@ connectionAttributes.set(connection, poolAttributes.get(this))

callback(err, connection)
}
})
getConnection.apply(this, arguments)

@@ -126,0 +126,0 @@ } else {

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

}, BasicStrategy => {
return shimmer.wrap(BasicStrategy, function () {
return shimmer.wrapFunction(BasicStrategy, BasicStrategy => function () {
const type = 'http'

@@ -15,0 +15,0 @@

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

}, Strategy => {
return shimmer.wrap(Strategy, function () {
return shimmer.wrapFunction(Strategy, Strategy => function () {
const type = 'local'

@@ -15,0 +15,0 @@

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

// eslint-disable-next-line n/handle-callback-err
return shimmer.wrap(verified, function (err, user, info) {
return shimmer.wrapFunction(verified, verified => function (err, user, info) {
const credentials = { type, username }

@@ -17,0 +17,0 @@ passportVerifyChannel.publish({ credentials, user })

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

if (typeof cb === 'function') {
arguments[arguments.length - 1] = shimmer.wrap(cb, function () {
arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => function () {
finish()

@@ -128,0 +128,0 @@ return cb.apply(this, arguments)

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

return shimmer.wrap(pino, wrapPino(asJsonSym, wrapAsJson, pino))
return shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino))
})

@@ -86,3 +86,3 @@

return shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
return shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino))
})

@@ -93,3 +93,3 @@

const wrapped = shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino))
wrapped.pino = wrapped

@@ -107,3 +107,3 @@ wrapped.default = wrapped

addHook({ name: 'pino-pretty', versions: ['1 - 2'] }, prettyFactory => {
return shimmer.wrap(prettyFactory, wrapPrettyFactory(prettyFactory))
return shimmer.wrapFunction(prettyFactory, wrapPrettyFactory)
})

@@ -5,3 +5,3 @@ const semver = require('semver')

const shimmer = require('../../datadog-shimmer')
const { parseAnnotations, getTestSuitePath, NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')
const { parseAnnotations, getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
const log = require('../../dd-trace/src/log')

@@ -40,4 +40,5 @@

let isEarlyFlakeDetectionEnabled = false
let earlyFlakeDetectionNumRetries = 0
let isFlakyTestRetriesEnabled = false
let earlyFlakeDetectionNumRetries = 0
let flakyTestRetriesCount = 0
let knownTests = {}

@@ -412,2 +413,3 @@ let rootDir = ''

isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
}

@@ -435,6 +437,6 @@ } catch (e) {

if (isFlakyTestRetriesEnabled) {
if (isFlakyTestRetriesEnabled && flakyTestRetriesCount > 0) {
projects.forEach(project => {
if (project.retries === 0) { // Only if it hasn't been set by the user
project.retries = NUM_FAILED_TEST_RETRIES
project.retries = flakyTestRetriesCount
}

@@ -441,0 +443,0 @@ })

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

function wrapCallback (finishCh, errorCh, callback) {
return function (err) {
return shimmer.wrapFunction(callback, callback => function (err) {
finish(finishCh, errorCh, err)

@@ -165,3 +165,3 @@ if (callback) {

}
}
})
}

@@ -168,0 +168,0 @@

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

return function (req, res, next) {
return shimmer.wrapFunction(fn, fn => function (req, res, next) {
if (typeof next === 'function') {

@@ -76,7 +76,7 @@ arguments[2] = wrapNext(req, next)

}
}
})
}
function wrapNext (req, next) {
return function () {
return shimmer.wrapFunction(next, next => function () {
nextChannel.publish({ req })

@@ -86,3 +86,3 @@ finishChannel.publish({ req })

next.apply(this, arguments)
}
})
}

@@ -89,0 +89,0 @@

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

const cb = asyncResource.bind(update)
return AsyncResource.bind(function wrappedUpdate (settled, stateData) {
return shimmer.wrapFunction(cb, cb => AsyncResource.bind(function wrappedUpdate (settled, stateData) {
const state = getStateFromData(stateData)
dispatchReceiveCh.publish({ state })
return cb.apply(this, arguments)
})
}))
}

@@ -182,3 +182,3 @@ return function wrappedUpdate (settled, stateData) {

shimmer.wrap(CircularBuffer.prototype, 'pop_if', popIf => function (fn) {
arguments[0] = AsyncResource.bind(function (entry) {
arguments[0] = shimmer.wrapFunction(fn, fn => AsyncResource.bind(function (entry) {
const context = contexts.get(entry)

@@ -203,3 +203,3 @@ const asyncResource = context && context.asyncResource

return shouldPop
})
}))
return popIf.apply(this, arguments)

@@ -206,0 +206,0 @@ })

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

const handle = shimmer.wrap(original, function () {
const handle = shimmer.wrapFunction(original, original => function () {
if (!enterChannel.hasSubscribers) return original.apply(this, arguments)

@@ -93,3 +93,3 @@

function wrapNext (req, next) {
return function (error) {
return shimmer.wrapFunction(next, next => function (error) {
if (error && error !== 'route' && error !== 'router') {

@@ -103,3 +103,3 @@ errorChannel.publish({ req, error })

next.apply(this, arguments)
}
})
}

@@ -157,3 +157,3 @@

function wrapMethod (original) {
return function methodWithTrace (fn) {
return shimmer.wrapFunction(original, original => function methodWithTrace (fn) {
const offset = this.stack ? [].concat(this.stack).length : 0

@@ -169,3 +169,3 @@ const router = original.apply(this, arguments)

return router
}
})
}

@@ -172,0 +172,0 @@

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

arguments[1] = asyncResource.bind(function (error, res) {
arguments[1] = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (error, res) {
if (error) {

@@ -59,3 +59,3 @@ errorCh.publish(error)

return callback.apply(this, arguments)
})
}))

@@ -62,0 +62,0 @@ try {

const { addHook, channel, AsyncResource } = require('./helpers/instrument')
const shimmer = require('../../datadog-shimmer')
const { NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')

@@ -111,2 +110,3 @@ // test hooks

let isFlakyTestRetriesEnabled = false
let flakyTestRetriesCount = 0

@@ -117,2 +117,3 @@ try {

isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
}

@@ -122,4 +123,4 @@ } catch (e) {

}
if (isFlakyTestRetriesEnabled && !this.ctx.config.retry) {
this.ctx.config.retry = NUM_FAILED_TEST_RETRIES
if (isFlakyTestRetriesEnabled && !this.ctx.config.retry && flakyTestRetriesCount > 0) {
this.ctx.config.retry = flakyTestRetriesCount
}

@@ -126,0 +127,0 @@

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

const log = transport.log
transport.log = function wrappedLog (level, msg, meta, callback) {
shimmer.wrap(transport, 'log', log => function wrappedLog (level, msg, meta, callback) {
const payload = { message: meta || {} }

@@ -52,3 +51,3 @@ logCh.publish(payload)

log.apply(this, arguments)
}
})
patched.add(transport)

@@ -55,0 +54,0 @@ }

@@ -31,4 +31,3 @@ const {

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

@@ -233,3 +232,4 @@ const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')

earlyFlakeDetectionNumRetries,
isFlakyTestRetriesEnabled
isFlakyTestRetriesEnabled,
flakyTestRetriesCount
}

@@ -241,5 +241,4 @@ } = libraryConfigurationResponse

this.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
this.isFlakyTestRetriesEnabled = isFlakyTestRetriesEnabled
if (this.isFlakyTestRetriesEnabled) {
this.cypressConfig.retries.runMode = NUM_FAILED_TEST_RETRIES
if (isFlakyTestRetriesEnabled) {
this.cypressConfig.retries.runMode = flakyTestRetriesCount
}

@@ -246,0 +245,0 @@ }

@@ -35,4 +35,4 @@ 'use strict'

this.addSub('apm:hapi:extension:enter', ({ req }) => {
this.enter(this._requestSpans.get(req))
this.addBind('apm:hapi:extension:start', ({ req }) => {
return this._requestSpans.get(req)
})

@@ -39,0 +39,0 @@ }

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

config._ddIsFlakyTestRetriesEnabled = this.libraryConfig?.isFlakyTestRetriesEnabled ?? false
config._ddFlakyTestRetriesCount = this.libraryConfig?.flakyTestRetriesCount
})

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

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

static get system () { return 'openai' }
static get prefix () {
return 'tracing:apm:openai:request'
}

@@ -59,4 +62,6 @@ constructor (...args) {

start ({ methodName, args, basePath, apiKey }) {
bindStart (ctx) {
const { methodName, args, basePath, apiKey } = ctx
const payload = normalizeRequestPayload(methodName, args)
const store = storage.getStore() || {}

@@ -92,7 +97,5 @@ const span = this.startSpan('openai.request', {

}
})
}, false)
const fullStore = storage.getStore() || {} // certain request body fields are later used for logs
const store = Object.create(null)
fullStore.openai = store // namespacing these fields
const openaiStore = Object.create(null)

@@ -104,3 +107,3 @@ const tags = {} // The remaining tags are added one at a time

const prompt = payload.prompt
store.prompt = prompt
openaiStore.prompt = prompt
if (typeof prompt === 'string' || (Array.isArray(prompt) && typeof prompt[0] === 'number')) {

@@ -121,3 +124,3 @@ // This is a single prompt, either String or [Number]

tags['openai.request.input'] = truncateText(normalized)
store.input = normalized
openaiStore.input = normalized
}

@@ -149,3 +152,3 @@

case 'images.createVariation':
commonCreateImageRequestExtraction(tags, payload, store)
commonCreateImageRequestExtraction(tags, payload, openaiStore)
break

@@ -155,3 +158,3 @@

case 'chat.completions.create':
createChatCompletionRequestExtraction(tags, payload, store)
createChatCompletionRequestExtraction(tags, payload, openaiStore)
break

@@ -170,3 +173,3 @@

case 'audio.translations.create':
commonCreateAudioRequestExtraction(tags, payload, store)
commonCreateAudioRequestExtraction(tags, payload, openaiStore)
break

@@ -195,3 +198,3 @@

case 'edits.create':
createEditRequestExtraction(tags, payload, store)
createEditRequestExtraction(tags, payload, openaiStore)
break

@@ -201,6 +204,15 @@ }

span.addTags(tags)
ctx.currentStore = { ...store, span, openai: openaiStore }
return ctx.currentStore
}
finish (response) {
const span = this.activeSpan
asyncEnd (ctx) {
const { result } = ctx
const store = ctx.currentStore
const span = store?.span
if (!span) return
const error = !!span.context()._tags.error

@@ -210,6 +222,6 @@

if (!error) {
headers = response.headers
body = response.body
method = response.method
path = response.path
headers = result.headers
body = result.data
method = result.request.method
path = result.request.path
}

@@ -224,6 +236,5 @@

const fullStore = storage.getStore()
const store = fullStore.openai
const openaiStore = store.openai
if (!error && (path.startsWith('https://') || path.startsWith('http://'))) {
if (!error && (path?.startsWith('https://') || path?.startsWith('http://'))) {
// basic checking for if the path was set as a full URL

@@ -254,7 +265,7 @@ // not using a full regex as it will likely be "https://api.openai.com/..."

responseDataExtractionByMethod(methodName, tags, body, store)
responseDataExtractionByMethod(methodName, tags, body, openaiStore)
span.addTags(tags)
super.finish()
this.sendLog(methodName, span, tags, store, error)
span.finish()
this.sendLog(methodName, span, tags, openaiStore, error)
this.sendMetrics(headers, body, endpoint, span._duration, error, tags)

@@ -324,5 +335,5 @@ }

sendLog (methodName, span, tags, store, error) {
if (!store) return
if (!Object.keys(store).length) return
sendLog (methodName, span, tags, openaiStore, error) {
if (!openaiStore) return
if (!Object.keys(openaiStore).length) return
if (!this.sampler.isSampled()) return

@@ -333,3 +344,3 @@

message: `sampled ${methodName}`,
...store
...openaiStore
}

@@ -418,6 +429,6 @@

function createEditRequestExtraction (tags, payload, store) {
function createEditRequestExtraction (tags, payload, openaiStore) {
const instruction = payload.instruction
tags['openai.request.instruction'] = instruction
store.instruction = instruction
openaiStore.instruction = instruction
}

@@ -429,7 +440,7 @@

function createChatCompletionRequestExtraction (tags, payload, store) {
function createChatCompletionRequestExtraction (tags, payload, openaiStore) {
const messages = payload.messages
if (!defensiveArrayLength(messages)) return
store.messages = payload.messages
openaiStore.messages = payload.messages
for (let i = 0; i < payload.messages.length; i++) {

@@ -444,3 +455,3 @@ const message = payload.messages[i]

function commonCreateImageRequestExtraction (tags, payload, store) {
function commonCreateImageRequestExtraction (tags, payload, openaiStore) {
// createImageEdit, createImageVariation

@@ -451,3 +462,3 @@ const img = payload.file || payload.image

tags['openai.request.image'] = file
store.file = file
openaiStore.file = file
}

@@ -459,3 +470,3 @@

tags['openai.request.mask'] = mask
store.mask = mask
openaiStore.mask = mask
}

@@ -468,3 +479,3 @@

function responseDataExtractionByMethod (methodName, tags, body, store) {
function responseDataExtractionByMethod (methodName, tags, body, openaiStore) {
switch (methodName) {

@@ -482,3 +493,3 @@ case 'createModeration':

case 'edits.create':
commonCreateResponseExtraction(tags, body, store, methodName)
commonCreateResponseExtraction(tags, body, openaiStore, methodName)
break

@@ -499,3 +510,3 @@

case 'embeddings.create':
createEmbeddingResponseExtraction(tags, body)
createEmbeddingResponseExtraction(tags, body, openaiStore)
break

@@ -655,3 +666,3 @@

function commonCreateAudioRequestExtraction (tags, body, store) {
function commonCreateAudioRequestExtraction (tags, body, openaiStore) {
tags['openai.request.response_format'] = body.response_format

@@ -663,3 +674,3 @@ tags['openai.request.language'] = body.language

tags['openai.request.filename'] = filename
store.file = filename
openaiStore.file = filename
}

@@ -687,4 +698,4 @@ }

function createEmbeddingResponseExtraction (tags, body) {
usageExtraction(tags, body)
function createEmbeddingResponseExtraction (tags, body, openaiStore) {
usageExtraction(tags, body, openaiStore)

@@ -723,4 +734,4 @@ if (!body.data) return

// createCompletion, createChatCompletion, createEdit
function commonCreateResponseExtraction (tags, body, store, methodName) {
usageExtraction(tags, body, methodName)
function commonCreateResponseExtraction (tags, body, openaiStore, methodName) {
usageExtraction(tags, body, methodName, openaiStore)

@@ -731,3 +742,3 @@ if (!body.choices) return

store.choices = body.choices
openaiStore.choices = body.choices

@@ -766,3 +777,3 @@ for (let choiceIdx = 0; choiceIdx < body.choices.length; choiceIdx++) {

// createCompletion, createChatCompletion, createEdit, createEmbedding
function usageExtraction (tags, body, methodName) {
function usageExtraction (tags, body, methodName, openaiStore) {
let promptTokens = 0

@@ -775,3 +786,3 @@ let completionTokens = 0

totalTokens = body.usage.total_tokens
} else if (['chat.completions.create', 'completions.create'].includes(methodName)) {
} else if (body.model && ['chat.completions.create', 'completions.create'].includes(methodName)) {
// estimate tokens based on method name for completions and chat completions

@@ -783,3 +794,3 @@ const { model } = body

// prompt tokens
const payload = storage.getStore().openai
const payload = openaiStore
const promptTokensCount = countPromptTokens(methodName, payload, model)

@@ -786,0 +797,0 @@ promptTokens = promptTokensCount.promptTokens

'use strict'
const log = require('../../dd-trace/src/log')
// Use a weak map to avoid polluting the wrapped function/method.

@@ -21,5 +23,8 @@ const unwrappers = new WeakMap()

function wrapFn (original, delegate) {
assertFunction(delegate)
assertNotClass(original) // TODO: support constructors of native classes
function wrapFunction (original, wrapper) {
if (typeof original === 'function') assertNotClass(original)
// TODO This needs to be re-done so that this and wrapMethod are distinct.
const target = { func: original }
wrapMethod(target, 'func', wrapper, typeof original !== 'function')
let delegate = target.func

@@ -34,3 +39,3 @@ const shim = function shim () {

copyProperties(original, shim)
if (typeof original === 'function') copyProperties(original, shim)

@@ -40,8 +45,135 @@ return shim

function wrapMethod (target, name, wrapper) {
assertMethod(target, name)
assertFunction(wrapper)
const wrapFn = function (original, delegate) {
throw new Error('calling `wrap()` with 2 args is deprecated. Use wrapFunction instead.')
}
// This is only used in safe mode. It's a simple state machine to track if the
// original method was called and if it returned. We need this to determine if
// an error was thrown by the original method, or by us. We'll use one of these
// per call to a wrapped method.
class CallState {
constructor () {
this.called = false
this.completed = false
this.retVal = undefined
}
startCall () {
this.called = true
}
endCall (retVal) {
this.completed = true
this.retVal = retVal
}
}
function isPromise (obj) {
return obj && typeof obj === 'object' && typeof obj.then === 'function'
}
let safeMode = !!process.env.DD_INEJCTION_ENABLED
function setSafe (value) {
safeMode = value
}
function wrapMethod (target, name, wrapper, noAssert) {
if (!noAssert) {
assertMethod(target, name)
assertFunction(wrapper)
}
const original = target[name]
const wrapped = wrapper(original)
let wrapped
if (safeMode && original) {
// In this mode, we make a best-effort attempt to handle errors that are thrown
// by us, rather than wrapped code. With such errors, we log them, and then attempt
// to return the result as if no wrapping was done at all.
//
// Caveats:
// * If the original function is called in a later iteration of the event loop,
// and we throw _then_, then it won't be caught by this. In practice, we always call
// the original function synchronously, so this is not a problem.
// * While async errors are dealt with here, errors in callbacks are not. This
// is because we don't necessarily know _for sure_ that any function arguments
// are wrapped by us. We could wrap them all anyway and just make that assumption,
// or just assume that the last argument is always a callback set by us if it's a
// function, but those don't seem like things we can rely on. We could add a
// `shimmer.markCallbackAsWrapped()` function that's a no-op outside safe-mode,
// but that means modifying every instrumentation. Even then, the complexity of
// this code increases because then we'd need to effectively do the reverse of
// what we're doing for synchronous functions. This is a TODO.
// We're going to hold on to current callState in this variable in this scope,
// which is fine because any time we reference it, we're referencing it synchronously.
// We'll use it in the our wrapper (which, again, is called syncrhonously), and in the
// errorHandler, which will already have been bound to this callState.
let currentCallState
// Rather than calling the original function directly from the shim wrapper, we wrap
// it again so that we can track if it was called and if it returned. This is because
// we need to know if an error was thrown by the original function, or by us.
// We could do this inside the `wrapper` function defined below, which would simplify
// managing the callState, but then we'd be calling `wrapper` on each invocation, so
// instead we do it here, once.
const innerWrapped = wrapper(function (...args) {
// We need to stash the callState here because of recursion.
const callState = currentCallState
callState.startCall()
const retVal = original.apply(this, args)
if (isPromise(retVal)) {
retVal.then(callState.endCall.bind(callState))
} else {
callState.endCall(retVal)
}
return retVal
})
// This is the crux of what we're doing in safe mode. It handles errors
// that _we_ cause, by logging them, and transparently providing results
// as if no wrapping was done at all. That means detecting (via callState)
// whether the function has already run or not, and if it has, returning
// the result, and otherwise calling the original function unwrapped.
const handleError = function (args, callState, e) {
if (callState.completed) {
// error was thrown after original function returned/resolved, so
// it was us. log it.
log.error(e)
// original ran and returned something. return it.
return callState.retVal
}
if (!callState.called) {
// error was thrown before original function was called, so
// it was us. log it.
log.error(e)
// original never ran. call it unwrapped.
return original.apply(this, args)
}
// error was thrown during original function execution, so
// it was them. throw.
throw e
}
// The wrapped function is the one that will be called by the user.
// It calls our version of the original function, which manages the
// callState. That way when we use the errorHandler, it can tell where
// the error originated.
wrapped = function (...args) {
currentCallState = new CallState()
const errorHandler = handleError.bind(this, args, currentCallState)
try {
const retVal = innerWrapped.apply(this, args)
return isPromise(retVal) ? retVal.catch(errorHandler) : retVal
} catch (e) {
return errorHandler(e)
}
}
} else {
// In non-safe mode, we just wrap the original function directly.
wrapped = wrapper(original)
}
const descriptor = Object.getOwnPropertyDescriptor(target, name)

@@ -54,3 +186,3 @@

copyProperties(original, wrapped)
if (typeof original === 'function') copyProperties(original, wrapped)

@@ -163,5 +295,7 @@ if (descriptor) {

wrap,
wrapFunction,
massWrap,
unwrap,
massUnwrap
massUnwrap,
setSafe
}

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

let defaultBlockingActionParameters
const responseBlockedSet = new WeakSet()

@@ -27,3 +29,3 @@

function getBlockWithRedirectData (rootSpan, actionParameters) {
function getBlockWithRedirectData (actionParameters) {
let statusCode = actionParameters.status_code

@@ -37,6 +39,2 @@ if (!statusCode || statusCode < 300 || statusCode >= 400) {

rootSpan.addTags({
'appsec.blocked': 'true'
})
return { headers, statusCode }

@@ -55,3 +53,3 @@ }

function getBlockWithContentData (req, specificType, rootSpan, actionParameters) {
function getBlockWithContentData (req, specificType, actionParameters) {
let type

@@ -97,18 +95,14 @@ let body

rootSpan.addTags({
'appsec.blocked': 'true'
})
return { body, statusCode, headers }
}
function getBlockingData (req, specificType, rootSpan, actionParameters) {
function getBlockingData (req, specificType, actionParameters) {
if (actionParameters?.location) {
return getBlockWithRedirectData(rootSpan, actionParameters)
return getBlockWithRedirectData(actionParameters)
} else {
return getBlockWithContentData(req, specificType, rootSpan, actionParameters)
return getBlockWithContentData(req, specificType, actionParameters)
}
}
function block (req, res, rootSpan, abortController, actionParameters) {
function block (req, res, rootSpan, abortController, actionParameters = defaultBlockingActionParameters) {
if (res.headersSent) {

@@ -119,4 +113,8 @@ log.warn('Cannot send blocking response when headers have already been sent')

const { body, headers, statusCode } = getBlockingData(req, null, rootSpan, actionParameters)
const { body, headers, statusCode } = getBlockingData(req, null, actionParameters)
rootSpan.addTags({
'appsec.blocked': 'true'
})
for (const headerName of res.getHeaderNames()) {

@@ -134,3 +132,4 @@ res.removeHeader(headerName)

function getBlockingAction (actions) {
return actions?.block_request || actions?.redirect_request
// waf only returns one action, but it prioritizes redirect over block
return actions?.redirect_request || actions?.block_request
}

@@ -162,2 +161,8 @@

function setDefaultBlockingActionParameters (actions) {
const blockAction = actions?.find(action => action.id === 'block')
defaultBlockingActionParameters = blockAction?.parameters
}
module.exports = {

@@ -170,3 +175,4 @@ addSpecificEndpoint,

setTemplates,
isBlocked
isBlocked,
setDefaultBlockingActionParameters
}

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

const blockingData = getBlockingData(req, specificBlockingTypes.GRAPHQL, rootSpan, requestData.wafAction)
const blockingData = getBlockingData(req, specificBlockingTypes.GRAPHQL, requestData.wafAction)
abortData.statusCode = blockingData.statusCode

@@ -103,2 +103,4 @@ abortData.headers = blockingData.headers

rootSpan.setTag('appsec.blocked', 'true')
abortController?.abort()

@@ -105,0 +107,0 @@ }

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

this.error(data)
return this.publish(data, 'ERROR')
// publish is done automatically by log.error()
return this
}

@@ -84,0 +85,0 @@ }

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

method: 'POST',
path: '/v0.7/config'
path: '/v0.7/config',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}

@@ -126,0 +129,0 @@

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

const blocking = require('./blocking')
let defaultRules

@@ -23,2 +25,4 @@

waf.init(defaultRules, config)
blocking.setDefaultBlockingActionParameters(defaultRules?.actions)
}

@@ -146,2 +150,4 @@

appliedActions = newActions
blocking.setDefaultBlockingActionParameters(concatArrays(newActions))
}

@@ -248,2 +254,4 @@ } catch (err) {

appliedActions.clear()
blocking.setDefaultBlockingActionParameters(undefined)
}

@@ -250,0 +258,0 @@

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

const tags = { rule_type: raspRuleType, waf_version: metrics.wafVersion }
appsecMetrics.count('appsec.rasp.rule.eval', tags).inc(1)
appsecMetrics.count('rasp.rule.eval', tags).inc(1)
if (metrics.wafTimeout) {
appsecMetrics.count('appsec.rasp.timeout', tags).inc(1)
appsecMetrics.count('rasp.timeout', tags).inc(1)
}
if (metrics.ruleTriggered) {
appsecMetrics.count('appsec.rasp.rule.match', tags).inc(1)
appsecMetrics.count('rasp.rule.match', tags).inc(1)
}

@@ -103,0 +103,0 @@ }

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

earlyFlakeDetectionFaultyThreshold,
isFlakyTestRetriesEnabled
isFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled && this._config.isFlakyTestRetriesEnabled,
flakyTestRetriesCount: this._config.flakyTestRetriesCount
}

@@ -207,0 +208,0 @@ }

@@ -444,5 +444,8 @@ 'use strict'

this._setValue(defaults, 'iast.telemetryVerbosity', 'INFORMATION')
this._setValue(defaults, 'injectionEnabled', [])
this._setValue(defaults, 'isAzureFunction', false)
this._setValue(defaults, 'isCiVisibility', false)
this._setValue(defaults, 'isEarlyFlakeDetectionEnabled', false)
this._setValue(defaults, 'isFlakyTestRetriesEnabled', false)
this._setValue(defaults, 'flakyTestRetriesCount', 5)
this._setValue(defaults, 'isGCPFunction', false)

@@ -463,4 +466,2 @@ this._setValue(defaults, 'isGitUploadEnabled', false)

this._setValue(defaults, 'profiling.sourceMap', true)
this._setValue(defaults, 'profiling.ssi', false)
this._setValue(defaults, 'profiling.heuristicsEnabled', false)
this._setValue(defaults, 'profiling.longLivedThreshold', undefined)

@@ -686,2 +687,3 @@ this._setValue(defaults, 'protocolVersion', '0.4')

this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())

@@ -702,14 +704,14 @@ this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())

this._setString(env, 'port', DD_TRACE_AGENT_PORT)
this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
const profilingEnabledEnv = coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED)
const profilingEnabled = isTrue(profilingEnabledEnv)
? 'true'
: isFalse(profilingEnabledEnv)
? 'false'
: profilingEnabledEnv === 'auto' ? 'auto' : undefined
this._setString(env, 'profiling.enabled', profilingEnabled)
this._setString(env, 'profiling.exporters', DD_PROFILING_EXPORTERS)
this._setBoolean(env, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED) {
this._setBoolean(env, 'profiling.ssi', true)
if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED.split(',').includes('profiler')) {
this._setBoolean(env, 'profiling.heuristicsEnabled', true)
}
if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
// This is only used in testing to not have to wait 30s
this._setValue(env, 'profiling.longLivedThreshold', Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD))
}
if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
// This is only used in testing to not have to wait 30s
this._setValue(env, 'profiling.longLivedThreshold', Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD))
}

@@ -769,8 +771,3 @@

this._envUnprocessed['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000
const hasTelemetryLogsUsingFeatures =
env['iast.enabled'] || env['profiling.enabled'] || env['profiling.heuristicsEnabled']
? true
: undefined
this._setBoolean(env, 'telemetry.logCollection', coalesce(DD_TELEMETRY_LOG_COLLECTION_ENABLED,
hasTelemetryLogsUsingFeatures))
this._setBoolean(env, 'telemetry.logCollection', DD_TELEMETRY_LOG_COLLECTION_ENABLED)
this._setBoolean(env, 'telemetry.metrics', DD_TELEMETRY_METRICS_ENABLED)

@@ -870,3 +867,6 @@ this._setBoolean(env, 'traceId128BitGenerationEnabled', DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)

this._setString(opts, 'port', options.port)
this._setBoolean(opts, 'profiling.enabled', options.profiling)
const strProfiling = String(options.profiling)
if (['true', 'false', 'auto'].includes(strProfiling)) {
this._setString(opts, 'profiling.enabled', strProfiling)
}
this._setString(opts, 'protocolVersion', options.protocolVersion)

@@ -894,6 +894,2 @@ if (options.remoteConfig) {

this._setTags(opts, 'tags', tags)
const hasTelemetryLogsUsingFeatures =
(options.iast && (options.iast === true || options.iast?.enabled === true)) ||
(options.profiling && options.profiling === true)
this._setBoolean(opts, 'telemetry.logCollection', hasTelemetryLogsUsingFeatures)
this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)

@@ -997,3 +993,5 @@ this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)

DD_CIVISIBILITY_AGENTLESS_URL,
DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED
DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED,
DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
DD_CIVISIBILITY_FLAKY_RETRY_COUNT
} = process.env

@@ -1009,2 +1007,5 @@

coalesce(DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
this._setBoolean(calc, 'isFlakyTestRetriesEnabled',
coalesce(DD_CIVISIBILITY_FLAKY_RETRY_ENABLED, true))
this._setValue(calc, 'flakyTestRetriesCount', coalesce(maybeInt(DD_CIVISIBILITY_FLAKY_RETRY_COUNT), 5))
this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))

@@ -1031,2 +1032,9 @@ this._setBoolean(calc, 'isManualApiEnabled', this._isCiVisibilityManualApiEnabled())

}
const iastEnabled = coalesce(this._options['iast.enabled'], this._env['iast.enabled'])
const profilingEnabled = coalesce(this._options['profiling.enabled'], this._env['profiling.enabled'])
const injectionIncludesProfiler = (this._env.injectionEnabled || []).includes('profiler')
if (iastEnabled || ['auto', 'true'].includes(profilingEnabled) || injectionIncludesProfiler) {
this._setBoolean(calc, 'telemetry.logCollection', true)
}
}

@@ -1156,13 +1164,14 @@

const container = containers[i]
const origin = origins[i]
const unprocessed = unprocessedValues[i]
const value = container[name]
if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
if (get(this, name) === container[name] && has(this, name)) break
if ((value !== null && value !== undefined) || container === this._defaults) {
if (get(this, name) === value && has(this, name)) break
let value = container[name]
set(this, name, value)
value = unprocessed[name] || value
changes.push({ name, value, origin })
changes.push({
name,
value: unprocessedValues[i][name] || value,
origin: origins[i]
})

@@ -1169,0 +1178,0 @@ break

@@ -96,4 +96,5 @@ 'use strict'

}
clearTimeout(__lambdaTimeout)
return result
}
}

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

registerLambdaHook()
/**
* It is safe to do it this way, since customers will never be expected to disable
* this specific instrumentation through the init config object.
*/
const _DD_TRACE_DISABLED_INSTRUMENTATIONS = process.env.DD_TRACE_DISABLED_INSTRUMENTATIONS || ''
const _disabledInstrumentations = new Set(
_DD_TRACE_DISABLED_INSTRUMENTATIONS ? _DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : []
)
if (!_disabledInstrumentations.has('lambda')) {
registerLambdaHook()
}

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

_hasParentIdInTags (spanContext) {
return tags.DD_PARENT_ID in spanContext._trace.tags &&
spanContext._trace.tags[tags.DD_PARENT_ID] !== zeroTraceId
return tags.DD_PARENT_ID in spanContext._trace.tags
}

@@ -449,6 +448,2 @@

if (!spanContext._trace.tags[tags.DD_PARENT_ID]) {
spanContext._trace.tags[tags.DD_PARENT_ID] = zeroTraceId
}
this._extractBaggageItems(carrier, spanContext)

@@ -455,0 +450,0 @@ return spanContext

@@ -98,5 +98,2 @@ const path = require('path')

// Flaky test retries
const NUM_FAILED_TEST_RETRIES = 5
module.exports = {

@@ -174,4 +171,3 @@ TEST_CODE_OWNERS,

TEST_BROWSER_NAME,
TEST_BROWSER_VERSION,
NUM_FAILED_TEST_RETRIES
TEST_BROWSER_VERSION
}

@@ -178,0 +174,0 @@

@@ -11,4 +11,4 @@ 'use strict'

start: config => {
const { service, version, env, url, hostname, port, tags, repositoryUrl, commitSHA } = config
const { enabled, sourceMap, exporters, heuristicsEnabled } = config.profiling
const { service, version, env, url, hostname, port, tags, repositoryUrl, commitSHA, injectionEnabled } = config
const { enabled, sourceMap, exporters } = config.profiling
const logger = {

@@ -21,5 +21,13 @@ debug: (message) => log.debug(message),

const libraryInjected = injectionEnabled.length > 0
let activation
if (enabled === 'auto') {
activation = 'auto'
} else if (enabled === 'true') {
activation = 'manual'
} else if (injectionEnabled.includes('profiler')) {
activation = 'injection'
} // else activation = undefined
return profiler.start({
enabled,
heuristicsEnabled,
service,

@@ -36,3 +44,5 @@ version,

repositoryUrl,
commitSHA
commitSHA,
libraryInjected,
activation
})

@@ -39,0 +49,0 @@ },

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

DD_PROFILING_DEBUG_SOURCE_MAPS,
DD_PROFILING_ENABLED,
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,

@@ -53,3 +52,2 @@ DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,

const enabled = isTrue(coalesce(options.enabled, DD_PROFILING_ENABLED, true))
const env = coalesce(options.env, DD_ENV)

@@ -69,4 +67,2 @@ const service = options.service || DD_SERVICE || 'node'

this.enabled = enabled
this.heuristicsEnabled = options.heuristicsEnabled
this.service = service

@@ -135,2 +131,4 @@ this.env = env

this.libraryInjected = options.libraryInjected
this.activation = options.activation
this.exporters = ensureExporters(options.exporters || [

@@ -137,0 +135,0 @@ new AgentExporter(this)

@@ -19,6 +19,18 @@ 'use strict'

} else {
const injectionEnabled = (process.env.DD_INJECTION_ENABLED || '').split(',')
const libraryInjected = injectionEnabled.length > 0
const profilingEnabled = (process.env.DD_PROFILING_ENABLED || '').toLowerCase()
const activation = ['true', '1'].includes(profilingEnabled)
? 'manual'
: profilingEnabled === 'auto'
? 'auto'
: injectionEnabled.includes('profiling')
? 'injection'
: 'unknown'
return new AgentExporter({
url,
logger,
uploadTimeout: timeoutMs
uploadTimeout: timeoutMs,
libraryInjected,
activation
})

@@ -25,0 +37,0 @@ }

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

class AgentExporter {
constructor ({ url, logger, uploadTimeout, env, host, service, version } = {}) {
constructor ({ url, logger, uploadTimeout, env, host, service, version, libraryInjected, activation } = {}) {
this._url = url

@@ -69,2 +69,4 @@ this._logger = logger

this._appVersion = version
this._libraryInjected = !!libraryInjected
this._activation = activation || 'unknown'
}

@@ -110,2 +112,6 @@

profiler: {
activation: this._activation,
ssi: {
mechanism: this._libraryInjected ? 'injected_agent' : 'none'
},
version

@@ -112,0 +118,0 @@ },

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

const dc = require('dc-polyfill')
const telemetryLog = dc.channel('datadog:telemetry:log')

@@ -24,9 +23,2 @@ const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')

}
if (telemetryLog.hasSubscribers) {
telemetryLog.publish({
message: err.message,
level: 'ERROR',
stack_trace: err.stack
})
}
}

@@ -60,3 +52,2 @@

const config = this._config = new Config(options)
if (!config.enabled && !config.heuristicsEnabled) return false

@@ -63,0 +54,0 @@ this._logger = config.logger

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

const EnablementChoice = {
MANUALLY_ENABLED: Symbol('SSITelemetry.EnablementChoice.MANUALLY_ENABLED'),
SSI_ENABLED: Symbol('SSITelemetry.EnablementChoice.SSI_ENABLED'),
SSI_NOT_ENABLED: Symbol('SSITelemetry.EnablementChoice.SSI_NOT_ENABLED'),
DISABLED: Symbol('SSITelemetry.EnablementChoice.DISABLED')
}
Object.freeze(EnablementChoice)
function getEnablementChoiceFromConfig (config) {
if (config.ssi === false || config.enabled === false) {
return EnablementChoice.DISABLED
} else if (config.heuristicsEnabled === true) {
return EnablementChoice.SSI_ENABLED
} else if (config.enabled === true) {
return EnablementChoice.MANUALLY_ENABLED
} else {
return EnablementChoice.SSI_NOT_ENABLED
}
}
function enablementChoiceToTagValue (enablementChoice) {
switch (enablementChoice) {
case EnablementChoice.MANUALLY_ENABLED:
return 'manually_enabled'
case EnablementChoice.SSI_ENABLED:
return 'ssi_enabled'
case EnablementChoice.SSI_NOT_ENABLED:
return 'not_enabled'
case EnablementChoice.DISABLED:
// Can't emit this one as a tag
throw new Error('Invalid enablement choice')
}
}
/**

@@ -60,5 +26,19 @@ * This class embodies the SSI profiler-triggering heuristics and also emits telemetry metrics about

constructor (config) {
this.enablementChoice = getEnablementChoiceFromConfig(config)
const injectionIncludesProfiler = config.injectionEnabled.includes('profiler')
this._heuristicsActive = injectionIncludesProfiler || config.profiling.enabled === 'auto'
this._emitsTelemetry = config.injectionEnabled.length > 0 && config.profiling.enabled !== 'false'
const longLivedThreshold = config.longLivedThreshold || DEFAULT_LONG_LIVED_THRESHOLD
if (this._emitsTelemetry) {
if (config.profiling.enabled === 'true') {
this.enablementChoice = 'manually_enabled'
} else if (injectionIncludesProfiler) {
this.enablementChoice = 'ssi_enabled'
} else if (config.profiling.enabled === 'auto') {
this.enablementChoice = 'auto_enabled'
} else {
this.enablementChoice = 'ssi_not_enabled'
}
}
const longLivedThreshold = config.profiling.longLivedThreshold || DEFAULT_LONG_LIVED_THRESHOLD
if (typeof longLivedThreshold !== 'number' || longLivedThreshold <= 0) {

@@ -74,8 +54,12 @@ throw new Error('Long-lived threshold must be a positive number')

enabled () {
return this.enablementChoice !== EnablementChoice.DISABLED
get emitsTelemetry () {
return this._emitsTelemetry
}
get heuristicsActive () {
return this._heuristicsActive
}
start () {
if (this.enabled()) {
if (this.heuristicsActive || this.emitsTelemetry) {
// Used to determine short-livedness of the process. We could use the process start time as the

@@ -91,9 +75,13 @@ // reference point, but the tracer initialization point is more relevant, as we couldn't be

this._onSpanCreated = this._onSpanCreated.bind(this)
this._onProfileSubmitted = this._onProfileSubmitted.bind(this)
this._onMockProfileSubmitted = this._onMockProfileSubmitted.bind(this)
dc.subscribe('dd-trace:span:start', this._onSpanCreated)
if (this.emitsTelemetry) {
this._onProfileSubmitted = this._onProfileSubmitted.bind(this)
this._onMockProfileSubmitted = this._onMockProfileSubmitted.bind(this)
dc.subscribe('datadog:profiling:profile-submitted', this._onProfileSubmitted)
dc.subscribe('datadog:profiling:mock-profile-submitted', this._onMockProfileSubmitted)
}
this._onAppClosing = this._onAppClosing.bind(this)
dc.subscribe('dd-trace:span:start', this._onSpanCreated)
dc.subscribe('datadog:profiling:profile-submitted', this._onProfileSubmitted)
dc.subscribe('datadog:profiling:mock-profile-submitted', this._onMockProfileSubmitted)
dc.subscribe('datadog:telemetry:app-closing', this._onAppClosing)

@@ -159,3 +147,3 @@ }

'installation:ssi',
`enablement_choice:${enablementChoiceToTagValue(this.enablementChoice)}`,
`enablement_choice:${this.enablementChoice}`,
`has_sent_profiles:${this.hasSentProfiles}`,

@@ -171,5 +159,5 @@ `heuristic_hypothetical_decision:${decision.join('_')}`

decision[0] === 'triggered' &&
// When enablement choice is SSI_ENABLED, hasSentProfiles can transition from false to true when the
// When heuristics are active, hasSentProfiles can transition from false to true when the
// profiler gets started and the first profile is submitted, so we have to wait for it.
(this.enablementChoice !== EnablementChoice.SSI_ENABLED || this.hasSentProfiles)
(!this.heuristicsActive || this.hasSentProfiles)
) {

@@ -183,13 +171,16 @@ // Tags won't change anymore, so we can emit the runtime ID metric now.

_onAppClosing () {
this._ensureProfileMetrics()
// Last ditch effort to emit a runtime ID count metric
if (!this._emittedRuntimeId) {
this._emittedRuntimeId = true
this._runtimeIdCount.inc()
if (this.emitsTelemetry) {
this._ensureProfileMetrics()
// Last ditch effort to emit a runtime ID count metric
if (!this._emittedRuntimeId) {
this._emittedRuntimeId = true
this._runtimeIdCount.inc()
}
// So we have the metrics in the final state
this._profileCount.inc(0)
dc.unsubscribe('datadog:profiling:profile-submitted', this._onProfileSubmitted)
dc.unsubscribe('datadog:profiling:mock-profile-submitted', this._onMockProfileSubmitted)
}
// So we have the metrics in the final state
this._profileCount.inc(0)
dc.unsubscribe('datadog:profiling:profile-submitted', this._onProfileSubmitted)
dc.unsubscribe('datadog:profiling:mock-profile-submitted', this._onMockProfileSubmitted)
dc.unsubscribe('datadog:telemetry:app-closing', this._onAppClosing)

@@ -202,2 +193,2 @@ if (this.noSpan) {

module.exports = { SSIHeuristics, EnablementChoice }
module.exports = { SSIHeuristics }

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

const { SSIHeuristics } = require('./profiling/ssi-heuristics')
const telemetryLog = require('dc-polyfill').channel('datadog:telemetry:log')
const appsecStandalone = require('./appsec/standalone')

@@ -121,21 +120,29 @@

const ssiHeuristics = new SSIHeuristics(config.profiling)
ssiHeuristics.start()
if (config.profiling.enabled) {
this._profilerStarted = this._startProfiler(config)
} else if (config.profiling.ssi) {
const mockProfiler = require('./profiling/ssi-telemetry-mock-profiler')
mockProfiler.start(config)
if (config.profiling.enabled !== 'false') {
const ssiHeuristics = new SSIHeuristics(config)
ssiHeuristics.start()
let mockProfiler = null
if (config.profiling.enabled === 'true') {
this._profilerStarted = this._startProfiler(config)
} else if (ssiHeuristics.emitsTelemetry) {
// Start a mock profiler that emits mock profile-submitted events for the telemetry.
// It will be stopped if the real profiler is started by the heuristics.
mockProfiler = require('./profiling/ssi-telemetry-mock-profiler')
mockProfiler.start(config)
}
if (config.profiling.heuristicsEnabled) {
if (ssiHeuristics.heuristicsActive) {
ssiHeuristics.onTriggered(() => {
mockProfiler.stop()
if (mockProfiler) {
mockProfiler.stop()
}
this._startProfiler(config)
ssiHeuristics.onTriggered()
ssiHeuristics.onTriggered() // deregister this callback
})
}
if (!this._profilerStarted) {
this._profilerStarted = Promise.resolve(false)
}
}
if (!this._profilerStarted) {
this._profilerStarted = Promise.resolve(false)
}

@@ -168,9 +175,2 @@ if (config.runtimeMetrics) {

log.error(e)
if (telemetryLog.hasSubscribers) {
telemetryLog.publish({
message: e.message,
level: 'ERROR',
stack_trace: e.stack
})
}
}

@@ -177,0 +177,0 @@ }

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

version: tracerVersion,
enabled: config.profiling.enabled
enabled: profilingEnabledToBoolean(config.profiling.enabled)
}

@@ -333,9 +333,13 @@ }

if (namesNeedFormatting.has(entry.name)) entry.value = formatMapForTelemetry(entry.value)
if (entry.name === 'url' && entry.value) entry.value = entry.value.toString()
if (entry.name === 'DD_TRACE_SAMPLING_RULES') {
if (namesNeedFormatting.has(entry.name)) {
entry.value = formatMapForTelemetry(entry.value)
} else if (entry.name === 'url') {
if (entry.value) {
entry.value = entry.value.toString()
}
} else if (entry.name === 'DD_TRACE_SAMPLING_RULES') {
entry.value = JSON.stringify(entry.value)
} else if (Array.isArray(entry.value)) {
entry.value = value.join(',')
}
if (Array.isArray(entry.value)) entry.value = value.join(',')
configuration.push(entry)

@@ -359,2 +363,15 @@ }

function profilingEnabledToBoolean (profilingEnabled) {
if (typeof profilingEnabled === 'boolean') {
return profilingEnabled
}
if (['auto', 'true'].includes(profilingEnabled)) {
return true
}
if (profilingEnabled === 'false') {
return false
}
return undefined
}
module.exports = {

@@ -361,0 +378,0 @@ start,

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

const telemetryLog = dc.channel('datadog:telemetry:log')
const errorLog = dc.channel('datadog:log:error')

@@ -37,2 +38,17 @@ let enabled = false

function onErrorLog (msg) {
if (msg instanceof Error) {
onLog({
level: 'ERROR',
message: msg.message,
stack_trace: msg.stack
})
} else if (typeof msg === 'string') {
onLog({
level: 'ERROR',
message: msg
})
}
}
function start (config) {

@@ -44,2 +60,4 @@ if (!config.telemetry.logCollection || enabled) return

telemetryLog.subscribe(onLog)
errorLog.subscribe(onErrorLog)
}

@@ -53,2 +71,4 @@

}
errorLog.unsubscribe(onErrorLog)
}

@@ -55,0 +75,0 @@

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