dd-trace 2.3.1 → 2.4.2
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/init.js +26 -2
- package/index.d.ts +51 -0
- package/package.json +2 -2
- package/packages/datadog-instrumentations/index.js +10 -0
- package/packages/datadog-instrumentations/src/amqp10.js +70 -0
- package/packages/datadog-instrumentations/src/amqplib.js +58 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +191 -0
- package/packages/datadog-instrumentations/src/cucumber.js +27 -12
- package/packages/datadog-instrumentations/src/helpers/hook.js +44 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +31 -58
- package/packages/datadog-instrumentations/src/http/client.js +170 -0
- package/packages/datadog-instrumentations/src/http/server.js +61 -0
- package/packages/datadog-instrumentations/src/http.js +4 -0
- package/packages/datadog-instrumentations/src/mocha.js +139 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +179 -0
- package/packages/datadog-instrumentations/src/net.js +117 -0
- package/packages/datadog-instrumentations/src/pg.js +75 -0
- package/packages/datadog-instrumentations/src/rhea.js +224 -0
- package/packages/datadog-instrumentations/src/tedious.js +66 -0
- package/packages/datadog-plugin-amqp10/src/index.js +79 -122
- package/packages/datadog-plugin-amqplib/src/index.js +77 -142
- package/packages/datadog-plugin-cassandra-driver/src/index.js +52 -224
- package/packages/datadog-plugin-cucumber/src/index.js +3 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +4 -2
- package/packages/datadog-plugin-http/src/client.js +112 -252
- package/packages/datadog-plugin-http/src/index.js +29 -3
- package/packages/datadog-plugin-http/src/server.js +54 -32
- package/packages/datadog-plugin-jest/src/jest-environment.js +3 -3
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +5 -3
- package/packages/datadog-plugin-mocha/src/index.js +96 -207
- package/packages/datadog-plugin-mongodb-core/src/index.js +119 -3
- package/packages/datadog-plugin-net/src/index.js +65 -121
- package/packages/datadog-plugin-next/src/index.js +10 -10
- package/packages/datadog-plugin-pg/src/index.js +32 -69
- package/packages/datadog-plugin-rhea/src/index.js +59 -225
- package/packages/datadog-plugin-tedious/src/index.js +38 -86
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/recommended.json +235 -315
- package/packages/dd-trace/src/config.js +6 -0
- package/packages/dd-trace/src/iitm.js +5 -1
- package/packages/dd-trace/src/loader.js +6 -4
- package/packages/dd-trace/src/noop/tracer.js +4 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -1
- package/packages/dd-trace/src/opentracing/span.js +34 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -0
- package/packages/dd-trace/src/plugins/plugin.js +3 -1
- package/packages/dd-trace/src/plugins/util/web.js +99 -93
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/ritm.js +60 -25
- package/packages/dd-trace/src/tracer.js +16 -0
- package/packages/datadog-plugin-mongodb-core/src/legacy.js +0 -59
- package/packages/datadog-plugin-mongodb-core/src/unified.js +0 -138
- package/packages/datadog-plugin-mongodb-core/src/util.js +0 -143
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
2
5
|
|
|
3
|
-
const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
|
|
4
|
-
const { SAMPLING_PRIORITY, SPAN_TYPE, RESOURCE_NAME } = require('../../../ext/tags')
|
|
5
|
-
const { AUTO_KEEP } = require('../../../ext/priority')
|
|
6
6
|
const {
|
|
7
|
+
CI_APP_ORIGIN,
|
|
7
8
|
TEST_TYPE,
|
|
8
9
|
TEST_NAME,
|
|
9
10
|
TEST_SUITE,
|
|
11
|
+
TEST_FRAMEWORK_VERSION,
|
|
10
12
|
TEST_STATUS,
|
|
11
13
|
TEST_PARAMETERS,
|
|
12
|
-
TEST_FRAMEWORK_VERSION,
|
|
13
|
-
CI_APP_ORIGIN,
|
|
14
|
-
getTestEnvironmentMetadata,
|
|
15
|
-
getTestParametersString,
|
|
16
14
|
finishAllTraceSpans,
|
|
15
|
+
getTestEnvironmentMetadata,
|
|
16
|
+
getTestSuitePath,
|
|
17
17
|
getTestParentSpan,
|
|
18
|
-
|
|
18
|
+
getTestParametersString
|
|
19
19
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
20
|
+
const { SPAN_TYPE, RESOURCE_NAME, SAMPLING_PRIORITY } = require('../../../ext/tags')
|
|
21
|
+
const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
|
|
22
|
+
const { AUTO_KEEP } = require('../../../ext/priority')
|
|
20
23
|
|
|
21
24
|
const skippedTests = new WeakSet()
|
|
22
25
|
|
|
@@ -29,240 +32,126 @@ function getTestSpanMetadata (tracer, test, sourceRoot) {
|
|
|
29
32
|
|
|
30
33
|
return {
|
|
31
34
|
childOf,
|
|
32
|
-
|
|
35
|
+
[SPAN_TYPE]: 'test',
|
|
33
36
|
[TEST_TYPE]: 'test',
|
|
34
37
|
[TEST_NAME]: fullTestName,
|
|
35
38
|
[TEST_SUITE]: testSuite,
|
|
36
39
|
[SAMPLING_RULE_DECISION]: 1,
|
|
37
40
|
[SAMPLING_PRIORITY]: AUTO_KEEP,
|
|
38
|
-
[TEST_FRAMEWORK_VERSION]: tracer._version
|
|
41
|
+
[TEST_FRAMEWORK_VERSION]: tracer._version,
|
|
42
|
+
[RESOURCE_NAME]: `${testSuite}.${fullTestName}`
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
// This clause prevents rewrapping `this.test.fn` when it has already been wrapped.
|
|
47
|
-
if (this.test._currentRetry !== undefined && this.test._currentRetry !== 0) {
|
|
48
|
-
return runTest.apply(this, arguments)
|
|
49
|
-
}
|
|
46
|
+
class MochaPlugin extends Plugin {
|
|
47
|
+
static get name () {
|
|
48
|
+
return 'mocha'
|
|
49
|
+
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
specFunction = promisify(specFunction)
|
|
54
|
-
// otherwise you have to explicitly call done()
|
|
55
|
-
this.test.async = 0
|
|
56
|
-
this.test.sync = true
|
|
57
|
-
}
|
|
51
|
+
constructor (...args) {
|
|
52
|
+
super(...args)
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
this._testNameToParams = {}
|
|
55
|
+
this.testEnvironmentMetadata = getTestEnvironmentMetadata('mocha', this.config)
|
|
56
|
+
this.sourceRoot = process.cwd()
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
this.addSub('ci:mocha:test:start', (test) => {
|
|
59
|
+
const store = storage.getStore()
|
|
60
|
+
const span = this.startTestSpan(test)
|
|
61
|
+
|
|
62
|
+
this.enter(span, store)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
this.addSub('ci:mocha:test:async-end', (status) => {
|
|
66
|
+
// if the status is skipped the span has already been finished
|
|
67
|
+
if (status === 'skipped') {
|
|
68
|
+
return
|
|
64
69
|
}
|
|
70
|
+
const span = storage.getStore().span
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
'mocha.test',
|
|
68
|
-
{
|
|
69
|
-
type: 'test',
|
|
70
|
-
childOf,
|
|
71
|
-
resource,
|
|
72
|
-
tags: {
|
|
73
|
-
...testSpanMetadata,
|
|
74
|
-
...testEnvironmentMetadata
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
async () => {
|
|
78
|
-
const activeSpan = tracer.scope().active()
|
|
79
|
-
activeSpan.context()._trace.origin = CI_APP_ORIGIN
|
|
80
|
-
let result
|
|
81
|
-
try {
|
|
82
|
-
const context = this.test.ctx
|
|
83
|
-
result = await specFunction.call(context)
|
|
84
|
-
if (context.test.state !== 'failed' && !context.test.timedOut) {
|
|
85
|
-
activeSpan.setTag(TEST_STATUS, 'pass')
|
|
86
|
-
} else {
|
|
87
|
-
activeSpan.setTag(TEST_STATUS, 'fail')
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
// this.skip has been called
|
|
91
|
-
if (error.constructor.name === 'Pending' && !this.forbidPending) {
|
|
92
|
-
activeSpan.setTag(TEST_STATUS, 'skip')
|
|
93
|
-
} else {
|
|
94
|
-
activeSpan.setTag(TEST_STATUS, 'fail')
|
|
95
|
-
activeSpan.setTag('error', error)
|
|
96
|
-
}
|
|
97
|
-
throw error
|
|
98
|
-
} finally {
|
|
99
|
-
finishAllTraceSpans(activeSpan)
|
|
100
|
-
}
|
|
101
|
-
return result
|
|
102
|
-
}
|
|
103
|
-
)
|
|
104
|
-
return runTest.apply(this, arguments)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
72
|
+
span.setTag(TEST_STATUS, status)
|
|
108
73
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function getTests (suiteOrTest) {
|
|
112
|
-
suiteOrTest.tests.forEach(test => {
|
|
113
|
-
tests.push(test)
|
|
74
|
+
span.finish()
|
|
75
|
+
finishAllTraceSpans(span)
|
|
114
76
|
})
|
|
115
|
-
|
|
116
|
-
|
|
77
|
+
|
|
78
|
+
this.addSub('ci:mocha:test:end', () => {
|
|
79
|
+
this.exit()
|
|
117
80
|
})
|
|
118
|
-
}
|
|
119
|
-
getTests(root)
|
|
120
|
-
return tests
|
|
121
|
-
}
|
|
122
81
|
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
82
|
+
// This covers programmatically skipped tests (that do go through `runTest`)
|
|
83
|
+
this.addSub('ci:mocha:test:skip', () => {
|
|
84
|
+
const span = storage.getStore().span
|
|
85
|
+
span.setTag(TEST_STATUS, 'skip')
|
|
86
|
+
span.finish()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
this.addSub('ci:mocha:test:error', (err) => {
|
|
90
|
+
if (err) {
|
|
91
|
+
const span = storage.getStore().span
|
|
92
|
+
if (err.constructor.name === 'Pending' && !this.forbidPending) {
|
|
93
|
+
span.setTag(TEST_STATUS, 'skip')
|
|
94
|
+
} else {
|
|
95
|
+
span.setTag(TEST_STATUS, 'fail')
|
|
96
|
+
span.setTag('error', err)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
this.addSub('ci:mocha:suite:end', tests => {
|
|
131
102
|
tests.forEach(test => {
|
|
132
103
|
const { pending: isSkipped } = test
|
|
133
|
-
//
|
|
134
|
-
// should already have an associated test span.
|
|
135
|
-
// This function is called with every suite, so we need a way to mark
|
|
104
|
+
// `tests` includes every test, so we need a way to mark
|
|
136
105
|
// the test as already accounted for. We do this through `skippedTests`.
|
|
137
106
|
// If the test is already marked as skipped, we don't create an additional test span.
|
|
138
107
|
if (!isSkipped || skippedTests.has(test)) {
|
|
139
108
|
return
|
|
140
109
|
}
|
|
141
110
|
skippedTests.add(test)
|
|
142
|
-
const { childOf, resource, ...testSpanMetadata } = getTestSpanMetadata(tracer, test, sourceRoot)
|
|
143
111
|
|
|
144
|
-
const testSpan =
|
|
145
|
-
.startSpan('mocha.test', {
|
|
146
|
-
childOf,
|
|
147
|
-
tags: {
|
|
148
|
-
[SPAN_TYPE]: 'test',
|
|
149
|
-
[RESOURCE_NAME]: resource,
|
|
150
|
-
...testSpanMetadata,
|
|
151
|
-
...testEnvironmentMetadata,
|
|
152
|
-
[TEST_STATUS]: 'skip'
|
|
153
|
-
}
|
|
154
|
-
})
|
|
155
|
-
testSpan.context()._trace.origin = CI_APP_ORIGIN
|
|
112
|
+
const testSpan = this.startTestSpan(test)
|
|
156
113
|
|
|
114
|
+
testSpan.setTag(TEST_STATUS, 'skip')
|
|
157
115
|
testSpan.finish()
|
|
158
116
|
})
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
117
|
+
})
|
|
162
118
|
|
|
163
|
-
|
|
119
|
+
this.addSub('ci:mocha:hook:error', ({ test, error }) => {
|
|
120
|
+
const testSpan = this.startTestSpan(test)
|
|
121
|
+
testSpan.setTag(TEST_STATUS, 'fail')
|
|
122
|
+
testSpan.setTag('error', error)
|
|
123
|
+
testSpan.finish()
|
|
124
|
+
})
|
|
164
125
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
it.apply(this, arguments)
|
|
173
|
-
},
|
|
174
|
-
...rest
|
|
175
|
-
}
|
|
126
|
+
this.addSub('ci:mocha:test:parameterize', ({ name, params }) => {
|
|
127
|
+
this._testNameToParams[name] = params
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
this.addSub('ci:mocha:run:end', () => {
|
|
131
|
+
this.tracer._exporter._writer.flush()
|
|
132
|
+
})
|
|
176
133
|
}
|
|
177
|
-
}
|
|
178
134
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return function failWithTrace (hook, err) {
|
|
182
|
-
if (hook.type !== 'hook') {
|
|
183
|
-
/**
|
|
184
|
-
* This clause is to cover errors that are uncaught, such as:
|
|
185
|
-
* it('will fail', done => {
|
|
186
|
-
* setTimeout(() => {
|
|
187
|
-
* // will throw but will not be caught by `runTestWithTrace`
|
|
188
|
-
* expect(true).to.equal(false)
|
|
189
|
-
* done()
|
|
190
|
-
* }, 100)
|
|
191
|
-
* })
|
|
192
|
-
*/
|
|
193
|
-
const testSpan = tracer.scope().active()
|
|
194
|
-
if (!testSpan) {
|
|
195
|
-
return fail.apply(this, arguments)
|
|
196
|
-
}
|
|
197
|
-
const {
|
|
198
|
-
[TEST_NAME]: testName,
|
|
199
|
-
[TEST_SUITE]: testSuite,
|
|
200
|
-
[TEST_STATUS]: testStatus
|
|
201
|
-
} = testSpan._spanContext._tags
|
|
135
|
+
startTestSpan (test) {
|
|
136
|
+
const { childOf, ...testSpanMetadata } = getTestSpanMetadata(this.tracer, test, this.sourceRoot)
|
|
202
137
|
|
|
203
|
-
|
|
138
|
+
const testParametersString = getTestParametersString(this._testNameToParams, test.title)
|
|
139
|
+
if (testParametersString) {
|
|
140
|
+
testSpanMetadata[TEST_PARAMETERS] = testParametersString
|
|
141
|
+
}
|
|
204
142
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
return fail.apply(this, arguments)
|
|
212
|
-
}
|
|
213
|
-
if (err && hook.ctx && hook.ctx.currentTest) {
|
|
214
|
-
err.message = `${hook.title}: ${err.message}`
|
|
215
|
-
const {
|
|
216
|
-
childOf,
|
|
217
|
-
resource,
|
|
143
|
+
const testSpan = this.tracer
|
|
144
|
+
.startSpan('mocha.test', {
|
|
145
|
+
childOf,
|
|
146
|
+
tags: {
|
|
147
|
+
...this.testEnvironmentMetadata,
|
|
218
148
|
...testSpanMetadata
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
[SPAN_TYPE]: 'test',
|
|
225
|
-
[RESOURCE_NAME]: resource,
|
|
226
|
-
...testSpanMetadata,
|
|
227
|
-
...testEnvironmentMetadata,
|
|
228
|
-
[TEST_STATUS]: 'fail'
|
|
229
|
-
}
|
|
230
|
-
})
|
|
231
|
-
testSpan.setTag('error', err)
|
|
232
|
-
testSpan.context()._trace.origin = CI_APP_ORIGIN
|
|
233
|
-
testSpan.finish()
|
|
234
|
-
}
|
|
235
|
-
return fail.apply(this, arguments)
|
|
236
|
-
}
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
testSpan.context()._trace.origin = CI_APP_ORIGIN
|
|
152
|
+
|
|
153
|
+
return testSpan
|
|
237
154
|
}
|
|
238
155
|
}
|
|
239
156
|
|
|
240
|
-
module.exports =
|
|
241
|
-
{
|
|
242
|
-
name: 'mocha',
|
|
243
|
-
versions: ['>=5.2.0'],
|
|
244
|
-
file: 'lib/runner.js',
|
|
245
|
-
patch (Runner, tracer, config) {
|
|
246
|
-
const testEnvironmentMetadata = getTestEnvironmentMetadata('mocha', config)
|
|
247
|
-
const sourceRoot = process.cwd()
|
|
248
|
-
this.wrap(Runner.prototype, 'runTests', createWrapRunTests(tracer, testEnvironmentMetadata, sourceRoot))
|
|
249
|
-
this.wrap(Runner.prototype, 'runTest', createWrapRunTest(tracer, testEnvironmentMetadata, sourceRoot))
|
|
250
|
-
this.wrap(Runner.prototype, 'fail', createWrapFail(tracer, testEnvironmentMetadata, sourceRoot))
|
|
251
|
-
},
|
|
252
|
-
unpatch (Runner) {
|
|
253
|
-
this.unwrap(Runner.prototype, 'runTests')
|
|
254
|
-
this.unwrap(Runner.prototype, 'runTest')
|
|
255
|
-
this.unwrap(Runner.prototype, 'fail')
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: 'mocha-each',
|
|
260
|
-
versions: ['>=2.0.1'],
|
|
261
|
-
patch (mochaEach) {
|
|
262
|
-
return this.wrapExport(mochaEach, wrapMochaEach(mochaEach))
|
|
263
|
-
},
|
|
264
|
-
unpatch (mochaEach) {
|
|
265
|
-
this.unwrapExport(mochaEach)
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
]
|
|
157
|
+
module.exports = MochaPlugin
|
|
@@ -1,6 +1,122 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
5
|
+
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
class MongodbCorePlugin extends Plugin {
|
|
8
|
+
static get name () {
|
|
9
|
+
return 'mongodb-core'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
constructor (...args) {
|
|
13
|
+
super(...args)
|
|
14
|
+
|
|
15
|
+
this.addSub(`apm:mongodb:query:start`, ({ ns, ops, options, name }) => {
|
|
16
|
+
const query = getQuery(ops)
|
|
17
|
+
const resource = getResource(ns, query, name)
|
|
18
|
+
const store = storage.getStore()
|
|
19
|
+
const childOf = store ? store.span : store
|
|
20
|
+
const span = this.tracer.startSpan('mongodb.query', {
|
|
21
|
+
childOf,
|
|
22
|
+
tags: {
|
|
23
|
+
'service.name': this.config.service || `${this.tracer._service}-mongodb`,
|
|
24
|
+
'resource.name': resource,
|
|
25
|
+
'span.type': 'mongodb',
|
|
26
|
+
'span.kind': 'client',
|
|
27
|
+
'db.name': ns
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (query) {
|
|
32
|
+
span.setTag('mongodb.query', query)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (options && options.host && options.port) {
|
|
36
|
+
span.addTags({
|
|
37
|
+
'out.host': options.host,
|
|
38
|
+
'out.port': options.port
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
43
|
+
this.enter(span, store)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
this.addSub(`apm:mongodb:query:end`, () => {
|
|
47
|
+
this.exit()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
this.addSub(`apm:mongodb:query:error`, err => {
|
|
51
|
+
storage.getStore().span.setTag('error', err)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
this.addSub(`apm:mongodb:query:async-end`, () => {
|
|
55
|
+
storage.getStore().span.finish()
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getQuery (cmd) {
|
|
61
|
+
if (!cmd || typeof cmd !== 'object' || Array.isArray(cmd)) return
|
|
62
|
+
if (cmd.query) return JSON.stringify(sanitize(cmd.query))
|
|
63
|
+
if (cmd.filter) return JSON.stringify(sanitize(cmd.filter))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getResource (ns, query, operationName) {
|
|
67
|
+
const parts = [operationName, ns]
|
|
68
|
+
|
|
69
|
+
if (query) {
|
|
70
|
+
parts.push(query)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return parts.join(' ')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function shouldHide (input) {
|
|
77
|
+
return !isObject(input) || Buffer.isBuffer(input) || isBSON(input)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function sanitize (input) {
|
|
81
|
+
if (shouldHide(input)) return '?'
|
|
82
|
+
|
|
83
|
+
const output = {}
|
|
84
|
+
const queue = [{
|
|
85
|
+
input,
|
|
86
|
+
output,
|
|
87
|
+
depth: 0
|
|
88
|
+
}]
|
|
89
|
+
|
|
90
|
+
while (queue.length) {
|
|
91
|
+
const {
|
|
92
|
+
input, output, depth
|
|
93
|
+
} = queue.pop()
|
|
94
|
+
const nextDepth = depth + 1
|
|
95
|
+
for (const key in input) {
|
|
96
|
+
if (typeof input[key] === 'function') continue
|
|
97
|
+
|
|
98
|
+
const child = input[key]
|
|
99
|
+
if (depth >= 20 || shouldHide(child)) {
|
|
100
|
+
output[key] = '?'
|
|
101
|
+
} else {
|
|
102
|
+
queue.push({
|
|
103
|
+
input: child,
|
|
104
|
+
output: output[key] = {},
|
|
105
|
+
depth: nextDepth
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return output
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function isObject (val) {
|
|
115
|
+
return typeof val === 'object' && val !== null && !(val instanceof Array)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isBSON (val) {
|
|
119
|
+
return val && val._bsontype
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = MongodbCorePlugin
|