dd-trace 2.4.2 → 2.7.0
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/LICENSE-3rdparty.csv +1 -2
- package/ci/init.js +6 -0
- package/ci/jest/env.js +16 -3
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +17 -8
- package/package.json +20 -23
- package/packages/datadog-instrumentations/index.js +14 -0
- package/packages/datadog-instrumentations/src/connect.js +111 -0
- package/packages/datadog-instrumentations/src/cypress.js +8 -0
- package/packages/datadog-instrumentations/src/express.js +27 -0
- package/packages/datadog-instrumentations/src/fastify.js +187 -0
- package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +175 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
- package/packages/datadog-instrumentations/src/knex.js +20 -0
- package/packages/datadog-instrumentations/src/koa.js +159 -0
- package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
- package/packages/datadog-instrumentations/src/oracledb.js +128 -0
- package/packages/datadog-instrumentations/src/paperplane.js +77 -0
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/restify.js +58 -0
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +177 -0
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
- package/packages/datadog-plugin-connect/src/index.js +10 -114
- package/packages/datadog-plugin-cucumber/src/index.js +16 -16
- package/packages/datadog-plugin-cypress/src/index.js +10 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
- package/packages/datadog-plugin-dns/src/index.js +12 -1
- package/packages/datadog-plugin-express/src/index.js +11 -25
- package/packages/datadog-plugin-fastify/src/index.js +17 -4
- package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
- package/packages/datadog-plugin-fs/src/index.js +2 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
- package/packages/datadog-plugin-http/src/server.js +2 -10
- package/packages/datadog-plugin-jest/src/index.js +101 -3
- package/packages/datadog-plugin-jest/src/util.js +1 -29
- package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
- package/packages/datadog-plugin-koa/src/index.js +12 -164
- package/packages/datadog-plugin-mocha/src/index.js +14 -15
- package/packages/datadog-plugin-oracledb/src/index.js +34 -100
- package/packages/datadog-plugin-paperplane/src/index.js +14 -100
- package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
- package/packages/datadog-plugin-paperplane/src/server.js +24 -0
- package/packages/datadog-plugin-restify/src/index.js +13 -75
- package/packages/datadog-plugin-router/src/index.js +67 -164
- package/packages/datadog-plugin-web/src/index.js +20 -0
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
- package/packages/dd-trace/src/appsec/index.js +7 -3
- package/packages/dd-trace/src/appsec/recommended.json +15 -5
- package/packages/dd-trace/src/appsec/reporter.js +33 -3
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
- package/packages/dd-trace/src/config.js +33 -4
- package/packages/dd-trace/src/encode/0.4.js +0 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
- package/packages/dd-trace/src/encode/tags-processors.js +116 -0
- package/packages/dd-trace/src/exporter.js +3 -0
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
- package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
- package/packages/dd-trace/src/exporters/common/request.js +83 -0
- package/packages/dd-trace/src/exporters/common/writer.js +36 -0
- package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
- package/packages/dd-trace/src/format.js +9 -5
- package/packages/dd-trace/src/instrumenter.js +3 -0
- package/packages/dd-trace/src/pkg.js +11 -6
- package/packages/dd-trace/src/plugin_manager.js +13 -7
- package/packages/dd-trace/src/plugins/index.js +1 -2
- package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
- package/packages/dd-trace/src/plugins/plugin.js +8 -0
- package/packages/dd-trace/src/plugins/util/test.js +79 -1
- package/packages/dd-trace/src/plugins/util/web.js +41 -12
- package/packages/dd-trace/src/profiling/config.js +8 -8
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/index.js +4 -4
- package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
- package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +4 -1
- package/packages/dd-trace/src/telemetry.js +187 -0
- package/scripts/install_plugin_modules.js +1 -0
- package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
- package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
- package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
- package/packages/datadog-plugin-knex/src/index.js +0 -23
- package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
- package/packages/dd-trace/src/exporters/agent/request.js +0 -86
- package/scripts/postpublish.js +0 -24
|
@@ -1,111 +1,25 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const PaperplaneLoggerPlugin = require('./logger')
|
|
5
|
+
const PaperplaneServerPlugin = require('./server')
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (web.active(original)) {
|
|
9
|
-
web.enterRoute(original, route)
|
|
7
|
+
class PaperplanePlugin extends Plugin {
|
|
8
|
+
static get name () {
|
|
9
|
+
return 'paperplane'
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const wrapLogger = tracer => logger => record => {
|
|
16
|
-
const span = tracer.scope().active()
|
|
12
|
+
constructor (...args) {
|
|
13
|
+
super(...args)
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const correlation = {
|
|
21
|
-
dd: {
|
|
22
|
-
trace_id: span.context().toTraceId(),
|
|
23
|
-
span_id: span.context().toSpanId()
|
|
24
|
-
}
|
|
15
|
+
this.server = new PaperplaneServerPlugin(...args)
|
|
16
|
+
this.logger = new PaperplaneLoggerPlugin(...args)
|
|
25
17
|
}
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return logger(record)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const wrapMount = (tracer, config) => mount => opts => {
|
|
35
|
-
const handler = mount(opts)
|
|
36
|
-
|
|
37
|
-
const traced = (req, res) =>
|
|
38
|
-
web.instrument(
|
|
39
|
-
tracer, config, req, res, 'paperplane.request',
|
|
40
|
-
() => handler(req, res)
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
return traced
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const wrapRoutes = tracer => routes => handlers => {
|
|
47
|
-
const traced = {}
|
|
48
|
-
|
|
49
|
-
for (const route in handlers) {
|
|
50
|
-
traced[route] = traceRoute(handlers[route])
|
|
19
|
+
configure (config) {
|
|
20
|
+
this.server.configure(config)
|
|
21
|
+
this.logger.configure(config)
|
|
51
22
|
}
|
|
52
|
-
|
|
53
|
-
return routes(traced)
|
|
54
23
|
}
|
|
55
24
|
|
|
56
|
-
|
|
57
|
-
const mainVersionRange = nodeMajor <= 12 ? ['>=2.3.2'] : nodeMajor <= 14 ? ['>=3.1.1'] : []
|
|
58
|
-
|
|
59
|
-
module.exports = [
|
|
60
|
-
{
|
|
61
|
-
name: 'paperplane',
|
|
62
|
-
versions: mainVersionRange,
|
|
63
|
-
file: 'lib/logger.js',
|
|
64
|
-
patch (exports, tracer) {
|
|
65
|
-
if (tracer._logInjection) {
|
|
66
|
-
this.wrap(exports, 'logger', wrapLogger(tracer))
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
unpatch (exports) {
|
|
70
|
-
this.unwrap(exports, 'logger')
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: 'paperplane',
|
|
75
|
-
versions: mainVersionRange,
|
|
76
|
-
file: 'lib/mount.js',
|
|
77
|
-
patch (exports, tracer, config) {
|
|
78
|
-
config = web.normalizeConfig(config)
|
|
79
|
-
this.wrap(exports, 'mount', wrapMount(tracer, config))
|
|
80
|
-
},
|
|
81
|
-
unpatch (exports) {
|
|
82
|
-
this.unwrap(exports, 'mount')
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: 'paperplane',
|
|
87
|
-
versions: mainVersionRange,
|
|
88
|
-
file: 'lib/routes.js',
|
|
89
|
-
patch (exports, tracer) {
|
|
90
|
-
this.wrap(exports, 'routes', wrapRoutes(tracer))
|
|
91
|
-
},
|
|
92
|
-
unpatch (exports) {
|
|
93
|
-
this.unwrap(exports, 'routes')
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
]
|
|
97
|
-
|
|
98
|
-
if (nodeMajor <= 12) {
|
|
99
|
-
module.exports.push({
|
|
100
|
-
name: 'paperplane',
|
|
101
|
-
versions: ['2.3.0 - 2.3.1'],
|
|
102
|
-
patch (paperplane, tracer, config) {
|
|
103
|
-
config = web.normalizeConfig(config)
|
|
104
|
-
this.wrap(paperplane, 'mount', wrapMount(tracer, config))
|
|
105
|
-
this.wrap(paperplane, 'routes', wrapRoutes(tracer))
|
|
106
|
-
},
|
|
107
|
-
unpatch (paperplane) {
|
|
108
|
-
this.unwrap(paperplane, ['mount', 'routes'])
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
}
|
|
25
|
+
module.exports = PaperplanePlugin
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const RouterPlugin = require('../../datadog-plugin-router/src')
|
|
4
|
+
const web = require('../../dd-trace/src/plugins/util/web')
|
|
5
|
+
|
|
6
|
+
class PaperplaneServerPlugin extends RouterPlugin {
|
|
7
|
+
static get name () {
|
|
8
|
+
return 'paperplane'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
constructor (...args) {
|
|
12
|
+
super(...args)
|
|
13
|
+
|
|
14
|
+
this.addSub('apm:paperplane:request:handle', req => {
|
|
15
|
+
this.setFramework(req, 'paperplane', this.config)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
this.addSub('apm:paperplane:request:route', ({ req, route }) => {
|
|
19
|
+
web.setRoute(req, route)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = PaperplaneServerPlugin
|
|
@@ -1,86 +1,24 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const RouterPlugin = require('../../datadog-plugin-router/src')
|
|
3
4
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
4
|
-
const handlers = ['use', 'pre']
|
|
5
|
-
const methods = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return function wrapSetupRequest (setupRequest) {
|
|
11
|
-
return function setupRequestWithTrace (req, res) {
|
|
12
|
-
return web.instrument(tracer, config, req, res, 'restify.request', () => {
|
|
13
|
-
web.beforeEnd(req, () => {
|
|
14
|
-
if (req.route && withRoute) {
|
|
15
|
-
web.enterRoute(req, req.route.path)
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
return setupRequest.apply(this, arguments)
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function createWrapMethod (tracer, config) {
|
|
26
|
-
return function wrapMethod (method) {
|
|
27
|
-
return function methodWithTrace (path) {
|
|
28
|
-
const middleware = wrapMiddleware(Array.prototype.slice.call(arguments, 1))
|
|
29
|
-
|
|
30
|
-
return method.apply(this, [path].concat(middleware))
|
|
31
|
-
}
|
|
6
|
+
class RestifyPlugin extends RouterPlugin {
|
|
7
|
+
static get name () {
|
|
8
|
+
return 'restify'
|
|
32
9
|
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function createWrapHandler (tracer, config) {
|
|
36
|
-
return function wrapMethod (method) {
|
|
37
|
-
return function methodWithTrace () {
|
|
38
|
-
return method.apply(this, wrapMiddleware(arguments))
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
10
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
11
|
+
constructor (...args) {
|
|
12
|
+
super(...args)
|
|
46
13
|
|
|
47
|
-
|
|
48
|
-
|
|
14
|
+
this.addSub('apm:restify:request:handle', ({ req }) => {
|
|
15
|
+
this.setFramework(req, 'restify', this.config)
|
|
16
|
+
})
|
|
49
17
|
|
|
50
|
-
|
|
51
|
-
|
|
18
|
+
this.addSub('apm:restify:request:route', ({ req, route }) => {
|
|
19
|
+
web.setRoute(req, route)
|
|
20
|
+
})
|
|
52
21
|
}
|
|
53
22
|
}
|
|
54
23
|
|
|
55
|
-
module.exports =
|
|
56
|
-
{
|
|
57
|
-
name: 'restify',
|
|
58
|
-
versions: ['>=7'],
|
|
59
|
-
file: 'lib/server.js',
|
|
60
|
-
patch (Server, tracer, config) {
|
|
61
|
-
this.wrap(Server.prototype, '_setupRequest', createWrapSetupRequest(tracer, config))
|
|
62
|
-
this.wrap(Server.prototype, handlers, createWrapHandler(tracer, config))
|
|
63
|
-
this.wrap(Server.prototype, methods, createWrapMethod(tracer, config))
|
|
64
|
-
},
|
|
65
|
-
unpatch (Server) {
|
|
66
|
-
this.unwrap(Server.prototype, '_setupRequest')
|
|
67
|
-
this.unwrap(Server.prototype, handlers)
|
|
68
|
-
this.unwrap(Server.prototype, methods)
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: 'restify',
|
|
73
|
-
versions: ['3 - 6'],
|
|
74
|
-
file: 'lib/server.js',
|
|
75
|
-
patch (Server, tracer, config) {
|
|
76
|
-
this.wrap(Server.prototype, '_setupRequest', createWrapSetupRequest(tracer, config, true))
|
|
77
|
-
this.wrap(Server.prototype, handlers, createWrapHandler(tracer, config))
|
|
78
|
-
this.wrap(Server.prototype, methods, createWrapMethod(tracer, config))
|
|
79
|
-
},
|
|
80
|
-
unpatch (Server) {
|
|
81
|
-
this.unwrap(Server.prototype, '_setupRequest')
|
|
82
|
-
this.unwrap(Server.prototype, handlers)
|
|
83
|
-
this.unwrap(Server.prototype, methods)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
]
|
|
24
|
+
module.exports = RestifyPlugin
|
|
@@ -1,204 +1,107 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const METHODS = require('methods').concat('all')
|
|
4
|
-
const pathToRegExp = require('path-to-regexp')
|
|
5
|
-
const shimmer = require('../../datadog-shimmer')
|
|
6
3
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
4
|
+
const WebPlugin = require('../../datadog-plugin-web/src')
|
|
5
|
+
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
6
|
+
const { storage } = require('../../datadog-core')
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const layerMatchers = new WeakMap()
|
|
12
|
-
const regexpCache = Object.create(null)
|
|
13
|
-
|
|
14
|
-
function createWrapHandle (tracer, config) {
|
|
15
|
-
return function wrapHandle (handle) {
|
|
16
|
-
return function handleWithTrace (req, res, done) {
|
|
17
|
-
web.patch(req)
|
|
18
|
-
|
|
19
|
-
if (!contexts.has(req)) {
|
|
20
|
-
const context = {
|
|
21
|
-
route: '',
|
|
22
|
-
stack: []
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
web.beforeEnd(req, () => {
|
|
26
|
-
web.enterRoute(req, context.route)
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
contexts.set(req, context)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return handle.apply(this, arguments)
|
|
33
|
-
}
|
|
8
|
+
class RouterPlugin extends WebPlugin {
|
|
9
|
+
static get name () {
|
|
10
|
+
return 'router'
|
|
34
11
|
}
|
|
35
|
-
}
|
|
36
12
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const offset = this.stack ? [].concat(this.stack).length : 0
|
|
40
|
-
const router = original.apply(this, arguments)
|
|
13
|
+
constructor (...args) {
|
|
14
|
+
super(...args)
|
|
41
15
|
|
|
42
|
-
|
|
43
|
-
this.stack = [{ handle: this.stack }]
|
|
44
|
-
}
|
|
16
|
+
this._contexts = new WeakMap()
|
|
45
17
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
18
|
+
this.addSub(`apm:${this.constructor.name}:middleware:enter`, ({ req, name, route }) => {
|
|
19
|
+
const store = storage.getStore()
|
|
20
|
+
const context = this._createContext(req, route)
|
|
21
|
+
const span = this._getMiddlewareSpan(context, store, name)
|
|
51
22
|
|
|
52
|
-
|
|
53
|
-
handle._name = handle._name || layer.name
|
|
23
|
+
this.enter(span, store)
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (handle.length === 4) {
|
|
58
|
-
wrapCallHandle = shimmer.wrap(handle, function (error, req, res, next) {
|
|
59
|
-
return callHandle(layer, handle, req, [error, req, res, wrapNext(layer, req, next)])
|
|
60
|
-
})
|
|
61
|
-
} else {
|
|
62
|
-
wrapCallHandle = shimmer.wrap(handle, function (req, res, next) {
|
|
63
|
-
return callHandle(layer, handle, req, [req, res, wrapNext(layer, req, next)])
|
|
25
|
+
web.patch(req)
|
|
26
|
+
web.setRoute(req, context.route)
|
|
64
27
|
})
|
|
65
|
-
}
|
|
66
28
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
wrapCallHandle._datadog_orig = handle
|
|
29
|
+
this.addSub(`apm:${this.constructor.name}:middleware:exit`, ({ req }) => {
|
|
30
|
+
const context = this._contexts.get(req)
|
|
70
31
|
|
|
71
|
-
|
|
72
|
-
}
|
|
32
|
+
if (!context) return
|
|
73
33
|
|
|
74
|
-
|
|
75
|
-
[].concat(stack).slice(offset).forEach(layer => {
|
|
76
|
-
if (layer.__handle) { // express-async-errors
|
|
77
|
-
layer.__handle = wrapLayerHandle(layer, layer.__handle)
|
|
78
|
-
} else {
|
|
79
|
-
layer.handle = wrapLayerHandle(layer, layer.handle)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
layerMatchers.set(layer, matchers)
|
|
83
|
-
|
|
84
|
-
if (layer.route) {
|
|
85
|
-
METHODS.forEach(method => {
|
|
86
|
-
if (typeof layer.route.stack === 'function') {
|
|
87
|
-
layer.route.stack = [{ handle: layer.route.stack }]
|
|
88
|
-
}
|
|
34
|
+
context.stack.pop()
|
|
89
35
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
36
|
+
if (context.middleware.length > 0) {
|
|
37
|
+
context.middleware.pop().finish()
|
|
38
|
+
}
|
|
39
|
+
})
|
|
95
40
|
|
|
96
|
-
|
|
97
|
-
if (!next || !web.active(req)) return next
|
|
41
|
+
this.addSub(`apm:${this.constructor.name}:middleware:error`, this.addError)
|
|
98
42
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const matchers = layerMatchers.get(layer)
|
|
43
|
+
this.addSub(`apm:http:server:request:finish`, ({ req }) => {
|
|
44
|
+
const context = this._contexts.get(req)
|
|
102
45
|
|
|
103
|
-
|
|
104
|
-
if (layer.path && !isFastStar(layer, matchers) && !isFastSlash(layer, matchers)) {
|
|
105
|
-
context.stack.pop()
|
|
106
|
-
}
|
|
46
|
+
if (!context) return
|
|
107
47
|
|
|
108
|
-
|
|
48
|
+
let span
|
|
109
49
|
|
|
110
|
-
|
|
50
|
+
while ((span = context.middleware.pop())) {
|
|
51
|
+
span.finish()
|
|
52
|
+
}
|
|
53
|
+
})
|
|
111
54
|
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function callHandle (layer, handle, req, args) {
|
|
115
|
-
const matchers = layerMatchers.get(layer)
|
|
116
55
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
for (let i = 0; i < matchers.length; i++) {
|
|
120
|
-
if (matchers[i].test(layer)) {
|
|
121
|
-
const context = contexts.get(req)
|
|
56
|
+
_getMiddlewareSpan (context, store, name) {
|
|
57
|
+
const childOf = store && store.span
|
|
122
58
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Longer route is more likely to be the actual route handler route.
|
|
128
|
-
if (route.length > context.route.length) {
|
|
129
|
-
context.route = route
|
|
130
|
-
}
|
|
59
|
+
if (this.config.middleware === false) {
|
|
60
|
+
return childOf
|
|
61
|
+
}
|
|
131
62
|
|
|
132
|
-
|
|
63
|
+
const span = this.tracer.startSpan(`${this.constructor.name}.middleware`, {
|
|
64
|
+
childOf,
|
|
65
|
+
tags: {
|
|
66
|
+
'resource.name': name || '<anonymous>'
|
|
133
67
|
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
68
|
+
})
|
|
136
69
|
|
|
137
|
-
|
|
138
|
-
return handle.apply(layer, args)
|
|
139
|
-
})
|
|
140
|
-
}
|
|
70
|
+
context.middleware.push(span)
|
|
141
71
|
|
|
142
|
-
|
|
143
|
-
const arg = flatten([].concat(fn))
|
|
72
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
144
73
|
|
|
145
|
-
|
|
146
|
-
return []
|
|
74
|
+
return span
|
|
147
75
|
}
|
|
148
76
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
test: layer => {
|
|
152
|
-
const matchers = layerMatchers.get(layer)
|
|
77
|
+
_createContext (req, route) {
|
|
78
|
+
let context = this._contexts.get(req)
|
|
153
79
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
cachedPathToRegExp(pattern).test(layer.path)
|
|
80
|
+
if (!route || route === '/' || route === '*') {
|
|
81
|
+
route = ''
|
|
157
82
|
}
|
|
158
|
-
}))
|
|
159
|
-
}
|
|
160
83
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return layer.regexp.fast_star
|
|
164
|
-
}
|
|
84
|
+
if (context) {
|
|
85
|
+
context.stack.push(route)
|
|
165
86
|
|
|
166
|
-
|
|
167
|
-
}
|
|
87
|
+
route = context.stack.join('')
|
|
168
88
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
89
|
+
// Longer route is more likely to be the actual route handler route.
|
|
90
|
+
if (route.length > context.route.length) {
|
|
91
|
+
context.route = route
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
context = {
|
|
95
|
+
stack: [route],
|
|
96
|
+
route,
|
|
97
|
+
middleware: []
|
|
98
|
+
}
|
|
176
99
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
100
|
+
this._contexts.set(req, context)
|
|
101
|
+
}
|
|
180
102
|
|
|
181
|
-
|
|
182
|
-
const maybeCached = regexpCache[pattern]
|
|
183
|
-
if (maybeCached) {
|
|
184
|
-
return maybeCached
|
|
103
|
+
return context
|
|
185
104
|
}
|
|
186
|
-
const regexp = pathToRegExp(pattern)
|
|
187
|
-
regexpCache[pattern] = regexp
|
|
188
|
-
return regexp
|
|
189
105
|
}
|
|
190
106
|
|
|
191
|
-
module.exports =
|
|
192
|
-
name: 'router',
|
|
193
|
-
versions: ['>=1'],
|
|
194
|
-
patch (Router, tracer, config) {
|
|
195
|
-
this.wrap(Router.prototype, 'handle', createWrapHandle(tracer, config))
|
|
196
|
-
this.wrap(Router.prototype, 'use', wrapRouterMethod)
|
|
197
|
-
this.wrap(Router.prototype, 'route', wrapRouterMethod)
|
|
198
|
-
},
|
|
199
|
-
unpatch (Router) {
|
|
200
|
-
this.unwrap(Router.prototype, 'handle')
|
|
201
|
-
this.unwrap(Router.prototype, 'use')
|
|
202
|
-
this.unwrap(Router.prototype, 'route')
|
|
203
|
-
}
|
|
204
|
-
}
|
|
107
|
+
module.exports = RouterPlugin
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const web = require('../../dd-trace/src/plugins/util/web')
|
|
5
|
+
|
|
6
|
+
class WebPlugin extends Plugin {
|
|
7
|
+
static get name () {
|
|
8
|
+
return 'web'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
configure (config) {
|
|
12
|
+
return super.configure(web.normalizeConfig(config))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
setFramework (req, name, config) {
|
|
16
|
+
web.setFramework(req, name, config)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = WebPlugin
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = '2.
|
|
1
|
+
module.exports = '2.7.0'
|
|
@@ -7,16 +7,14 @@ const Reporter = require('../reporter')
|
|
|
7
7
|
|
|
8
8
|
const validAddressSet = new Set(Object.values(addresses))
|
|
9
9
|
|
|
10
|
-
const DEFAULT_MAX_BUDGET = 5e3 // µs
|
|
11
|
-
|
|
12
10
|
// TODO: put reusable code in a base class
|
|
13
11
|
class WAFCallback {
|
|
14
|
-
static loadDDWAF (rules) {
|
|
12
|
+
static loadDDWAF (rules, config) {
|
|
15
13
|
try {
|
|
16
14
|
// require in `try/catch` because this can throw at require time
|
|
17
15
|
const { DDWAF } = require('@datadog/native-appsec')
|
|
18
16
|
|
|
19
|
-
return new DDWAF(rules)
|
|
17
|
+
return new DDWAF(rules, config)
|
|
20
18
|
} catch (err) {
|
|
21
19
|
log.error('AppSec could not load native package. In-app WAF features will not be available.')
|
|
22
20
|
|
|
@@ -24,8 +22,24 @@ class WAFCallback {
|
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
constructor (rules) {
|
|
28
|
-
|
|
25
|
+
constructor (rules, config) {
|
|
26
|
+
const { wafTimeout, obfuscatorKeyRegex, obfuscatorValueRegex } = config
|
|
27
|
+
|
|
28
|
+
this.ddwaf = WAFCallback.loadDDWAF(rules, { obfuscatorKeyRegex, obfuscatorValueRegex })
|
|
29
|
+
|
|
30
|
+
this.wafTimeout = wafTimeout
|
|
31
|
+
|
|
32
|
+
const version = this.ddwaf.constructor.version()
|
|
33
|
+
|
|
34
|
+
Reporter.metricsQueue.set('_dd.appsec.waf.version', `${version.major}.${version.minor}.${version.patch}`)
|
|
35
|
+
|
|
36
|
+
const { loaded, failed } = this.ddwaf.rulesInfo
|
|
37
|
+
|
|
38
|
+
Reporter.metricsQueue.set('_dd.appsec.event_rules.loaded', loaded)
|
|
39
|
+
Reporter.metricsQueue.set('_dd.appsec.event_rules.error_count', failed)
|
|
40
|
+
|
|
41
|
+
Reporter.metricsQueue.set('manual.keep', true)
|
|
42
|
+
|
|
29
43
|
this.wafContextCache = new WeakMap()
|
|
30
44
|
|
|
31
45
|
// closures are faster than binds
|
|
@@ -70,7 +84,7 @@ class WAFCallback {
|
|
|
70
84
|
}
|
|
71
85
|
}
|
|
72
86
|
|
|
73
|
-
if (!wafContext) {
|
|
87
|
+
if (!wafContext || wafContext.disposed) {
|
|
74
88
|
wafContext = this.ddwaf.createContext()
|
|
75
89
|
}
|
|
76
90
|
|
|
@@ -81,23 +95,31 @@ class WAFCallback {
|
|
|
81
95
|
|
|
82
96
|
try {
|
|
83
97
|
// TODO: possible optimizaion: only send params that haven't already been sent to this wafContext
|
|
84
|
-
const
|
|
98
|
+
const start = process.hrtime.bigint()
|
|
99
|
+
|
|
100
|
+
const result = wafContext.run(params, this.wafTimeout)
|
|
101
|
+
|
|
102
|
+
result.durationExt = parseInt(process.hrtime.bigint() - start)
|
|
85
103
|
|
|
86
104
|
return this.applyResult(result, store)
|
|
87
105
|
} catch (err) {
|
|
88
106
|
log.error('Error while running the AppSec WAF')
|
|
89
107
|
log.error(err)
|
|
108
|
+
} finally {
|
|
109
|
+
wafContext.dispose()
|
|
90
110
|
}
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
applyResult (result, store) {
|
|
114
|
+
Reporter.reportMetrics({
|
|
115
|
+
duration: result.totalRuntime / 1e3,
|
|
116
|
+
durationExt: result.durationExt / 1e3,
|
|
117
|
+
rulesVersion: this.ddwaf.rulesInfo.version
|
|
118
|
+
}, store)
|
|
119
|
+
|
|
94
120
|
if (result.data && result.data !== '[]') {
|
|
95
121
|
Reporter.reportAttack(result.data, store)
|
|
96
122
|
}
|
|
97
|
-
|
|
98
|
-
// TODO: use these values later for budget management
|
|
99
|
-
// result.perfData
|
|
100
|
-
// result.perfTotalRuntime
|
|
101
123
|
}
|
|
102
124
|
|
|
103
125
|
clear () {
|
|
@@ -16,7 +16,7 @@ function enable (config) {
|
|
|
16
16
|
let rules = fs.readFileSync(config.appsec.rules)
|
|
17
17
|
rules = JSON.parse(rules)
|
|
18
18
|
|
|
19
|
-
RuleManager.applyRules(rules)
|
|
19
|
+
RuleManager.applyRules(rules, config.appsec)
|
|
20
20
|
} catch (err) {
|
|
21
21
|
log.error('Unable to start AppSec')
|
|
22
22
|
log.error(err)
|
|
@@ -94,12 +94,16 @@ function incomingHttpEndTranslator (data) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
if (data.req.cookies && typeof data.req.cookies === 'object') {
|
|
97
|
-
payload[addresses.HTTP_INCOMING_COOKIES] =
|
|
97
|
+
payload[addresses.HTTP_INCOMING_COOKIES] = {}
|
|
98
|
+
|
|
99
|
+
for (const k of Object.keys(data.req.cookies)) {
|
|
100
|
+
payload[addresses.HTTP_INCOMING_COOKIES][k] = [ data.req.cookies[k] ]
|
|
101
|
+
}
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
Gateway.propagate(payload, context)
|
|
101
105
|
|
|
102
|
-
Reporter.
|
|
106
|
+
Reporter.finishRequest(data.req, context)
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
function disable () {
|