dd-trace 2.0.0-appsec-beta.1 → 2.0.0-appsec-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci/cypress/plugin.js +3 -0
- package/ci/cypress/support.js +1 -0
- package/ci/init.js +13 -0
- package/ci/jest/env.js +14 -0
- package/index.d.ts +5 -5
- package/package.json +5 -4
- package/packages/datadog-instrumentations/index.js +5 -0
- package/packages/datadog-instrumentations/src/dns.js +94 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +121 -0
- package/packages/datadog-instrumentations/src/memcached.js +55 -0
- package/packages/datadog-instrumentations/src/mysql.js +69 -0
- package/packages/datadog-plugin-cucumber/src/index.js +4 -4
- package/packages/datadog-plugin-cypress/src/plugin.js +6 -2
- package/packages/datadog-plugin-cypress/src/support.js +21 -6
- package/packages/datadog-plugin-dns/src/index.js +65 -178
- package/packages/datadog-plugin-http/src/server.js +5 -0
- package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
- package/packages/datadog-plugin-memcached/src/index.js +41 -63
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mysql/src/index.js +37 -89
- package/packages/datadog-plugin-redis/src/index.js +31 -1
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +9 -20
- package/packages/dd-trace/src/{gateway → appsec/gateway}/als.js +0 -0
- package/packages/dd-trace/src/appsec/gateway/channels.js +8 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/dc_block.js +0 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/engine.js +19 -30
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/index.js +0 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/runner.js +2 -0
- package/packages/dd-trace/src/appsec/index.js +19 -28
- package/packages/dd-trace/src/appsec/recommended.json +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +46 -180
- package/packages/dd-trace/src/config.js +11 -2
- package/packages/dd-trace/src/constants.js +6 -1
- package/packages/dd-trace/src/format.js +12 -0
- package/packages/dd-trace/src/instrumenter.js +6 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -0
- package/packages/dd-trace/src/opentracing/span_context.js +2 -1
- package/packages/dd-trace/src/plugin_manager.js +65 -0
- package/packages/dd-trace/src/plugins/plugin.js +57 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -4
- package/packages/dd-trace/src/plugins/util/redis.js +0 -2
- package/packages/dd-trace/src/plugins/util/test.js +8 -2
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -2
- package/packages/dd-trace/src/plugins/util/web.js +3 -13
- package/packages/dd-trace/src/priority_sampler.js +71 -19
- package/packages/dd-trace/src/profiling/exporters/agent.js +35 -34
- package/packages/dd-trace/src/proxy.js +5 -1
- package/packages/dd-trace/src/ritm.js +40 -16
- package/scripts/install_plugin_modules.js +23 -1
- package/packages/dd-trace/src/gateway/channels.js +0 -8
- package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -36
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require('../../packages/datadog-plugin-cypress/src/support')
|
package/ci/init.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const tracer = require('../packages/dd-trace')
|
|
2
|
+
const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
|
|
3
|
+
|
|
4
|
+
tracer.init({
|
|
5
|
+
startupLogs: false,
|
|
6
|
+
tags: {
|
|
7
|
+
[ORIGIN_KEY]: 'ciapp-test'
|
|
8
|
+
}
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
tracer.use('fs', false)
|
|
12
|
+
|
|
13
|
+
module.exports = tracer
|
package/ci/jest/env.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const tracer = require('../../packages/dd-trace')
|
|
2
|
+
const { ORIGIN_KEY } = require('../../packages/dd-trace/src/constants')
|
|
3
|
+
|
|
4
|
+
tracer.init({
|
|
5
|
+
startupLogs: false,
|
|
6
|
+
flushInterval: 400000,
|
|
7
|
+
tags: {
|
|
8
|
+
[ORIGIN_KEY]: 'ciapp-test'
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
tracer.use('fs', false)
|
|
13
|
+
|
|
14
|
+
module.exports = tracer
|
package/index.d.ts
CHANGED
|
@@ -786,7 +786,7 @@ declare namespace plugins {
|
|
|
786
786
|
* This plugin automatically instruments the
|
|
787
787
|
* [cucumber](https://www.npmjs.com/package/@cucumber/cucumber) module.
|
|
788
788
|
*/
|
|
789
|
-
interface cucumber extends
|
|
789
|
+
interface cucumber extends Integration {}
|
|
790
790
|
|
|
791
791
|
/**
|
|
792
792
|
* This plugin automatically instruments the
|
|
@@ -972,12 +972,12 @@ declare namespace plugins {
|
|
|
972
972
|
/**
|
|
973
973
|
* Configuration for HTTP clients.
|
|
974
974
|
*/
|
|
975
|
-
client?: HttpClient,
|
|
975
|
+
client?: HttpClient | boolean,
|
|
976
976
|
|
|
977
977
|
/**
|
|
978
978
|
* Configuration for HTTP servers.
|
|
979
979
|
*/
|
|
980
|
-
server?: HttpServer
|
|
980
|
+
server?: HttpServer | boolean
|
|
981
981
|
|
|
982
982
|
/**
|
|
983
983
|
* Hooks to run before spans are finished.
|
|
@@ -1006,12 +1006,12 @@ declare namespace plugins {
|
|
|
1006
1006
|
/**
|
|
1007
1007
|
* Configuration for HTTP clients.
|
|
1008
1008
|
*/
|
|
1009
|
-
client?: Http2Client,
|
|
1009
|
+
client?: Http2Client | boolean,
|
|
1010
1010
|
|
|
1011
1011
|
/**
|
|
1012
1012
|
* Configuration for HTTP servers.
|
|
1013
1013
|
*/
|
|
1014
|
-
server?: Http2Server
|
|
1014
|
+
server?: Http2Server | boolean
|
|
1015
1015
|
}
|
|
1016
1016
|
|
|
1017
1017
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.0.0-appsec-beta.
|
|
3
|
+
"version": "2.0.0-appsec-beta.5",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"bench": "node benchmark",
|
|
11
11
|
"bench:profiler": "node benchmark/profiler",
|
|
12
12
|
"bench:e2e": "SERVICES=mongo yarn services && cd benchmark/e2e && node benchmark-run.js --duration=30",
|
|
13
|
+
"bench:e2e:ci-visibility": "node benchmark/e2e-ci/benchmark-run.js",
|
|
13
14
|
"type:doc": "cd docs && yarn && yarn build",
|
|
14
15
|
"type:test": "cd docs && yarn && yarn test",
|
|
15
16
|
"lint": "node scripts/check_licenses.js && eslint . && yarn audit --groups dependencies",
|
|
@@ -58,11 +59,11 @@
|
|
|
58
59
|
"node": ">=12"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"@datadog/native-appsec": "^0.
|
|
62
|
-
"@datadog/native-metrics": "^1.0
|
|
62
|
+
"@datadog/native-appsec": "^0.7.0",
|
|
63
|
+
"@datadog/native-metrics": "^1.1.0",
|
|
63
64
|
"@datadog/pprof": "^0.3.0",
|
|
64
65
|
"@datadog/sketches-js": "^1.0.4",
|
|
65
|
-
"@types/node": "
|
|
66
|
+
"@types/node": ">=12",
|
|
66
67
|
"crypto-randomuuid": "^1.0.0",
|
|
67
68
|
"diagnostics_channel": "^1.1.0",
|
|
68
69
|
"form-data": "^3.0.0",
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel, addHook, bind } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
const rrtypes = {
|
|
7
|
+
resolveAny: 'ANY',
|
|
8
|
+
resolve4: 'A',
|
|
9
|
+
resolve6: 'AAAA',
|
|
10
|
+
resolveCname: 'CNAME',
|
|
11
|
+
resolveMx: 'MX',
|
|
12
|
+
resolveNs: 'NS',
|
|
13
|
+
resolveTxt: 'TXT',
|
|
14
|
+
resolveSrv: 'SRV',
|
|
15
|
+
resolvePtr: 'PTR',
|
|
16
|
+
resolveNaptr: 'NAPTR',
|
|
17
|
+
resolveSoa: 'SOA'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const rrtypeMap = new WeakMap()
|
|
21
|
+
|
|
22
|
+
addHook({ name: 'dns' }, dns => {
|
|
23
|
+
dns.lookup = wrap('apm:dns:lookup', dns.lookup, 2)
|
|
24
|
+
dns.lookupService = wrap('apm:dns:lookup_service', dns.lookupService, 3)
|
|
25
|
+
dns.resolve = wrap('apm:dns:resolve', dns.resolve, 2)
|
|
26
|
+
dns.reverse = wrap('apm:dns:reverse', dns.reverse, 2)
|
|
27
|
+
|
|
28
|
+
patchResolveShorthands(dns)
|
|
29
|
+
|
|
30
|
+
if (dns.Resolver) {
|
|
31
|
+
dns.Resolver.prototype.resolve = wrap('apm:dns:resolve', dns.Resolver.prototype.resolve, 2)
|
|
32
|
+
dns.Resolver.prototype.reverse = wrap('apm:dns:reverse', dns.Resolver.prototype.reverse, 2)
|
|
33
|
+
|
|
34
|
+
patchResolveShorthands(dns.Resolver.prototype)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return dns
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
function patchResolveShorthands (prototype) {
|
|
41
|
+
Object.keys(rrtypes)
|
|
42
|
+
.filter(method => !!prototype[method])
|
|
43
|
+
.forEach(method => {
|
|
44
|
+
rrtypeMap.set(prototype[method], rrtypes[method])
|
|
45
|
+
prototype[method] = wrap('apm:dns:resolve', prototype[method], 2, rrtypes[method])
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function wrap (prefix, fn, expectedArgs, rrtype) {
|
|
50
|
+
const startCh = channel(prefix + ':start')
|
|
51
|
+
const endCh = channel(prefix + ':end')
|
|
52
|
+
const asyncEndCh = channel(prefix + ':async-end')
|
|
53
|
+
const errorCh = channel(prefix + ':error')
|
|
54
|
+
|
|
55
|
+
const wrapped = function () {
|
|
56
|
+
const cb = bind(arguments[arguments.length - 1])
|
|
57
|
+
if (
|
|
58
|
+
!startCh.hasSubscribers ||
|
|
59
|
+
arguments.length < expectedArgs ||
|
|
60
|
+
typeof cb !== 'function'
|
|
61
|
+
) {
|
|
62
|
+
return fn.apply(this, arguments)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const startArgs = Array.from(arguments)
|
|
66
|
+
startArgs.pop() // gets rid of the callback
|
|
67
|
+
if (rrtype) {
|
|
68
|
+
startArgs.push(rrtype)
|
|
69
|
+
}
|
|
70
|
+
startCh.publish(startArgs)
|
|
71
|
+
|
|
72
|
+
arguments[arguments.length - 1] = function (error, result) {
|
|
73
|
+
if (error) {
|
|
74
|
+
errorCh.publish(error)
|
|
75
|
+
}
|
|
76
|
+
asyncEndCh.publish(result)
|
|
77
|
+
cb.apply(this, arguments)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
return fn.apply(this, arguments)
|
|
82
|
+
// TODO deal with promise versions when we support `dns/promises`
|
|
83
|
+
} catch (error) {
|
|
84
|
+
error.stack // trigger getting the stack at the original throwing point
|
|
85
|
+
errorCh.publish(error)
|
|
86
|
+
|
|
87
|
+
throw error
|
|
88
|
+
} finally {
|
|
89
|
+
endCh.publish(undefined)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return shimmer.wrap(fn, wrapped)
|
|
94
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const dc = require('diagnostics_channel')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const semver = require('semver')
|
|
6
|
+
const iitm = require('../../../dd-trace/src/iitm')
|
|
7
|
+
const ritm = require('../../../dd-trace/src/ritm')
|
|
8
|
+
const parse = require('module-details-from-path')
|
|
9
|
+
const requirePackageJson = require('../../../dd-trace/src/require-package-json')
|
|
10
|
+
const { AsyncResource } = require('async_hooks')
|
|
11
|
+
|
|
12
|
+
const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
|
|
13
|
+
const channelMap = {}
|
|
14
|
+
exports.channel = function channel (name) {
|
|
15
|
+
const maybe = channelMap[name]
|
|
16
|
+
if (maybe) return maybe
|
|
17
|
+
const ch = dc.channel(name)
|
|
18
|
+
channelMap[name] = ch
|
|
19
|
+
return ch
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.addHook = function addHook ({ name, versions, file }, hook) {
|
|
23
|
+
file = filename(name, file)
|
|
24
|
+
const loaderHook = (moduleExports, moduleName, moduleBaseDir) => {
|
|
25
|
+
moduleName = moduleName.replace(pathSepExpr, '/')
|
|
26
|
+
const moduleVersion = getVersion(moduleBaseDir)
|
|
27
|
+
if (moduleName !== file || !matchVersion(moduleVersion, versions)) {
|
|
28
|
+
return moduleExports
|
|
29
|
+
}
|
|
30
|
+
return hook(moduleExports)
|
|
31
|
+
}
|
|
32
|
+
ritm([name], loaderHook)
|
|
33
|
+
cjsPostLoad({ name, versions, file }, hook)
|
|
34
|
+
iitm([name], loaderHook)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function matchVersion (version, ranges) {
|
|
38
|
+
return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getVersion (moduleBaseDir) {
|
|
42
|
+
if (moduleBaseDir) {
|
|
43
|
+
return requirePackageJson(moduleBaseDir, module).version
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function filename (name, file) {
|
|
48
|
+
return [name, file].filter(val => val).join('/')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// TODO this is basically Loader#_getModules + running the hook. DRY up.
|
|
52
|
+
function cjsPostLoad (instrumentation, hook) {
|
|
53
|
+
const ids = Object.keys(require.cache)
|
|
54
|
+
|
|
55
|
+
let pkg
|
|
56
|
+
|
|
57
|
+
for (let i = 0, l = ids.length; i < l; i++) {
|
|
58
|
+
if (ids[i] === instrumentation.name) {
|
|
59
|
+
hook(require.cache[ids[i]].exports)
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const id = ids[i].replace(pathSepExpr, '/')
|
|
64
|
+
|
|
65
|
+
if (!id.includes(`/node_modules/${instrumentation.name}/`)) continue
|
|
66
|
+
|
|
67
|
+
if (instrumentation.file) {
|
|
68
|
+
if (!id.endsWith(`/node_modules/${filename(instrumentation)}`)) continue
|
|
69
|
+
|
|
70
|
+
const basedir = getBasedir(ids[i])
|
|
71
|
+
|
|
72
|
+
pkg = requirePackageJson(basedir, module)
|
|
73
|
+
} else {
|
|
74
|
+
const basedir = getBasedir(ids[i])
|
|
75
|
+
|
|
76
|
+
pkg = requirePackageJson(basedir, module)
|
|
77
|
+
|
|
78
|
+
const mainFile = path.posix.normalize(pkg.main || 'index.js')
|
|
79
|
+
if (!id.endsWith(`/node_modules/${instrumentation.name}/${mainFile}`)) continue
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!matchVersion(pkg.version, instrumentation.versions)) continue
|
|
83
|
+
|
|
84
|
+
hook(require.cache[ids[i]].exports)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getBasedir (id) {
|
|
89
|
+
return parse(id).basedir.replace(pathSepExpr, '/')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (semver.satisfies(process.versions.node, '>=16.0.0')) {
|
|
93
|
+
exports.bind = AsyncResource.bind
|
|
94
|
+
exports.bindAsyncResource = AsyncResource.prototype.bind
|
|
95
|
+
} else {
|
|
96
|
+
exports.bindAsyncResource = function bindAsyncResource (fn, thisArg) {
|
|
97
|
+
thisArg = thisArg || this
|
|
98
|
+
const ret = this.runInAsyncScope.bind(this, fn, thisArg)
|
|
99
|
+
Object.defineProperties(ret, {
|
|
100
|
+
'length': {
|
|
101
|
+
configurable: true,
|
|
102
|
+
enumerable: false,
|
|
103
|
+
value: fn.length,
|
|
104
|
+
writable: false
|
|
105
|
+
},
|
|
106
|
+
'asyncResource': {
|
|
107
|
+
configurable: true,
|
|
108
|
+
enumerable: true,
|
|
109
|
+
value: this,
|
|
110
|
+
writable: true
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
return ret
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
exports.bind = function bind (fn, type, thisArg) {
|
|
117
|
+
type = type || fn.name
|
|
118
|
+
const ar = new AsyncResource(type || 'bound-anonymous-fn')
|
|
119
|
+
return exports.bindAsyncResource.call(ar, fn, thisArg)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AsyncResource } = require('async_hooks')
|
|
4
|
+
const {
|
|
5
|
+
channel,
|
|
6
|
+
addHook,
|
|
7
|
+
bind,
|
|
8
|
+
bindAsyncResource
|
|
9
|
+
} = require('./helpers/instrument')
|
|
10
|
+
const shimmer = require('../../datadog-shimmer')
|
|
11
|
+
|
|
12
|
+
addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
|
|
13
|
+
const startCh = channel('apm:memcached:command:start')
|
|
14
|
+
const startWithArgsCh = channel('apm:memcached:command:start:with-args')
|
|
15
|
+
const asyncEndCh = channel('apm:memcached:command:async-end')
|
|
16
|
+
const endCh = channel('apm:memcached:command:end')
|
|
17
|
+
const errorCh = channel('apm:memcached:command:error')
|
|
18
|
+
|
|
19
|
+
shimmer.wrap(Memcached.prototype, 'command', command => function (queryCompiler, server) {
|
|
20
|
+
if (!startCh.hasSubscribers) {
|
|
21
|
+
return command.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
25
|
+
|
|
26
|
+
const client = this
|
|
27
|
+
|
|
28
|
+
const wrappedQueryCompiler = function () {
|
|
29
|
+
const query = queryCompiler.apply(this, arguments)
|
|
30
|
+
const callback = bindAsyncResource.call(asyncResource, query.callback)
|
|
31
|
+
|
|
32
|
+
query.callback = bind(function (err) {
|
|
33
|
+
if (err) {
|
|
34
|
+
errorCh.publish(err)
|
|
35
|
+
}
|
|
36
|
+
asyncEndCh.publish(undefined)
|
|
37
|
+
|
|
38
|
+
return callback.apply(this, arguments)
|
|
39
|
+
})
|
|
40
|
+
startWithArgsCh.publish({ client, server, query })
|
|
41
|
+
|
|
42
|
+
return query
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
startCh.publish(undefined)
|
|
46
|
+
|
|
47
|
+
arguments[0] = wrappedQueryCompiler
|
|
48
|
+
|
|
49
|
+
const result = command.apply(this, arguments)
|
|
50
|
+
endCh.publish(undefined)
|
|
51
|
+
return result
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
return Memcached
|
|
55
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AsyncResource } = require('async_hooks')
|
|
4
|
+
const {
|
|
5
|
+
channel,
|
|
6
|
+
addHook,
|
|
7
|
+
bind,
|
|
8
|
+
bindAsyncResource
|
|
9
|
+
} = require('./helpers/instrument')
|
|
10
|
+
const shimmer = require('../../datadog-shimmer')
|
|
11
|
+
|
|
12
|
+
addHook({ name: 'mysql', file: 'lib/Connection.js', versions: ['>=2'] }, Connection => {
|
|
13
|
+
const startCh = channel('apm:mysql:query:start')
|
|
14
|
+
const asyncEndCh = channel('apm:mysql:query:async-end')
|
|
15
|
+
const endCh = channel('apm:mysql:query:end')
|
|
16
|
+
const errorCh = channel('apm:mysql:query:error')
|
|
17
|
+
|
|
18
|
+
shimmer.wrap(Connection.prototype, 'query', query => function () {
|
|
19
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
20
|
+
if (!startCh.hasSubscribers) {
|
|
21
|
+
return query.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const sql = arguments[0].sql ? arguments[0].sql : arguments[0]
|
|
25
|
+
const startArgs = [sql, this.config]
|
|
26
|
+
|
|
27
|
+
startCh.publish(startArgs)
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const res = query.apply(this, arguments)
|
|
31
|
+
|
|
32
|
+
if (res._callback) {
|
|
33
|
+
const cb = bindAsyncResource.call(asyncResource, res._callback)
|
|
34
|
+
res._callback = bind(function (error, result) {
|
|
35
|
+
if (error) {
|
|
36
|
+
errorCh.publish(error)
|
|
37
|
+
}
|
|
38
|
+
asyncEndCh.publish(result)
|
|
39
|
+
|
|
40
|
+
return cb.apply(this, arguments)
|
|
41
|
+
})
|
|
42
|
+
} else {
|
|
43
|
+
const cb = bind(function () {
|
|
44
|
+
asyncEndCh.publish(undefined)
|
|
45
|
+
})
|
|
46
|
+
res.on('end', cb)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return res
|
|
50
|
+
} catch (err) {
|
|
51
|
+
err.stack // trigger getting the stack at the original throwing point
|
|
52
|
+
errorCh.publish(err)
|
|
53
|
+
|
|
54
|
+
throw err
|
|
55
|
+
} finally {
|
|
56
|
+
endCh.publish(undefined)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
return Connection
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
addHook({ name: 'mysql', file: 'lib/Pool.js', versions: ['>=2'] }, Pool => {
|
|
64
|
+
shimmer.wrap(Pool.prototype, 'getConnection', getConnection => function (cb) {
|
|
65
|
+
arguments[0] = bind(cb)
|
|
66
|
+
return getConnection.apply(this, arguments)
|
|
67
|
+
})
|
|
68
|
+
return Pool
|
|
69
|
+
})
|
|
@@ -103,8 +103,8 @@ module.exports = [
|
|
|
103
103
|
name: '@cucumber/cucumber',
|
|
104
104
|
versions: ['7.0.0 - 7.2.1'],
|
|
105
105
|
file: 'lib/runtime/pickle_runner.js',
|
|
106
|
-
patch (PickleRunner, tracer) {
|
|
107
|
-
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber')
|
|
106
|
+
patch (PickleRunner, tracer, config) {
|
|
107
|
+
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', config)
|
|
108
108
|
const sourceRoot = process.cwd()
|
|
109
109
|
const pl = PickleRunner.default
|
|
110
110
|
this.wrap(
|
|
@@ -127,8 +127,8 @@ module.exports = [
|
|
|
127
127
|
name: '@cucumber/cucumber',
|
|
128
128
|
versions: ['>=7.3.0'],
|
|
129
129
|
file: 'lib/runtime/test_case_runner.js',
|
|
130
|
-
patch (TestCaseRunner, tracer) {
|
|
131
|
-
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber')
|
|
130
|
+
patch (TestCaseRunner, tracer, config) {
|
|
131
|
+
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', config)
|
|
132
132
|
const sourceRoot = process.cwd()
|
|
133
133
|
const pl = TestCaseRunner.default
|
|
134
134
|
this.wrap(
|
|
@@ -4,6 +4,7 @@ const {
|
|
|
4
4
|
TEST_SUITE,
|
|
5
5
|
TEST_STATUS,
|
|
6
6
|
TEST_FRAMEWORK_VERSION,
|
|
7
|
+
TEST_IS_RUM_ACTIVE,
|
|
7
8
|
getTestEnvironmentMetadata,
|
|
8
9
|
CI_APP_ORIGIN,
|
|
9
10
|
getTestParentSpan
|
|
@@ -66,15 +67,18 @@ module.exports = (on, config) => {
|
|
|
66
67
|
}
|
|
67
68
|
})
|
|
68
69
|
}
|
|
69
|
-
return null
|
|
70
|
+
return activeSpan ? activeSpan._spanContext._traceId.toString(10) : null
|
|
70
71
|
},
|
|
71
72
|
'dd:afterEach': (test) => {
|
|
72
|
-
const { state, error } = test
|
|
73
|
+
const { state, error, isRUMActive } = test
|
|
73
74
|
if (activeSpan) {
|
|
74
75
|
activeSpan.setTag(TEST_STATUS, CYPRESS_STATUS_TO_TEST_STATUS[state])
|
|
75
76
|
if (error) {
|
|
76
77
|
activeSpan.setTag('error', error)
|
|
77
78
|
}
|
|
79
|
+
if (isRUMActive) {
|
|
80
|
+
activeSpan.setTag(TEST_IS_RUM_ACTIVE, true)
|
|
81
|
+
}
|
|
78
82
|
activeSpan.finish()
|
|
79
83
|
}
|
|
80
84
|
activeSpan = null
|
|
@@ -3,15 +3,30 @@ beforeEach(() => {
|
|
|
3
3
|
cy.task('dd:beforeEach', {
|
|
4
4
|
testName: Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle(),
|
|
5
5
|
testSuite: Cypress.mocha.getRootSuite().file
|
|
6
|
+
}).then(traceId => {
|
|
7
|
+
Cypress.env('traceId', traceId)
|
|
6
8
|
})
|
|
7
9
|
})
|
|
8
10
|
|
|
11
|
+
after(() => {
|
|
12
|
+
cy.window().then(win => {
|
|
13
|
+
win.dispatchEvent(new Event('beforeunload'))
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
|
|
9
18
|
afterEach(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
cy.window().then(win => {
|
|
20
|
+
const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
|
|
21
|
+
const testInfo = {
|
|
22
|
+
testName: currentTest.fullTitle(),
|
|
23
|
+
testSuite: Cypress.mocha.getRootSuite().file,
|
|
24
|
+
state: currentTest.state,
|
|
25
|
+
error: currentTest.err,
|
|
26
|
+
}
|
|
27
|
+
if (win.DD_RUM) {
|
|
28
|
+
testInfo.isRUMActive = true
|
|
29
|
+
}
|
|
30
|
+
cy.task('dd:afterEach', testInfo)
|
|
16
31
|
})
|
|
17
32
|
})
|