dd-trace 5.1.0 → 5.2.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 +0 -3
- package/package.json +1 -4
- package/packages/datadog-instrumentations/src/amqplib.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/mquery.js +65 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +28 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +19 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +83 -10
- package/packages/datadog-plugin-graphql/src/index.js +1 -6
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +22 -17
- package/packages/dd-trace/src/datastreams/processor.js +30 -5
- package/packages/dd-trace/src/datastreams/writer.js +9 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/tracer.js +1 -0
- package/packages/utils/src/kebabcase.js +16 -0
- package/packages/utils/src/pick.js +11 -0
- package/packages/utils/src/uniq.js +5 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -17,10 +17,7 @@ require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
|
17
17
|
require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
|
|
18
18
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
19
19
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
|
20
|
-
require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
|
|
21
|
-
require,lodash.pick,MIT,Copyright JS Foundation and other contributors
|
|
22
20
|
require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
|
|
23
|
-
require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
|
|
24
21
|
require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
|
|
25
22
|
require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
|
|
26
23
|
require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -87,10 +87,7 @@
|
|
|
87
87
|
"jest-docblock": "^29.7.0",
|
|
88
88
|
"koalas": "^1.0.2",
|
|
89
89
|
"limiter": "1.1.5",
|
|
90
|
-
"lodash.kebabcase": "^4.1.1",
|
|
91
|
-
"lodash.pick": "^4.4.0",
|
|
92
90
|
"lodash.sortby": "^4.7.0",
|
|
93
|
-
"lodash.uniq": "^4.5.0",
|
|
94
91
|
"lru-cache": "^7.14.0",
|
|
95
92
|
"methods": "^1.1.2",
|
|
96
93
|
"module-details-from-path": "^1.0.3",
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
addHook,
|
|
6
6
|
AsyncResource
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
|
-
const kebabCase = require('
|
|
8
|
+
const kebabCase = require('../../utils/src/kebabcase')
|
|
9
9
|
const shimmer = require('../../datadog-shimmer')
|
|
10
10
|
|
|
11
11
|
const startCh = channel('apm:amqplib:command:start')
|
|
@@ -73,6 +73,7 @@ module.exports = {
|
|
|
73
73
|
'mongodb': () => require('../mongodb'),
|
|
74
74
|
'mongodb-core': () => require('../mongodb-core'),
|
|
75
75
|
'mongoose': () => require('../mongoose'),
|
|
76
|
+
'mquery': () => require('../mquery'),
|
|
76
77
|
'mysql': () => require('../mysql'),
|
|
77
78
|
'mysql2': () => require('../mysql2'),
|
|
78
79
|
'net': () => require('../net'),
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const dc = require('dc-polyfill')
|
|
4
|
+
const {
|
|
5
|
+
channel,
|
|
6
|
+
addHook
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const prepareCh = channel('datadog:mquery:filter:prepare')
|
|
11
|
+
const tracingCh = dc.tracingChannel('datadog:mquery:filter')
|
|
12
|
+
|
|
13
|
+
const methods = [
|
|
14
|
+
'find',
|
|
15
|
+
'findOne',
|
|
16
|
+
'findOneAndRemove',
|
|
17
|
+
'findOneAndDelete',
|
|
18
|
+
'count',
|
|
19
|
+
'distinct',
|
|
20
|
+
'where'
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
const methodsOptionalArgs = ['findOneAndUpdate']
|
|
24
|
+
|
|
25
|
+
function getFilters (args, methodName) {
|
|
26
|
+
const [arg0, arg1] = args
|
|
27
|
+
|
|
28
|
+
const filters = arg0 && typeof arg0 === 'object' ? [arg0] : []
|
|
29
|
+
|
|
30
|
+
if (arg1 && typeof arg1 === 'object' && methodsOptionalArgs.includes(methodName)) {
|
|
31
|
+
filters.push(arg1)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return filters
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
addHook({
|
|
38
|
+
name: 'mquery',
|
|
39
|
+
versions: ['>=5.0.0']
|
|
40
|
+
}, Query => {
|
|
41
|
+
[...methods, ...methodsOptionalArgs].forEach(methodName => {
|
|
42
|
+
if (!(methodName in Query.prototype)) return
|
|
43
|
+
|
|
44
|
+
shimmer.wrap(Query.prototype, methodName, method => {
|
|
45
|
+
return function () {
|
|
46
|
+
if (prepareCh.hasSubscribers) {
|
|
47
|
+
const filters = getFilters(arguments, methodName)
|
|
48
|
+
if (filters?.length) {
|
|
49
|
+
prepareCh.publish({ filters })
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return method.apply(this, arguments)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
shimmer.wrap(Query.prototype, 'exec', originalExec => {
|
|
59
|
+
return function wrappedExec () {
|
|
60
|
+
return tracingCh.tracePromise(originalExec, {}, this, arguments)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return Query
|
|
65
|
+
})
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const {
|
|
3
|
+
CONTEXT_PROPAGATION_KEY
|
|
4
|
+
} = require('../../../dd-trace/src/datastreams/processor')
|
|
5
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
2
6
|
const log = require('../../../dd-trace/src/log')
|
|
3
7
|
const BaseAwsSdkPlugin = require('../base')
|
|
8
|
+
|
|
4
9
|
class Kinesis extends BaseAwsSdkPlugin {
|
|
5
10
|
static get id () { return 'kinesis' }
|
|
6
11
|
static get peerServicePrecursors () { return ['streamname'] }
|
|
@@ -37,8 +42,9 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
37
42
|
if (!request.params) {
|
|
38
43
|
return
|
|
39
44
|
}
|
|
40
|
-
|
|
41
45
|
const traceData = {}
|
|
46
|
+
|
|
47
|
+
// inject data with DD context
|
|
42
48
|
this.tracer.inject(span, 'text_map', traceData)
|
|
43
49
|
let injectPath
|
|
44
50
|
if (request.params.Records && request.params.Records.length > 0) {
|
|
@@ -49,9 +55,30 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
49
55
|
log.error('No valid payload passed, unable to pass trace context')
|
|
50
56
|
return
|
|
51
57
|
}
|
|
58
|
+
|
|
52
59
|
const parsedData = this._tryParse(injectPath.Data)
|
|
53
60
|
if (parsedData) {
|
|
54
61
|
parsedData._datadog = traceData
|
|
62
|
+
|
|
63
|
+
// set DSM hash if enabled
|
|
64
|
+
if (this.config.dsmEnabled) {
|
|
65
|
+
// get payload size of request data
|
|
66
|
+
const payloadSize = Buffer.from(JSON.stringify(parsedData)).byteLength
|
|
67
|
+
let stream
|
|
68
|
+
// users can optionally use either stream name or stream arn
|
|
69
|
+
if (request.params && request.params.StreamArn) {
|
|
70
|
+
stream = request.params.StreamArn
|
|
71
|
+
} else if (request.params && request.params.StreamName) {
|
|
72
|
+
stream = request.params.StreamName
|
|
73
|
+
}
|
|
74
|
+
const dataStreamsContext = this.tracer
|
|
75
|
+
.setCheckpoint(['direction:out', `topic:${stream}`, 'type:kinesis'], span, payloadSize)
|
|
76
|
+
if (dataStreamsContext) {
|
|
77
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
78
|
+
parsedData._datadog[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
const finalData = Buffer.from(JSON.stringify(parsedData))
|
|
56
83
|
const byteSize = finalData.length
|
|
57
84
|
// Kinesis max payload size is 1MB
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const { CONTEXT_PROPAGATION_KEY, getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
3
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
2
4
|
const log = require('../../../dd-trace/src/log')
|
|
3
5
|
const BaseAwsSdkPlugin = require('../base')
|
|
4
6
|
|
|
@@ -11,6 +13,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
11
13
|
|
|
12
14
|
if (!params.TopicArn && !(response.data && response.data.TopicArn)) return {}
|
|
13
15
|
const TopicArn = params.TopicArn || response.data.TopicArn
|
|
16
|
+
|
|
14
17
|
// Split the ARN into its parts
|
|
15
18
|
// ex.'arn:aws:sns:us-east-1:123456789012:my-topic'
|
|
16
19
|
const arnParts = TopicArn.split(':')
|
|
@@ -72,10 +75,25 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
72
75
|
}
|
|
73
76
|
const ddInfo = {}
|
|
74
77
|
this.tracer.inject(span, 'text_map', ddInfo)
|
|
78
|
+
// add ddInfo before checking DSM so we can include DD attributes in payload size
|
|
75
79
|
params.MessageAttributes._datadog = {
|
|
76
80
|
DataType: 'Binary',
|
|
77
|
-
BinaryValue:
|
|
81
|
+
BinaryValue: ddInfo
|
|
82
|
+
}
|
|
83
|
+
if (this.config.dsmEnabled) {
|
|
84
|
+
const payloadSize = getHeadersSize({
|
|
85
|
+
Message: params.Message,
|
|
86
|
+
MessageAttributes: params.MessageAttributes
|
|
87
|
+
})
|
|
88
|
+
const dataStreamsContext = this.tracer
|
|
89
|
+
.setCheckpoint(['direction:out', `topic:${params.TopicArn}`, 'type:sns'], span, payloadSize)
|
|
90
|
+
if (dataStreamsContext) {
|
|
91
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
92
|
+
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
93
|
+
}
|
|
78
94
|
}
|
|
95
|
+
// BINARY types are automatically base64 encoded
|
|
96
|
+
params.MessageAttributes._datadog.BinaryValue = Buffer.from(JSON.stringify(ddInfo))
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const log = require('../../../dd-trace/src/log')
|
|
4
4
|
const BaseAwsSdkPlugin = require('../base')
|
|
5
5
|
const { storage } = require('../../../datadog-core')
|
|
6
|
+
const { CONTEXT_PROPAGATION_KEY, getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
7
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
6
8
|
|
|
7
9
|
class Sqs extends BaseAwsSdkPlugin {
|
|
8
10
|
static get id () { return 'sqs' }
|
|
@@ -19,20 +21,27 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
19
21
|
const { request, response } = obj
|
|
20
22
|
const store = storage.getStore()
|
|
21
23
|
const plugin = this
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
+
const contextExtraction = this.responseExtract(request.params, request.operation, response)
|
|
25
|
+
let span
|
|
26
|
+
let parsedMessageAttributes
|
|
27
|
+
if (contextExtraction && contextExtraction.datadogContext) {
|
|
24
28
|
obj.needsFinish = true
|
|
25
29
|
const options = {
|
|
26
|
-
childOf:
|
|
30
|
+
childOf: contextExtraction.datadogContext,
|
|
27
31
|
tags: Object.assign(
|
|
28
32
|
{},
|
|
29
33
|
this.requestTags.get(request) || {},
|
|
30
34
|
{ 'span.kind': 'server' }
|
|
31
35
|
)
|
|
32
36
|
}
|
|
33
|
-
|
|
37
|
+
parsedMessageAttributes = contextExtraction.parsedAttributes
|
|
38
|
+
span = plugin.tracer.startSpan('aws.response', options)
|
|
34
39
|
this.enter(span, store)
|
|
35
40
|
}
|
|
41
|
+
// extract DSM context after as we might not have a parent-child but may have a DSM context
|
|
42
|
+
this.responseExtractDSMContext(
|
|
43
|
+
request.operation, request.params, response, span ?? null, parsedMessageAttributes ?? null
|
|
44
|
+
)
|
|
36
45
|
})
|
|
37
46
|
|
|
38
47
|
this.addSub('apm:aws:response:finish:sqs', err => {
|
|
@@ -133,19 +142,69 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
133
142
|
|
|
134
143
|
const datadogAttribute = message.MessageAttributes._datadog
|
|
135
144
|
|
|
145
|
+
const parsedAttributes = this.parseDatadogAttributes(datadogAttribute)
|
|
146
|
+
if (parsedAttributes) {
|
|
147
|
+
return {
|
|
148
|
+
datadogContext: this.tracer.extract('text_map', parsedAttributes),
|
|
149
|
+
parsedAttributes: parsedAttributes
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
parseDatadogAttributes (attributes) {
|
|
136
155
|
try {
|
|
137
|
-
if (
|
|
138
|
-
const textMap =
|
|
139
|
-
return
|
|
140
|
-
} else if (
|
|
141
|
-
const buffer = Buffer.from(
|
|
142
|
-
return
|
|
156
|
+
if (attributes.StringValue) {
|
|
157
|
+
const textMap = attributes.StringValue
|
|
158
|
+
return JSON.parse(textMap)
|
|
159
|
+
} else if (attributes.Type === 'Binary') {
|
|
160
|
+
const buffer = Buffer.from(attributes.Value, 'base64')
|
|
161
|
+
return JSON.parse(buffer)
|
|
143
162
|
}
|
|
144
163
|
} catch (e) {
|
|
145
164
|
log.error(e)
|
|
146
165
|
}
|
|
147
166
|
}
|
|
148
167
|
|
|
168
|
+
responseExtractDSMContext (operation, params, response, span, parsedAttributes) {
|
|
169
|
+
if (!this.config.dsmEnabled) return
|
|
170
|
+
if (operation !== 'receiveMessage') return
|
|
171
|
+
if (!response || !response.Messages || !response.Messages[0]) return
|
|
172
|
+
|
|
173
|
+
// we only want to set the payloadSize on the span if we have one message
|
|
174
|
+
span = response.Messages.length > 1 ? null : span
|
|
175
|
+
|
|
176
|
+
response.Messages.forEach(message => {
|
|
177
|
+
// we may have already parsed the message attributes when extracting trace context
|
|
178
|
+
if (!parsedAttributes) {
|
|
179
|
+
if (message.Body) {
|
|
180
|
+
try {
|
|
181
|
+
const body = JSON.parse(message.Body)
|
|
182
|
+
|
|
183
|
+
// SNS to SQS
|
|
184
|
+
if (body.Type === 'Notification') {
|
|
185
|
+
message = body
|
|
186
|
+
}
|
|
187
|
+
} catch (e) {
|
|
188
|
+
// SQS to SQS
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (message.MessageAttributes && message.MessageAttributes._datadog) {
|
|
192
|
+
parsedAttributes = this.parseDatadogAttributes(message.MessageAttributes._datadog)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (parsedAttributes && parsedAttributes[CONTEXT_PROPAGATION_KEY]) {
|
|
196
|
+
const payloadSize = getHeadersSize({
|
|
197
|
+
Body: message.Body,
|
|
198
|
+
MessageAttributes: message.MessageAttributes
|
|
199
|
+
})
|
|
200
|
+
const queue = params.QueueUrl.split('/').pop()
|
|
201
|
+
this.tracer.decodeDataStreamsContext(Buffer.from(parsedAttributes[CONTEXT_PROPAGATION_KEY]))
|
|
202
|
+
this.tracer
|
|
203
|
+
.setCheckpoint(['direction:in', `topic:${queue}`, 'type:sqs'], span, payloadSize)
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
149
208
|
requestInject (span, request) {
|
|
150
209
|
const operation = request.operation
|
|
151
210
|
if (operation === 'sendMessage') {
|
|
@@ -164,6 +223,20 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
164
223
|
DataType: 'String',
|
|
165
224
|
StringValue: JSON.stringify(ddInfo)
|
|
166
225
|
}
|
|
226
|
+
if (this.config.dsmEnabled) {
|
|
227
|
+
const payloadSize = getHeadersSize({
|
|
228
|
+
Body: request.params.MessageBody,
|
|
229
|
+
MessageAttributes: request.params.MessageAttributes
|
|
230
|
+
})
|
|
231
|
+
const queue = request.params.QueueUrl.split('/').pop()
|
|
232
|
+
const dataStreamsContext = this.tracer
|
|
233
|
+
.setCheckpoint(['direction:out', `topic:${queue}`, 'type:sqs'], span, payloadSize)
|
|
234
|
+
if (dataStreamsContext) {
|
|
235
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
236
|
+
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
request.params.MessageAttributes._datadog.StringValue = JSON.stringify(ddInfo)
|
|
167
240
|
}
|
|
168
241
|
}
|
|
169
242
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const pick = require('../../utils/src/pick')
|
|
3
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
5
|
const log = require('../../dd-trace/src/log')
|
|
5
6
|
const GraphQLExecutePlugin = require('./execute')
|
|
@@ -63,10 +64,4 @@ function getHooks (config) {
|
|
|
63
64
|
return { execute, parse, validate }
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
// non-lodash pick
|
|
67
|
-
|
|
68
|
-
function pick (obj, selectors) {
|
|
69
|
-
return Object.fromEntries(Object.entries(obj).filter(([key]) => selectors.includes(key)))
|
|
70
|
-
}
|
|
71
|
-
|
|
72
67
|
module.exports = GraphQLPlugin
|
|
@@ -9,7 +9,7 @@ const { storage } = require('../../../../../datadog-core')
|
|
|
9
9
|
const { getIastContext } = require('../iast-context')
|
|
10
10
|
const { HTTP_REQUEST_PARAMETER, HTTP_REQUEST_BODY } = require('../taint-tracking/source-types')
|
|
11
11
|
|
|
12
|
-
const EXCLUDED_PATHS_FROM_STACK = getNodeModulesPaths('mongodb', 'mongoose')
|
|
12
|
+
const EXCLUDED_PATHS_FROM_STACK = getNodeModulesPaths('mongodb', 'mongoose', 'mquery')
|
|
13
13
|
const MONGODB_NOSQL_SECURE_MARK = getNextSecureMark()
|
|
14
14
|
|
|
15
15
|
function iterateObjectStrings (target, fn, levelKeys = [], depth = 50, visited = new Set()) {
|
|
@@ -37,34 +37,39 @@ class NosqlInjectionMongodbAnalyzer extends InjectionAnalyzer {
|
|
|
37
37
|
onConfigure () {
|
|
38
38
|
this.configureSanitizers()
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const onStart = ({ filters }) => {
|
|
41
41
|
const store = storage.getStore()
|
|
42
42
|
if (store && !store.nosqlAnalyzed && filters?.length) {
|
|
43
43
|
filters.forEach(filter => {
|
|
44
44
|
this.analyze({ filter }, store)
|
|
45
45
|
})
|
|
46
46
|
}
|
|
47
|
-
})
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (!store) return
|
|
48
|
+
return store
|
|
49
|
+
}
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
51
|
+
const onStartAndEnterWithStore = (message) => {
|
|
52
|
+
const store = onStart(message || {})
|
|
53
|
+
if (store) {
|
|
54
|
+
storage.enterWith({ ...store, nosqlAnalyzed: true, nosqlParentStore: store })
|
|
57
55
|
}
|
|
56
|
+
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
this.addSub('datadog:mongoose:model:filter:finish', () => {
|
|
58
|
+
const onFinish = () => {
|
|
63
59
|
const store = storage.getStore()
|
|
64
|
-
if (store?.
|
|
65
|
-
storage.enterWith(store.
|
|
60
|
+
if (store?.nosqlParentStore) {
|
|
61
|
+
storage.enterWith(store.nosqlParentStore)
|
|
66
62
|
}
|
|
67
|
-
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.addSub('datadog:mongodb:collection:filter:start', onStart)
|
|
66
|
+
|
|
67
|
+
this.addSub('datadog:mongoose:model:filter:start', onStartAndEnterWithStore)
|
|
68
|
+
this.addSub('datadog:mongoose:model:filter:finish', onFinish)
|
|
69
|
+
|
|
70
|
+
this.addSub('datadog:mquery:filter:prepare', onStart)
|
|
71
|
+
this.addSub('tracing:datadog:mquery:filter:start', onStartAndEnterWithStore)
|
|
72
|
+
this.addSub('tracing:datadog:mquery:filter:asyncEnd', onFinish)
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
configureSanitizers () {
|
|
@@ -125,6 +125,21 @@ function getSizeOrZero (obj) {
|
|
|
125
125
|
if (Buffer.isBuffer(obj)) {
|
|
126
126
|
return obj.length
|
|
127
127
|
}
|
|
128
|
+
if (Array.isArray(obj) && obj.length > 0) {
|
|
129
|
+
if (typeof obj[0] === 'number') return Buffer.from(obj).length
|
|
130
|
+
let payloadSize = 0
|
|
131
|
+
obj.forEach(item => {
|
|
132
|
+
payloadSize += getSizeOrZero(item)
|
|
133
|
+
})
|
|
134
|
+
return payloadSize
|
|
135
|
+
}
|
|
136
|
+
if (typeof obj === 'object') {
|
|
137
|
+
try {
|
|
138
|
+
return getHeadersSize(obj)
|
|
139
|
+
} catch {
|
|
140
|
+
// pass
|
|
141
|
+
}
|
|
142
|
+
}
|
|
128
143
|
return 0
|
|
129
144
|
}
|
|
130
145
|
|
|
@@ -157,7 +172,8 @@ class DataStreamsProcessor {
|
|
|
157
172
|
env,
|
|
158
173
|
tags,
|
|
159
174
|
version,
|
|
160
|
-
service
|
|
175
|
+
service,
|
|
176
|
+
flushInterval
|
|
161
177
|
} = {}) {
|
|
162
178
|
this.writer = new DataStreamsWriter({
|
|
163
179
|
hostname,
|
|
@@ -173,11 +189,13 @@ class DataStreamsProcessor {
|
|
|
173
189
|
this.service = service || 'unnamed-nodejs-service'
|
|
174
190
|
this.version = version || ''
|
|
175
191
|
this.sequence = 0
|
|
192
|
+
this.flushInterval = flushInterval
|
|
176
193
|
|
|
177
194
|
if (this.enabled) {
|
|
178
|
-
this.timer = setInterval(this.onInterval.bind(this),
|
|
195
|
+
this.timer = setInterval(this.onInterval.bind(this), flushInterval)
|
|
179
196
|
this.timer.unref()
|
|
180
197
|
}
|
|
198
|
+
process.once('beforeExit', () => this.onInterval())
|
|
181
199
|
}
|
|
182
200
|
|
|
183
201
|
onInterval () {
|
|
@@ -201,7 +219,8 @@ class DataStreamsProcessor {
|
|
|
201
219
|
*/
|
|
202
220
|
bucketFromTimestamp (timestamp) {
|
|
203
221
|
const bucketTime = Math.round(timestamp - (timestamp % this.bucketSizeNs))
|
|
204
|
-
|
|
222
|
+
const bucket = this.buckets.forTime(bucketTime)
|
|
223
|
+
return bucket
|
|
205
224
|
}
|
|
206
225
|
|
|
207
226
|
recordCheckpoint (checkpoint, span = null) {
|
|
@@ -259,8 +278,10 @@ class DataStreamsProcessor {
|
|
|
259
278
|
}
|
|
260
279
|
if (direction === 'direction:out') {
|
|
261
280
|
// Add the header for this now, as the callee doesn't have access to context when producing
|
|
262
|
-
|
|
263
|
-
|
|
281
|
+
// - 1 to account for extra byte for {
|
|
282
|
+
const ddInfoContinued = {}
|
|
283
|
+
ddInfoContinued[CONTEXT_PROPAGATION_KEY] = encodePathwayContext(dataStreamsContext).toJSON()
|
|
284
|
+
payloadSize += getSizeOrZero(JSON.stringify(ddInfoContinued)) - 1
|
|
264
285
|
}
|
|
265
286
|
const checkpoint = {
|
|
266
287
|
currentTimestamp: nowNs,
|
|
@@ -322,6 +343,10 @@ class DataStreamsProcessor {
|
|
|
322
343
|
Stats: serializedBuckets
|
|
323
344
|
}
|
|
324
345
|
}
|
|
346
|
+
|
|
347
|
+
setUrl (url) {
|
|
348
|
+
this.writer.setUrl(url)
|
|
349
|
+
}
|
|
325
350
|
}
|
|
326
351
|
|
|
327
352
|
module.exports = {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = str => {
|
|
4
|
+
if (typeof str !== 'string') {
|
|
5
|
+
throw new TypeError('Expected a string')
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return str
|
|
9
|
+
.trim()
|
|
10
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
11
|
+
.replace(/\s+/g, '-')
|
|
12
|
+
.replace(/^-+|-+$/g, '')
|
|
13
|
+
.replace(/_/g, '-')
|
|
14
|
+
.replace(/-{2,}/g, '-')
|
|
15
|
+
.toLowerCase()
|
|
16
|
+
}
|