dd-trace 5.38.0 → 5.40.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 +30 -21
- package/package.json +4 -2
- package/packages/datadog-instrumentations/src/apollo-server-core.js +1 -1
- package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
- package/packages/datadog-instrumentations/src/express-session.js +41 -0
- package/packages/datadog-instrumentations/src/fetch.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/fetch.js +6 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +16 -10
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -1
- package/packages/datadog-instrumentations/src/nyc.js +2 -1
- package/packages/datadog-instrumentations/src/vitest.js +4 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +9 -8
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -4
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +5 -2
- package/packages/datadog-plugin-kafkajs/src/producer.js +4 -3
- package/packages/datadog-plugin-mongodb-core/src/index.js +10 -13
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -2
- package/packages/datadog-shimmer/src/shimmer.js +95 -95
- package/packages/dd-trace/src/appsec/addresses.js +1 -0
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/iast-context.js +2 -2
- package/packages/dd-trace/src/appsec/iast/index.js +0 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -5
- package/packages/dd-trace/src/appsec/index.js +23 -1
- package/packages/dd-trace/src/appsec/reporter.js +3 -8
- package/packages/dd-trace/src/appsec/rule_manager.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/set_user.js +9 -5
- package/packages/dd-trace/src/appsec/sdk/track_event.js +2 -4
- package/packages/dd-trace/src/appsec/telemetry/common.js +24 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +126 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +35 -0
- package/packages/dd-trace/src/appsec/telemetry/user.js +24 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +92 -0
- package/packages/dd-trace/src/appsec/user_tracking.js +2 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +16 -4
- package/packages/dd-trace/src/config.js +31 -14
- package/packages/dd-trace/src/constants.js +1 -1
- package/packages/dd-trace/src/{data_streams.js → datastreams/checkpointer.js} +1 -1
- package/packages/dd-trace/src/{data_streams_context.js → datastreams/context.js} +2 -2
- package/packages/dd-trace/src/datastreams/index.js +104 -0
- package/packages/dd-trace/src/datastreams/manager.js +27 -0
- package/packages/dd-trace/src/datastreams/processor.js +1 -44
- package/packages/dd-trace/src/datastreams/size.js +53 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +22 -15
- package/packages/dd-trace/src/dogstatsd.js +23 -4
- package/packages/dd-trace/src/exporters/agent/index.js +2 -2
- package/packages/dd-trace/src/flare/index.js +3 -0
- package/packages/dd-trace/src/noop/dogstatsd.js +6 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +45 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +11 -47
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +1 -1
- package/packages/dd-trace/src/opentracing/span.js +12 -2
- package/packages/dd-trace/src/payload-tagging/config/aws.json +8 -0
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -2
- package/packages/dd-trace/src/priority_sampler.js +5 -3
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +15 -4
- package/packages/dd-trace/src/proxy.js +41 -22
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/capabilities.js +1 -0
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/index.js +8 -5
- package/packages/dd-trace/src/{appsec/remote_config → remote_config}/manager.js +5 -5
- package/packages/dd-trace/src/runtime_metrics/index.js +34 -0
- package/packages/dd-trace/src/{runtime_metrics.js → runtime_metrics/runtime_metrics.js} +4 -4
- package/packages/dd-trace/src/serverless.js +10 -1
- package/packages/dd-trace/src/service-naming/index.js +12 -4
- package/packages/dd-trace/src/span_processor.js +7 -4
- package/packages/dd-trace/src/span_stats.js +1 -2
- package/packages/dd-trace/src/standalone/index.js +70 -0
- package/packages/dd-trace/src/standalone/product.js +24 -0
- package/packages/dd-trace/src/standalone/tracesource.js +22 -0
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +47 -0
- package/packages/dd-trace/src/telemetry/index.js +16 -387
- package/packages/dd-trace/src/telemetry/telemetry.js +394 -0
- package/packages/dd-trace/src/tracer.js +7 -15
- package/packages/dd-trace/src/appsec/standalone.js +0 -130
- package/packages/dd-trace/src/appsec/telemetry.js +0 -218
- package/packages/dd-trace/src/service-naming/schemas/index.js +0 -6
- /package/packages/dd-trace/src/{appsec/remote_config → remote_config}/apply_states.js +0 -0
- /package/packages/dd-trace/src/{appsec/remote_config → remote_config}/scheduler.js +0 -0
|
@@ -9,14 +9,7 @@ const DynamicInstrumentation = require('./debugger')
|
|
|
9
9
|
const telemetry = require('./telemetry')
|
|
10
10
|
const nomenclature = require('./service-naming')
|
|
11
11
|
const PluginManager = require('./plugin_manager')
|
|
12
|
-
const remoteConfig = require('./appsec/remote_config')
|
|
13
|
-
const AppsecSdk = require('./appsec/sdk')
|
|
14
|
-
const dogstatsd = require('./dogstatsd')
|
|
15
12
|
const NoopDogStatsDClient = require('./noop/dogstatsd')
|
|
16
|
-
const spanleak = require('./spanleak')
|
|
17
|
-
const { SSIHeuristics } = require('./profiling/ssi-heuristics')
|
|
18
|
-
const appsecStandalone = require('./appsec/standalone')
|
|
19
|
-
const LLMObsSDK = require('./llmobs/sdk')
|
|
20
13
|
|
|
21
14
|
class LazyModule {
|
|
22
15
|
constructor (provider) {
|
|
@@ -33,6 +26,35 @@ class LazyModule {
|
|
|
33
26
|
}
|
|
34
27
|
}
|
|
35
28
|
|
|
29
|
+
function lazyProxy (obj, property, config, getClass, ...args) {
|
|
30
|
+
if (config?._isInServerlessEnvironment?.() === false) {
|
|
31
|
+
defineEagerly(obj, property, getClass, ...args)
|
|
32
|
+
} else {
|
|
33
|
+
defineLazily(obj, property, getClass, ...args)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function defineEagerly (obj, property, getClass, ...args) {
|
|
38
|
+
const RealClass = getClass()
|
|
39
|
+
|
|
40
|
+
obj[property] = new RealClass(...args)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function defineLazily (obj, property, getClass, ...args) {
|
|
44
|
+
Reflect.defineProperty(obj, property, {
|
|
45
|
+
get () {
|
|
46
|
+
const RealClass = getClass()
|
|
47
|
+
const value = new RealClass(...args)
|
|
48
|
+
|
|
49
|
+
Reflect.defineProperty(obj, property, { value, configurable: true, enumerable: true })
|
|
50
|
+
|
|
51
|
+
return value
|
|
52
|
+
},
|
|
53
|
+
configurable: true,
|
|
54
|
+
enumerable: true
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
36
58
|
class Tracer extends NoopProxy {
|
|
37
59
|
constructor () {
|
|
38
60
|
super()
|
|
@@ -68,18 +90,11 @@ class Tracer extends NoopProxy {
|
|
|
68
90
|
|
|
69
91
|
if (config.dogstatsd) {
|
|
70
92
|
// Custom Metrics
|
|
71
|
-
this
|
|
72
|
-
|
|
73
|
-
setInterval(() => {
|
|
74
|
-
this.dogstatsd.flush()
|
|
75
|
-
}, 10 * 1000).unref()
|
|
76
|
-
|
|
77
|
-
process.once('beforeExit', () => {
|
|
78
|
-
this.dogstatsd.flush()
|
|
79
|
-
})
|
|
93
|
+
lazyProxy(this, 'dogstatsd', config, () => require('./dogstatsd').CustomMetrics, config)
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
if (config.spanLeakDebug > 0) {
|
|
97
|
+
const spanleak = require('./spanleak')
|
|
83
98
|
if (config.spanLeakDebug === spanleak.MODES.LOG) {
|
|
84
99
|
spanleak.enableLogging()
|
|
85
100
|
} else if (config.spanLeakDebug === spanleak.MODES.GC_AND_LOG) {
|
|
@@ -89,7 +104,7 @@ class Tracer extends NoopProxy {
|
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
if (config.remoteConfig.enabled && !config.isCiVisibility) {
|
|
92
|
-
const rc =
|
|
107
|
+
const rc = require('./remote_config').enable(config, this._modules.appsec)
|
|
93
108
|
|
|
94
109
|
rc.setProductHandler('APM_TRACING', (action, conf) => {
|
|
95
110
|
if (action === 'unapply') {
|
|
@@ -129,6 +144,7 @@ class Tracer extends NoopProxy {
|
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
if (config.profiling.enabled !== 'false') {
|
|
147
|
+
const { SSIHeuristics } = require('./profiling/ssi-heuristics')
|
|
132
148
|
const ssiHeuristics = new SSIHeuristics(config)
|
|
133
149
|
ssiHeuristics.start()
|
|
134
150
|
let mockProfiler = null
|
|
@@ -186,8 +202,9 @@ class Tracer extends NoopProxy {
|
|
|
186
202
|
}
|
|
187
203
|
|
|
188
204
|
if (config.isTestDynamicInstrumentationEnabled) {
|
|
189
|
-
const
|
|
190
|
-
|
|
205
|
+
const getDynamicInstrumentationClient = require('./ci-visibility/dynamic-instrumentation')
|
|
206
|
+
// We instantiate the client but do not start the Worker here. The worker is started lazily
|
|
207
|
+
getDynamicInstrumentationClient(config)
|
|
191
208
|
}
|
|
192
209
|
} catch (e) {
|
|
193
210
|
log.error('Error initialising tracer', e)
|
|
@@ -218,11 +235,13 @@ class Tracer extends NoopProxy {
|
|
|
218
235
|
this._modules.llmobs.enable(config)
|
|
219
236
|
}
|
|
220
237
|
if (!this._tracingInitialized) {
|
|
221
|
-
const prioritySampler =
|
|
238
|
+
const prioritySampler = config.apmTracingEnabled === false
|
|
239
|
+
? require('./standalone').configure(config)
|
|
240
|
+
: undefined
|
|
222
241
|
this._tracer = new DatadogTracer(config, prioritySampler)
|
|
223
242
|
this.dataStreamsCheckpointer = this._tracer.dataStreamsCheckpointer
|
|
224
|
-
this
|
|
225
|
-
this
|
|
243
|
+
lazyProxy(this, 'appsec', config, () => require('./appsec/sdk'), this._tracer, config)
|
|
244
|
+
lazyProxy(this, 'llmobs', config, () => require('./llmobs/sdk'), this._tracer, this._modules.llmobs, config)
|
|
226
245
|
this._tracingInitialized = true
|
|
227
246
|
}
|
|
228
247
|
if (config.iast.enabled) {
|
|
@@ -24,6 +24,7 @@ module.exports = {
|
|
|
24
24
|
APM_TRACING_SAMPLE_RULES: 1n << 29n,
|
|
25
25
|
ASM_AUTO_USER_INSTRUM_MODE: 1n << 31n,
|
|
26
26
|
ASM_ENDPOINT_FINGERPRINT: 1n << 32n,
|
|
27
|
+
ASM_SESSION_FINGERPRINT: 1n << 33n,
|
|
27
28
|
ASM_NETWORK_FINGERPRINT: 1n << 34n,
|
|
28
29
|
ASM_HEADER_FINGERPRINT: 1n << 35n,
|
|
29
30
|
ASM_RASP_CMDI: 1n << 37n
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const Activation = require('../activation')
|
|
3
|
+
const Activation = require('../appsec/activation')
|
|
4
4
|
|
|
5
5
|
const RemoteConfigManager = require('./manager')
|
|
6
6
|
const RemoteConfigCapabilities = require('./capabilities')
|
|
7
|
-
const { setCollectionMode } = require('../user_tracking')
|
|
8
|
-
const log = require('
|
|
7
|
+
const { setCollectionMode } = require('../appsec/user_tracking')
|
|
8
|
+
const log = require('../log')
|
|
9
9
|
|
|
10
10
|
let rc
|
|
11
11
|
|
|
@@ -77,10 +77,11 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// TODO: all appsec specific stuff should be moved back in the appsec folder
|
|
80
81
|
function enableWafUpdate (appsecConfig) {
|
|
81
82
|
if (rc && appsecConfig && !appsecConfig.rules) {
|
|
82
83
|
// dirty require to make startup faster for serverless
|
|
83
|
-
const RuleManager = require('../rule_manager')
|
|
84
|
+
const RuleManager = require('../appsec/rule_manager')
|
|
84
85
|
|
|
85
86
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_IP_BLOCKING, true)
|
|
86
87
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_USER_BLOCKING, true)
|
|
@@ -93,6 +94,7 @@ function enableWafUpdate (appsecConfig) {
|
|
|
93
94
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_CUSTOM_BLOCKING_RESPONSE, true)
|
|
94
95
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_TRUSTED_IPS, true)
|
|
95
96
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_ENDPOINT_FINGERPRINT, true)
|
|
97
|
+
rc.updateCapabilities(RemoteConfigCapabilities.ASM_SESSION_FINGERPRINT, true)
|
|
96
98
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_NETWORK_FINGERPRINT, true)
|
|
97
99
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_HEADER_FINGERPRINT, true)
|
|
98
100
|
|
|
@@ -115,7 +117,7 @@ function enableWafUpdate (appsecConfig) {
|
|
|
115
117
|
|
|
116
118
|
function disableWafUpdate () {
|
|
117
119
|
if (rc) {
|
|
118
|
-
const RuleManager = require('../rule_manager')
|
|
120
|
+
const RuleManager = require('../appsec/rule_manager')
|
|
119
121
|
|
|
120
122
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_IP_BLOCKING, false)
|
|
121
123
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_USER_BLOCKING, false)
|
|
@@ -127,6 +129,7 @@ function disableWafUpdate () {
|
|
|
127
129
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_CUSTOM_BLOCKING_RESPONSE, false)
|
|
128
130
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_TRUSTED_IPS, false)
|
|
129
131
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_ENDPOINT_FINGERPRINT, false)
|
|
132
|
+
rc.updateCapabilities(RemoteConfigCapabilities.ASM_SESSION_FINGERPRINT, false)
|
|
130
133
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_NETWORK_FINGERPRINT, false)
|
|
131
134
|
rc.updateCapabilities(RemoteConfigCapabilities.ASM_HEADER_FINGERPRINT, false)
|
|
132
135
|
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
const { URL, format } = require('url')
|
|
4
4
|
const uuid = require('crypto-randomuuid')
|
|
5
5
|
const { EventEmitter } = require('events')
|
|
6
|
-
const tracerVersion = require('
|
|
7
|
-
const request = require('
|
|
8
|
-
const log = require('
|
|
9
|
-
const { getExtraServices } = require('
|
|
6
|
+
const tracerVersion = require('../../../../package.json').version
|
|
7
|
+
const request = require('../exporters/common/request')
|
|
8
|
+
const log = require('../log')
|
|
9
|
+
const { getExtraServices } = require('../service-naming/extra-services')
|
|
10
10
|
const { UNACKNOWLEDGED, ACKNOWLEDGED, ERROR } = require('./apply_states')
|
|
11
11
|
const Scheduler = require('./scheduler')
|
|
12
|
-
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('
|
|
12
|
+
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
13
13
|
|
|
14
14
|
const clientId = uuid()
|
|
15
15
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
let runtimeMetrics
|
|
4
|
+
|
|
5
|
+
const noop = runtimeMetrics = {
|
|
6
|
+
stop () {},
|
|
7
|
+
track () {},
|
|
8
|
+
boolean () {},
|
|
9
|
+
histogram () {},
|
|
10
|
+
count () {},
|
|
11
|
+
gauge () {},
|
|
12
|
+
increment () {},
|
|
13
|
+
decrement () {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
start (config) {
|
|
18
|
+
if (!config?.runtimeMetrics) return
|
|
19
|
+
|
|
20
|
+
runtimeMetrics = require('./runtime_metrics')
|
|
21
|
+
|
|
22
|
+
Object.setPrototypeOf(module.exports, runtimeMetrics)
|
|
23
|
+
|
|
24
|
+
runtimeMetrics.start(config)
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
stop () {
|
|
28
|
+
runtimeMetrics.stop()
|
|
29
|
+
|
|
30
|
+
Object.setPrototypeOf(module.exports, runtimeMetrics = noop)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Object.setPrototypeOf(module.exports, noop)
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
const v8 = require('v8')
|
|
6
6
|
const os = require('os')
|
|
7
|
-
const { DogStatsDClient } = require('
|
|
8
|
-
const log = require('
|
|
9
|
-
const Histogram = require('
|
|
7
|
+
const { DogStatsDClient } = require('../dogstatsd')
|
|
8
|
+
const log = require('../log')
|
|
9
|
+
const Histogram = require('../histogram')
|
|
10
10
|
const { performance, PerformanceObserver } = require('perf_hooks')
|
|
11
11
|
|
|
12
|
-
const { NODE_MAJOR, NODE_MINOR } = require('
|
|
12
|
+
const { NODE_MAJOR, NODE_MINOR } = require('../../../../version')
|
|
13
13
|
const INTERVAL = 10 * 1000
|
|
14
14
|
|
|
15
15
|
// Node >=16 has PerformanceObserver with `gc` type, but <16.7 had a critical bug.
|
|
@@ -60,9 +60,18 @@ function getIsAzureFunction () {
|
|
|
60
60
|
return isAzureFunction
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
function isInServerlessEnvironment () {
|
|
64
|
+
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
65
|
+
const isGCPFunction = getIsGCPFunction()
|
|
66
|
+
const isAzureFunction = getIsAzureFunction()
|
|
67
|
+
|
|
68
|
+
return inAWSLambda || isGCPFunction || isAzureFunction
|
|
69
|
+
}
|
|
70
|
+
|
|
63
71
|
module.exports = {
|
|
64
72
|
maybeStartServerlessMiniAgent,
|
|
65
73
|
getIsGCPFunction,
|
|
66
74
|
getIsAzureFunction,
|
|
67
|
-
getRustBinaryPath
|
|
75
|
+
getRustBinaryPath,
|
|
76
|
+
isInServerlessEnvironment
|
|
68
77
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
const { schemaDefinitions } = require('./schemas')
|
|
2
|
-
|
|
3
1
|
class SchemaManager {
|
|
4
2
|
constructor () {
|
|
5
|
-
this.schemas =
|
|
6
|
-
this.
|
|
3
|
+
this.schemas = {}
|
|
4
|
+
this.configure({ spanAttributeSchema: 'v0', spanRemoveIntegrationFromService: false })
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
get schema () {
|
|
@@ -31,6 +29,16 @@ class SchemaManager {
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
configure (config = {}) {
|
|
32
|
+
const { spanAttributeSchema, spanRemoveIntegrationFromService } = config
|
|
33
|
+
|
|
34
|
+
if (!this.schemas.v0 && spanAttributeSchema === 'v0') {
|
|
35
|
+
this.schemas.v0 = require('./schemas/v0')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!this.schemas.v1 && (spanAttributeSchema === 'v1' || spanRemoveIntegrationFromService)) {
|
|
39
|
+
this.schemas.v1 = require('./schemas/v1')
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
this.config = config
|
|
35
43
|
}
|
|
36
44
|
}
|
|
@@ -5,8 +5,6 @@ const format = require('./format')
|
|
|
5
5
|
const SpanSampler = require('./span_sampler')
|
|
6
6
|
const GitMetadataTagger = require('./git_metadata_tagger')
|
|
7
7
|
|
|
8
|
-
const { SpanStatsProcessor } = require('./span_stats')
|
|
9
|
-
|
|
10
8
|
const startedSpans = new WeakSet()
|
|
11
9
|
const finishedSpans = new WeakSet()
|
|
12
10
|
|
|
@@ -20,7 +18,12 @@ class SpanProcessor {
|
|
|
20
18
|
this._config = config
|
|
21
19
|
this._killAll = false
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
// TODO: This should already have been calculated in `config.js`.
|
|
22
|
+
if (config.stats?.enabled && !config.appsec?.standalone?.enabled) {
|
|
23
|
+
const { SpanStatsProcessor } = require('./span_stats')
|
|
24
|
+
this._stats = new SpanStatsProcessor(config)
|
|
25
|
+
}
|
|
26
|
+
|
|
24
27
|
this._spanSampler = new SpanSampler(config.sampler)
|
|
25
28
|
this._gitMetadataTagger = new GitMetadataTagger(config)
|
|
26
29
|
}
|
|
@@ -46,7 +49,7 @@ class SpanProcessor {
|
|
|
46
49
|
for (const span of started) {
|
|
47
50
|
if (span._duration !== undefined) {
|
|
48
51
|
const formattedSpan = format(span)
|
|
49
|
-
this._stats
|
|
52
|
+
this._stats?.onSpanFinished(formattedSpan)
|
|
50
53
|
formatted.push(formattedSpan)
|
|
51
54
|
|
|
52
55
|
spanProcessCh.publish({ span })
|
|
@@ -127,7 +127,6 @@ class SpanStatsProcessor {
|
|
|
127
127
|
url,
|
|
128
128
|
env,
|
|
129
129
|
tags,
|
|
130
|
-
appsec,
|
|
131
130
|
version
|
|
132
131
|
} = {}) {
|
|
133
132
|
this.exporter = new SpanStatsExporter({
|
|
@@ -140,7 +139,7 @@ class SpanStatsProcessor {
|
|
|
140
139
|
this.bucketSizeNs = interval * 1e9
|
|
141
140
|
this.buckets = new TimeBuckets()
|
|
142
141
|
this.hostname = os.hostname()
|
|
143
|
-
this.enabled = enabled
|
|
142
|
+
this.enabled = enabled
|
|
144
143
|
this.env = env
|
|
145
144
|
this.tags = tags || {}
|
|
146
145
|
this.sequence = 0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel } = require('dc-polyfill')
|
|
4
|
+
const TraceSourcePrioritySampler = require('./tracesource_priority_sampler')
|
|
5
|
+
const { USER_KEEP } = require('../../../../ext/priority')
|
|
6
|
+
const TraceState = require('../opentracing/propagation/tracestate')
|
|
7
|
+
const { APM_TRACING_ENABLED_KEY } = require('../constants')
|
|
8
|
+
const { hasTraceSourcePropagationTag } = require('./tracesource')
|
|
9
|
+
|
|
10
|
+
const startCh = channel('dd-trace:span:start')
|
|
11
|
+
const injectCh = channel('dd-trace:span:inject')
|
|
12
|
+
const extractCh = channel('dd-trace:span:extract')
|
|
13
|
+
|
|
14
|
+
function configure (config) {
|
|
15
|
+
if (startCh.hasSubscribers) startCh.unsubscribe(onSpanStart)
|
|
16
|
+
if (injectCh.hasSubscribers) injectCh.unsubscribe(onSpanInject)
|
|
17
|
+
if (extractCh.hasSubscribers) extractCh.unsubscribe(onSpanExtract)
|
|
18
|
+
|
|
19
|
+
if (config.apmTracingEnabled !== false) return
|
|
20
|
+
|
|
21
|
+
startCh.subscribe(onSpanStart)
|
|
22
|
+
injectCh.subscribe(onSpanInject)
|
|
23
|
+
extractCh.subscribe(onSpanExtract)
|
|
24
|
+
|
|
25
|
+
return new TraceSourcePrioritySampler(config.env)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function onSpanStart ({ span, fields }) {
|
|
29
|
+
const tags = span.context?.()?._tags
|
|
30
|
+
if (!tags) return
|
|
31
|
+
|
|
32
|
+
const { parent } = fields
|
|
33
|
+
if (!parent || parent._isRemote) {
|
|
34
|
+
tags[APM_TRACING_ENABLED_KEY] = 0
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function onSpanInject ({ spanContext, carrier }) {
|
|
39
|
+
if (!spanContext?._trace?.tags || !carrier) return
|
|
40
|
+
|
|
41
|
+
// do not inject trace and sampling if there is no _dd.p.ts
|
|
42
|
+
if (!hasTraceSourcePropagationTag(spanContext._trace.tags)) {
|
|
43
|
+
for (const key in carrier) {
|
|
44
|
+
const lKey = key.toLowerCase()
|
|
45
|
+
if (lKey.startsWith('x-datadog') || lKey.startsWith('x-b3') || lKey === 'traceparent') {
|
|
46
|
+
delete carrier[key]
|
|
47
|
+
} else if (lKey === 'tracestate') {
|
|
48
|
+
const tracestate = TraceState.fromString(carrier[key])
|
|
49
|
+
tracestate.forVendor('dd', state => state.clear())
|
|
50
|
+
carrier[key] = tracestate.toString()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function onSpanExtract ({ spanContext = {} }) {
|
|
57
|
+
if (!spanContext._trace?.tags || !spanContext._sampling) return
|
|
58
|
+
|
|
59
|
+
// reset upstream priority if _dd.p.ts is not found
|
|
60
|
+
if (!hasTraceSourcePropagationTag(spanContext._trace.tags)) {
|
|
61
|
+
spanContext._sampling.priority = undefined
|
|
62
|
+
} else if (spanContext._sampling.priority !== USER_KEEP) {
|
|
63
|
+
spanContext._sampling.priority = USER_KEEP
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
configure,
|
|
69
|
+
hasTraceSourcePropagationTag
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { SAMPLING_MECHANISM_APPSEC } = require('../constants')
|
|
4
|
+
const RateLimiter = require('../rate_limiter')
|
|
5
|
+
|
|
6
|
+
const dropAll = new RateLimiter(0)
|
|
7
|
+
const onePerMinute = new RateLimiter(1, 'minute')
|
|
8
|
+
|
|
9
|
+
function getProductRateLimiter (config) {
|
|
10
|
+
if (config?.appsec?.enabled || config?.iast?.enabled) {
|
|
11
|
+
return onePerMinute
|
|
12
|
+
}
|
|
13
|
+
return dropAll
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
APM: { id: 1 << 0 },
|
|
18
|
+
ASM: { id: 1 << 1, mechanism: SAMPLING_MECHANISM_APPSEC },
|
|
19
|
+
DSM: { id: 1 << 2 },
|
|
20
|
+
DJM: { id: 1 << 3 },
|
|
21
|
+
DBM: { id: 1 << 4 },
|
|
22
|
+
|
|
23
|
+
getProductRateLimiter
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { TRACE_SOURCE_PROPAGATION_KEY } = require('../constants')
|
|
4
|
+
const { hasOwn } = require('../util')
|
|
5
|
+
|
|
6
|
+
function addTraceSourceTag (tags, product) {
|
|
7
|
+
if (tags && product) {
|
|
8
|
+
const actual = tags[TRACE_SOURCE_PROPAGATION_KEY] ? parseInt(tags[TRACE_SOURCE_PROPAGATION_KEY], 16) : 0
|
|
9
|
+
tags[TRACE_SOURCE_PROPAGATION_KEY] = ((actual | product.id) >>> 0).toString(16).padStart(2, '0')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return tags
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function hasTraceSourcePropagationTag (tags) {
|
|
16
|
+
return hasOwn(tags, TRACE_SOURCE_PROPAGATION_KEY)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
addTraceSourceTag,
|
|
21
|
+
hasTraceSourcePropagationTag
|
|
22
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { hasOwn } = require('../util')
|
|
4
|
+
const PrioritySampler = require('../priority_sampler')
|
|
5
|
+
const { MANUAL_KEEP } = require('../../../../ext/tags')
|
|
6
|
+
const { USER_KEEP, AUTO_KEEP, AUTO_REJECT } = require('../../../../ext/priority')
|
|
7
|
+
const { SAMPLING_MECHANISM_DEFAULT } = require('../constants')
|
|
8
|
+
const { addTraceSourceTag, hasTraceSourcePropagationTag } = require('./tracesource')
|
|
9
|
+
const { getProductRateLimiter } = require('./product')
|
|
10
|
+
|
|
11
|
+
class TraceSourcePrioritySampler extends PrioritySampler {
|
|
12
|
+
configure (env, sampler, config) {
|
|
13
|
+
// rules not supported
|
|
14
|
+
this._env = env
|
|
15
|
+
this._limiter = getProductRateLimiter(config)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
_getPriorityFromTags (tags, context) {
|
|
19
|
+
if (hasOwn(tags, MANUAL_KEEP) &&
|
|
20
|
+
tags[MANUAL_KEEP] !== false &&
|
|
21
|
+
hasTraceSourcePropagationTag(context._trace.tags)
|
|
22
|
+
) {
|
|
23
|
+
return USER_KEEP
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_getPriorityFromAuto (span) {
|
|
28
|
+
const context = this._getContext(span)
|
|
29
|
+
|
|
30
|
+
context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
|
|
31
|
+
|
|
32
|
+
if (hasTraceSourcePropagationTag(context._trace.tags)) {
|
|
33
|
+
return USER_KEEP
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return this._isSampledByRateLimit(context) ? AUTO_KEEP : AUTO_REJECT
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setPriority (span, samplingPriority, product) {
|
|
40
|
+
super.setPriority(span, samplingPriority, product)
|
|
41
|
+
|
|
42
|
+
const context = this._getContext(span)
|
|
43
|
+
addTraceSourceTag(context?._trace?.tags, product)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = TraceSourcePrioritySampler
|