dd-trace 4.20.0 → 4.21.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 -0
- package/index.d.ts +24 -0
- package/package.json +6 -5
- package/packages/datadog-instrumentations/src/aerospike.js +47 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/http/client.js +22 -0
- package/packages/datadog-instrumentations/src/jest.js +11 -5
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/next.js +3 -1
- package/packages/datadog-instrumentations/src/restify.js +1 -1
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-http/src/client.js +19 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +51 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +55 -0
- package/packages/datadog-plugin-next/src/index.js +7 -7
- package/packages/dd-trace/src/appsec/addresses.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +105 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +12 -19
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +20 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +6 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +18 -25
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +79 -85
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +27 -36
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +14 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +13 -1
- package/packages/dd-trace/src/appsec/recommended.json +1395 -2
- package/packages/dd-trace/src/appsec/reporter.js +19 -0
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -3
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +17 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +75 -56
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +15 -9
- package/packages/dd-trace/src/config.js +31 -2
- package/packages/dd-trace/src/datastreams/processor.js +107 -12
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/git.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +3 -2
- package/packages/dd-trace/src/profiler.js +5 -3
- package/packages/dd-trace/src/profiling/config.js +8 -0
- package/packages/dd-trace/src/profiling/profiler.js +10 -4
- package/packages/dd-trace/src/profiling/profilers/events.js +166 -73
- package/packages/dd-trace/src/proxy.js +21 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
- package/packages/dd-trace/src/spanleak.js +98 -0
- package/packages/dd-trace/src/startup-log.js +7 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +55 -9
- package/packages/dd-trace/src/telemetry/index.js +135 -43
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/send-data.js +47 -5
- package/packages/dd-trace/src/tracer.js +4 -0
- package/scripts/install_plugin_modules.js +11 -3
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -30,6 +30,7 @@ require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
|
|
|
30
30
|
require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
|
|
31
31
|
require,pprof-format,MIT,Copyright 2022 Stephen Belanger
|
|
32
32
|
require,protobufjs,BSD-3-Clause,Copyright 2016 Daniel Wirtz
|
|
33
|
+
require,tlhunter-sorted-set,MIT,Copyright (c) 2023 Datadog Inc.
|
|
33
34
|
require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
|
|
34
35
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
35
36
|
dev,@types/node,MIT,Copyright Authors
|
package/index.d.ts
CHANGED
|
@@ -578,6 +578,22 @@ export declare interface TracerOptions {
|
|
|
578
578
|
* @default 'safe'
|
|
579
579
|
*/
|
|
580
580
|
mode?: 'safe' | 'extended' | 'disabled'
|
|
581
|
+
},
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Configuration for Api Security sampling
|
|
585
|
+
*/
|
|
586
|
+
apiSecurity?: {
|
|
587
|
+
/** Whether to enable Api Security.
|
|
588
|
+
* @default false
|
|
589
|
+
*/
|
|
590
|
+
enabled?: boolean,
|
|
591
|
+
|
|
592
|
+
/** Controls the request sampling rate (between 0 and 1) in which Api Security is triggered.
|
|
593
|
+
* The value will be coerced back if it's outside of the 0-1 range.
|
|
594
|
+
* @default 0.1
|
|
595
|
+
*/
|
|
596
|
+
requestSampling?: number
|
|
581
597
|
}
|
|
582
598
|
};
|
|
583
599
|
|
|
@@ -927,6 +943,14 @@ declare namespace plugins {
|
|
|
927
943
|
* @default code => code < 500
|
|
928
944
|
*/
|
|
929
945
|
validateStatus?: (code: number) => boolean;
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Enable injection of tracing headers into requests signed with AWS IAM headers.
|
|
949
|
+
* Disable this if you get AWS signature errors (HTTP 403).
|
|
950
|
+
*
|
|
951
|
+
* @default false
|
|
952
|
+
*/
|
|
953
|
+
enablePropagationWithAmazonHeaders?: boolean;
|
|
930
954
|
}
|
|
931
955
|
|
|
932
956
|
/** @hidden */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.21.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -68,11 +68,11 @@
|
|
|
68
68
|
"node": ">=16"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@datadog/native-appsec": "
|
|
71
|
+
"@datadog/native-appsec": "5.0.0",
|
|
72
72
|
"@datadog/native-iast-rewriter": "2.2.1",
|
|
73
73
|
"@datadog/native-iast-taint-tracking": "1.6.4",
|
|
74
74
|
"@datadog/native-metrics": "^2.0.0",
|
|
75
|
-
"@datadog/pprof": "4.0
|
|
75
|
+
"@datadog/pprof": "4.1.0",
|
|
76
76
|
"@datadog/sketches-js": "^2.1.0",
|
|
77
77
|
"@opentelemetry/api": "^1.0.0",
|
|
78
78
|
"@opentelemetry/core": "^1.14.0",
|
|
@@ -97,8 +97,9 @@
|
|
|
97
97
|
"node-abort-controller": "^3.1.1",
|
|
98
98
|
"opentracing": ">=0.12.1",
|
|
99
99
|
"path-to-regexp": "^0.1.2",
|
|
100
|
-
"pprof-format": "^2.0.7",
|
|
101
|
-
"protobufjs": "^7.2.
|
|
100
|
+
"pprof-format": "^2.0.7",
|
|
101
|
+
"protobufjs": "^7.2.5",
|
|
102
|
+
"tlhunter-sorted-set": "^0.1.0",
|
|
102
103
|
"retry": "^0.13.1",
|
|
103
104
|
"semver": "^7.5.4"
|
|
104
105
|
},
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
addHook
|
|
5
|
+
} = require('./helpers/instrument')
|
|
6
|
+
const shimmer = require('../../datadog-shimmer')
|
|
7
|
+
|
|
8
|
+
const tracingChannel = require('dc-polyfill').tracingChannel
|
|
9
|
+
const ch = tracingChannel('apm:aerospike:command')
|
|
10
|
+
|
|
11
|
+
function wrapCreateCommand (createCommand) {
|
|
12
|
+
if (typeof createCommand !== 'function') return createCommand
|
|
13
|
+
|
|
14
|
+
return function commandWithTrace () {
|
|
15
|
+
const CommandClass = createCommand.apply(this, arguments)
|
|
16
|
+
|
|
17
|
+
if (!CommandClass) return CommandClass
|
|
18
|
+
|
|
19
|
+
shimmer.wrap(CommandClass.prototype, 'process', wrapProcess)
|
|
20
|
+
|
|
21
|
+
return CommandClass
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function wrapProcess (process) {
|
|
26
|
+
return function (...args) {
|
|
27
|
+
const cb = args[0]
|
|
28
|
+
if (typeof cb !== 'function') return process.apply(this, args)
|
|
29
|
+
|
|
30
|
+
const ctx = {
|
|
31
|
+
commandName: this.constructor.name,
|
|
32
|
+
commandArgs: this.args,
|
|
33
|
+
clientConfig: this.client.config
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return ch.traceCallback(process, -1, ctx, this, ...args)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
addHook({
|
|
41
|
+
name: 'aerospike',
|
|
42
|
+
file: 'lib/commands/command.js',
|
|
43
|
+
versions: ['^3.16.2', '4', '5']
|
|
44
|
+
},
|
|
45
|
+
commandFactory => {
|
|
46
|
+
return shimmer.wrap(commandFactory, wrapCreateCommand(commandFactory))
|
|
47
|
+
})
|
|
@@ -20,6 +20,7 @@ module.exports = {
|
|
|
20
20
|
'@opentelemetry/sdk-trace-node': () => require('../otel-sdk-trace'),
|
|
21
21
|
'@redis/client': () => require('../redis'),
|
|
22
22
|
'@smithy/smithy-client': () => require('../aws-sdk'),
|
|
23
|
+
'aerospike': () => require('../aerospike'),
|
|
23
24
|
'amqp10': () => require('../amqp10'),
|
|
24
25
|
'amqplib': () => require('../amqplib'),
|
|
25
26
|
'aws-sdk': () => require('../aws-sdk'),
|
|
@@ -58,6 +58,7 @@ function patch (http, methodName) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const options = args.options
|
|
61
|
+
|
|
61
62
|
const finish = () => {
|
|
62
63
|
if (!finished) {
|
|
63
64
|
finished = true
|
|
@@ -69,8 +70,28 @@ function patch (http, methodName) {
|
|
|
69
70
|
const req = request.call(this, options, callback)
|
|
70
71
|
const emit = req.emit
|
|
71
72
|
|
|
73
|
+
const requestSetTimeout = req.setTimeout
|
|
74
|
+
|
|
72
75
|
ctx.req = req
|
|
73
76
|
|
|
77
|
+
// tracked to accurately discern custom request socket timeout
|
|
78
|
+
let customRequestTimeout = false
|
|
79
|
+
|
|
80
|
+
req.setTimeout = function () {
|
|
81
|
+
customRequestTimeout = true
|
|
82
|
+
return requestSetTimeout.apply(this, arguments)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
req.on('socket', socket => {
|
|
86
|
+
if (socket) {
|
|
87
|
+
const socketSetTimeout = socket.setTimeout
|
|
88
|
+
socket.setTimeout = function () {
|
|
89
|
+
customRequestTimeout = true
|
|
90
|
+
return socketSetTimeout.apply(this, arguments)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
74
95
|
req.emit = function (eventName, arg) {
|
|
75
96
|
switch (eventName) {
|
|
76
97
|
case 'response': {
|
|
@@ -88,6 +109,7 @@ function patch (http, methodName) {
|
|
|
88
109
|
case 'error':
|
|
89
110
|
case 'timeout':
|
|
90
111
|
ctx.error = arg
|
|
112
|
+
ctx.customRequestTimeout = customRequestTimeout
|
|
91
113
|
errorChannel.publish(ctx)
|
|
92
114
|
case 'abort': // deprecated and replaced by `close` in node 17
|
|
93
115
|
case 'close':
|
|
@@ -44,6 +44,7 @@ const itrSkippedSuitesCh = channel('ci:jest:itr:skipped-suites')
|
|
|
44
44
|
let skippableSuites = []
|
|
45
45
|
let isCodeCoverageEnabled = false
|
|
46
46
|
let isSuitesSkippingEnabled = false
|
|
47
|
+
let isUserCodeCoverageEnabled = false
|
|
47
48
|
let isSuitesSkipped = false
|
|
48
49
|
let numSkippedSuites = 0
|
|
49
50
|
let hasUnskippableSuites = false
|
|
@@ -289,11 +290,14 @@ function cliWrapper (cli, jestVersion) {
|
|
|
289
290
|
} = result
|
|
290
291
|
|
|
291
292
|
let testCodeCoverageLinesTotal
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
293
|
+
|
|
294
|
+
if (isUserCodeCoverageEnabled) {
|
|
295
|
+
try {
|
|
296
|
+
const { pct, total } = coverageMap.getCoverageSummary().lines
|
|
297
|
+
testCodeCoverageLinesTotal = total !== 0 ? pct : 0
|
|
298
|
+
} catch (e) {
|
|
299
|
+
// ignore errors
|
|
300
|
+
}
|
|
297
301
|
}
|
|
298
302
|
let status, error
|
|
299
303
|
|
|
@@ -436,6 +440,8 @@ function configureTestEnvironment (readConfigsResult) {
|
|
|
436
440
|
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled
|
|
437
441
|
})
|
|
438
442
|
|
|
443
|
+
isUserCodeCoverageEnabled = !!readConfigsResult.globalConfig.collectCoverage
|
|
444
|
+
|
|
439
445
|
if (isCodeCoverageEnabled) {
|
|
440
446
|
const globalConfig = {
|
|
441
447
|
...readConfigsResult.globalConfig,
|
|
@@ -8,13 +8,31 @@ const {
|
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
9
|
|
|
10
10
|
const producerStartCh = channel('apm:kafkajs:produce:start')
|
|
11
|
+
const producerCommitCh = channel('apm:kafkajs:produce:commit')
|
|
11
12
|
const producerFinishCh = channel('apm:kafkajs:produce:finish')
|
|
12
13
|
const producerErrorCh = channel('apm:kafkajs:produce:error')
|
|
13
14
|
|
|
14
15
|
const consumerStartCh = channel('apm:kafkajs:consume:start')
|
|
16
|
+
const consumerCommitCh = channel('apm:kafkajs:consume:commit')
|
|
15
17
|
const consumerFinishCh = channel('apm:kafkajs:consume:finish')
|
|
16
18
|
const consumerErrorCh = channel('apm:kafkajs:consume:error')
|
|
17
19
|
|
|
20
|
+
function commitsFromEvent (event) {
|
|
21
|
+
const { payload: { groupId, topics } } = event
|
|
22
|
+
const commitList = []
|
|
23
|
+
for (const { topic, partitions } of topics) {
|
|
24
|
+
for (const { partition, offset } of partitions) {
|
|
25
|
+
commitList.push({
|
|
26
|
+
groupId,
|
|
27
|
+
partition,
|
|
28
|
+
offset,
|
|
29
|
+
topic
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
consumerCommitCh.publish(commitList)
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKafka) => {
|
|
19
37
|
class Kafka extends BaseKafka {
|
|
20
38
|
constructor (options) {
|
|
@@ -58,6 +76,12 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
|
|
|
58
76
|
})
|
|
59
77
|
)
|
|
60
78
|
|
|
79
|
+
result.then(res => {
|
|
80
|
+
if (producerCommitCh.hasSubscribers) {
|
|
81
|
+
producerCommitCh.publish(res)
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
|
|
61
85
|
return result
|
|
62
86
|
} catch (e) {
|
|
63
87
|
producerErrorCh.publish(e)
|
|
@@ -75,6 +99,9 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
|
|
|
75
99
|
}
|
|
76
100
|
|
|
77
101
|
const consumer = createConsumer.apply(this, arguments)
|
|
102
|
+
|
|
103
|
+
consumer.on(consumer.events.COMMIT_OFFSETS, commitsFromEvent)
|
|
104
|
+
|
|
78
105
|
const run = consumer.run
|
|
79
106
|
|
|
80
107
|
const groupId = arguments[0].groupId
|
|
@@ -144,7 +144,9 @@ function instrument (req, res, handler) {
|
|
|
144
144
|
function wrapServeStatic (serveStatic) {
|
|
145
145
|
return function (req, res, path) {
|
|
146
146
|
return instrument(req, res, () => {
|
|
147
|
-
if (pageLoadChannel.hasSubscribers && path)
|
|
147
|
+
if (pageLoadChannel.hasSubscribers && path) {
|
|
148
|
+
pageLoadChannel.publish({ page: path, isStatic: true })
|
|
149
|
+
}
|
|
148
150
|
|
|
149
151
|
return serveStatic.apply(this, arguments)
|
|
150
152
|
})
|
|
@@ -55,7 +55,7 @@ function wrapFn (fn) {
|
|
|
55
55
|
return result.then(function () {
|
|
56
56
|
nextChannel.publish({ req })
|
|
57
57
|
finishChannel.publish({ req })
|
|
58
|
-
return arguments
|
|
58
|
+
return arguments[0]
|
|
59
59
|
}).catch(function (error) {
|
|
60
60
|
errorChannel.publish({ req, error })
|
|
61
61
|
nextChannel.publish({ req })
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../datadog-core')
|
|
4
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
5
|
+
|
|
6
|
+
const AEROSPIKE_PEER_SERVICE = 'aerospike.namespace'
|
|
7
|
+
|
|
8
|
+
class AerospikePlugin extends DatabasePlugin {
|
|
9
|
+
static get id () { return 'aerospike' }
|
|
10
|
+
static get operation () { return 'command' }
|
|
11
|
+
static get system () { return 'aerospike' }
|
|
12
|
+
static get prefix () {
|
|
13
|
+
return 'tracing:apm:aerospike:command'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static get peerServicePrecursors () {
|
|
17
|
+
return [AEROSPIKE_PEER_SERVICE]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
bindStart (ctx) {
|
|
21
|
+
const { commandName, commandArgs } = ctx
|
|
22
|
+
const resourceName = commandName.slice(0, commandName.indexOf('Command'))
|
|
23
|
+
const store = storage.getStore()
|
|
24
|
+
const childOf = store ? store.span : null
|
|
25
|
+
const meta = getMeta(resourceName, commandArgs)
|
|
26
|
+
|
|
27
|
+
const span = this.startSpan(this.operationName(), {
|
|
28
|
+
childOf,
|
|
29
|
+
service: this.serviceName({ pluginConfig: this.config }),
|
|
30
|
+
type: 'aerospike',
|
|
31
|
+
kind: 'client',
|
|
32
|
+
resource: resourceName,
|
|
33
|
+
meta
|
|
34
|
+
}, false)
|
|
35
|
+
|
|
36
|
+
ctx.parentStore = store
|
|
37
|
+
ctx.currentStore = { ...store, span }
|
|
38
|
+
|
|
39
|
+
return ctx.currentStore
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bindAsyncStart (ctx) {
|
|
43
|
+
if (ctx.currentStore) {
|
|
44
|
+
// have to manually trigger peer service calculation when using tracing channel
|
|
45
|
+
this.tagPeerService(ctx.currentStore.span)
|
|
46
|
+
ctx.currentStore.span.finish()
|
|
47
|
+
}
|
|
48
|
+
return ctx.parentStore
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
end (ctx) {
|
|
52
|
+
if (ctx.result) {
|
|
53
|
+
// have to manually trigger peer service calculation when using tracing channel
|
|
54
|
+
this.tagPeerService(ctx.currentStore.span)
|
|
55
|
+
ctx.currentStore.span.finish()
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
error (ctx) {
|
|
60
|
+
if (ctx.error) {
|
|
61
|
+
const error = ctx.error
|
|
62
|
+
const span = ctx.currentStore.span
|
|
63
|
+
span.setTag('error', error)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getMeta (resourceName, commandArgs) {
|
|
69
|
+
let meta = {}
|
|
70
|
+
if (resourceName.includes('Index')) {
|
|
71
|
+
const [ns, set, bin, index] = commandArgs
|
|
72
|
+
meta = getMetaForIndex(ns, set, bin, index)
|
|
73
|
+
} else if (resourceName === 'Query') {
|
|
74
|
+
const { ns, set } = commandArgs[2]
|
|
75
|
+
meta = getMetaForQuery({ ns, set })
|
|
76
|
+
} else if (isKeyObject(commandArgs[0])) {
|
|
77
|
+
const { ns, set, key } = commandArgs[0]
|
|
78
|
+
meta = getMetaForKey(ns, set, key)
|
|
79
|
+
}
|
|
80
|
+
return meta
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getMetaForIndex (ns, set, bin, index) {
|
|
84
|
+
return {
|
|
85
|
+
[AEROSPIKE_PEER_SERVICE]: ns,
|
|
86
|
+
'aerospike.setname': set,
|
|
87
|
+
'aerospike.bin': bin,
|
|
88
|
+
'aerospike.index': index
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getMetaForKey (ns, set, key) {
|
|
93
|
+
return {
|
|
94
|
+
'aerospike.key': `${ns}:${set}:${key}`,
|
|
95
|
+
[AEROSPIKE_PEER_SERVICE]: ns,
|
|
96
|
+
'aerospike.setname': set,
|
|
97
|
+
'aerospike.userkey': key
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getMetaForQuery (queryObj) {
|
|
102
|
+
const { ns, set } = queryObj
|
|
103
|
+
return {
|
|
104
|
+
[AEROSPIKE_PEER_SERVICE]: ns,
|
|
105
|
+
'aerospike.setname': set
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function isKeyObject (obj) {
|
|
110
|
+
return obj && obj.ns !== undefined && obj.set !== undefined && obj.key !== undefined
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = AerospikePlugin
|
|
@@ -58,7 +58,7 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
58
58
|
span._spanContext._trace.record = false
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
if (
|
|
61
|
+
if (this.shouldInjectTraceHeaders(options, uri)) {
|
|
62
62
|
this.tracer.inject(span, HTTP_HEADERS, options.headers)
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -71,6 +71,18 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
71
71
|
return message.currentStore
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
shouldInjectTraceHeaders (options, uri) {
|
|
75
|
+
if (hasAmazonSignature(options) && !this.config.enablePropagationWithAmazonHeaders) {
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!this.config.propagationFilter(uri)) {
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return true
|
|
84
|
+
}
|
|
85
|
+
|
|
74
86
|
bindAsyncStart ({ parentStore }) {
|
|
75
87
|
return parentStore
|
|
76
88
|
}
|
|
@@ -98,7 +110,7 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
98
110
|
span.finish()
|
|
99
111
|
}
|
|
100
112
|
|
|
101
|
-
error ({ span, error }) {
|
|
113
|
+
error ({ span, error, args, customRequestTimeout }) {
|
|
102
114
|
if (!span) return
|
|
103
115
|
if (error) {
|
|
104
116
|
span.addTags({
|
|
@@ -107,6 +119,11 @@ class HttpClientPlugin extends ClientPlugin {
|
|
|
107
119
|
[ERROR_STACK]: error.stack
|
|
108
120
|
})
|
|
109
121
|
} else {
|
|
122
|
+
// conditions for no error:
|
|
123
|
+
// 1. not using a custom agent instance with custom timeout specified
|
|
124
|
+
// 2. no invocation of `req.setTimeout` or `socket.setTimeout`
|
|
125
|
+
if (!args.options.agent?.options.timeout && !customRequestTimeout) return
|
|
126
|
+
|
|
110
127
|
span.setTag('error', 1)
|
|
111
128
|
}
|
|
112
129
|
}
|
|
@@ -7,6 +7,57 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
|
|
|
7
7
|
static get id () { return 'kafkajs' }
|
|
8
8
|
static get operation () { return 'consume' }
|
|
9
9
|
|
|
10
|
+
constructor () {
|
|
11
|
+
super(...arguments)
|
|
12
|
+
this.addSub('apm:kafkajs:consume:commit', message => this.commit(message))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Transform individual commit details sent by kafkajs' event reporter
|
|
17
|
+
* into actionable backlog items for DSM
|
|
18
|
+
*
|
|
19
|
+
* @typedef {object} ConsumerBacklog
|
|
20
|
+
* @property {number} type
|
|
21
|
+
* @property {string} consumer_group
|
|
22
|
+
* @property {string} topic
|
|
23
|
+
* @property {number} partition
|
|
24
|
+
* @property {number} offset
|
|
25
|
+
*
|
|
26
|
+
* @typedef {object} CommitEventItem
|
|
27
|
+
* @property {string} groupId
|
|
28
|
+
* @property {string} topic
|
|
29
|
+
* @property {number} partition
|
|
30
|
+
* @property {import('kafkajs/utils/long').Long} offset
|
|
31
|
+
*
|
|
32
|
+
* @param {CommitEventItem} commit
|
|
33
|
+
* @returns {ConsumerBacklog}
|
|
34
|
+
*/
|
|
35
|
+
transformCommit (commit) {
|
|
36
|
+
const { groupId, partition, offset, topic } = commit
|
|
37
|
+
return {
|
|
38
|
+
partition,
|
|
39
|
+
topic,
|
|
40
|
+
type: 'kafka_commit',
|
|
41
|
+
offset: Number(offset),
|
|
42
|
+
consumer_group: groupId
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
commit (commitList) {
|
|
47
|
+
if (!this.config.dsmEnabled) return
|
|
48
|
+
const keys = [
|
|
49
|
+
'consumer_group',
|
|
50
|
+
'type',
|
|
51
|
+
'partition',
|
|
52
|
+
'offset',
|
|
53
|
+
'topic'
|
|
54
|
+
]
|
|
55
|
+
for (const commit of commitList.map(this.transformCommit)) {
|
|
56
|
+
if (keys.some(key => !commit.hasOwnProperty(key))) continue
|
|
57
|
+
this.tracer.setOffset(commit)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
10
61
|
start ({ topic, partition, message, groupId }) {
|
|
11
62
|
const childOf = extract(this.tracer, message.headers)
|
|
12
63
|
const span = this.startSpan({
|
|
@@ -11,6 +11,61 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
11
11
|
static get operation () { return 'produce' }
|
|
12
12
|
static get peerServicePrecursors () { return [BOOTSTRAP_SERVERS_KEY] }
|
|
13
13
|
|
|
14
|
+
constructor () {
|
|
15
|
+
super(...arguments)
|
|
16
|
+
this.addSub('apm:kafkajs:produce:commit', message => this.commit(message))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Transform individual commit details sent by kafkajs' event reporter
|
|
21
|
+
* into actionable backlog items for DSM
|
|
22
|
+
*
|
|
23
|
+
* @typedef {object} ProducerBacklog
|
|
24
|
+
* @property {number} type
|
|
25
|
+
* @property {string} topic
|
|
26
|
+
* @property {number} partition
|
|
27
|
+
* @property {number} offset
|
|
28
|
+
*
|
|
29
|
+
* @typedef {object} ProducerResponseItem
|
|
30
|
+
* @property {string} topic
|
|
31
|
+
* @property {number} partition
|
|
32
|
+
* @property {import('kafkajs/utils/long').Long} [offset]
|
|
33
|
+
* @property {import('kafkajs/utils/long').Long} [baseOffset]
|
|
34
|
+
*
|
|
35
|
+
* @param {ProducerResponseItem} response
|
|
36
|
+
* @returns {ProducerBacklog}
|
|
37
|
+
*/
|
|
38
|
+
transformProduceResponse (response) {
|
|
39
|
+
// In produce protocol >=v3, the offset key changes from `offset` to `baseOffset`
|
|
40
|
+
const { topicName: topic, partition, offset, baseOffset } = response
|
|
41
|
+
const offsetAsLong = offset || baseOffset
|
|
42
|
+
return {
|
|
43
|
+
type: 'kafka_produce',
|
|
44
|
+
partition,
|
|
45
|
+
offset: offsetAsLong ? Number(offsetAsLong) : undefined,
|
|
46
|
+
topic
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param {ProducerResponseItem[]} commitList
|
|
53
|
+
* @returns {void}
|
|
54
|
+
*/
|
|
55
|
+
commit (commitList) {
|
|
56
|
+
if (!this.config.dsmEnabled) return
|
|
57
|
+
const keys = [
|
|
58
|
+
'type',
|
|
59
|
+
'partition',
|
|
60
|
+
'offset',
|
|
61
|
+
'topic'
|
|
62
|
+
]
|
|
63
|
+
for (const commit of commitList.map(this.transformProduceResponse)) {
|
|
64
|
+
if (keys.some(key => !commit.hasOwnProperty(key))) continue
|
|
65
|
+
this.tracer.setOffset(commit)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
14
69
|
start ({ topic, messages, bootstrapServers }) {
|
|
15
70
|
let pathwayCtx
|
|
16
71
|
const span = this.startSpan({
|
|
@@ -65,7 +65,7 @@ class NextPlugin extends ServerPlugin {
|
|
|
65
65
|
span.finish()
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
pageLoad ({ page, isAppPath = false }) {
|
|
68
|
+
pageLoad ({ page, isAppPath = false, isStatic = false }) {
|
|
69
69
|
const store = storage.getStore()
|
|
70
70
|
|
|
71
71
|
if (!store) return
|
|
@@ -82,12 +82,12 @@ class NextPlugin extends ServerPlugin {
|
|
|
82
82
|
// remove ending /route or /page for appDir projects
|
|
83
83
|
if (isAppPath) page = page.substring(0, page.lastIndexOf('/'))
|
|
84
84
|
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
// handle static resource
|
|
86
|
+
if (isStatic) {
|
|
87
|
+
page = req.url.includes('_next/static')
|
|
88
|
+
? '/_next/static/*'
|
|
89
|
+
: '/public/*'
|
|
90
|
+
}
|
|
91
91
|
|
|
92
92
|
span.addTags({
|
|
93
93
|
[COMPONENT]: this.constructor.id,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
'COMMAND_INJECTION_ANALYZER': require('./command-injection-analyzer'),
|
|
5
5
|
'HARCODED_SECRET_ANALYZER': require('./hardcoded-secret-analyzer'),
|
|
6
|
+
'HEADER_INJECTION_ANALYZER': require('./header-injection-analyzer'),
|
|
6
7
|
'HSTS_HEADER_MISSING_ANALYZER': require('./hsts-header-missing-analyzer'),
|
|
7
8
|
'INSECURE_COOKIE_ANALYZER': require('./insecure-cookie-analyzer'),
|
|
8
9
|
'LDAP_ANALYZER': require('./ldap-injection-analyzer'),
|