dd-trace 5.19.0 → 5.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/ext/formats.d.ts +1 -0
- package/ext/formats.js +2 -1
- package/index.d.ts +2 -1
- package/init.js +3 -15
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/body-parser.js +14 -2
- package/packages/datadog-instrumentations/src/cucumber.js +10 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +21 -12
- package/packages/datadog-instrumentations/src/http/client.js +7 -1
- package/packages/datadog-instrumentations/src/http/server.js +50 -13
- package/packages/datadog-instrumentations/src/mocha/main.js +111 -78
- package/packages/datadog-instrumentations/src/nyc.js +23 -0
- package/packages/datadog-instrumentations/src/process.js +29 -0
- package/packages/datadog-instrumentations/src/vitest.js +65 -25
- package/packages/datadog-plugin-aws-sdk/src/base.js +15 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +3 -3
- package/packages/datadog-plugin-cucumber/src/index.js +12 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +53 -12
- package/packages/datadog-plugin-jest/src/index.js +17 -4
- package/packages/datadog-plugin-mocha/src/index.js +25 -6
- package/packages/datadog-plugin-nyc/src/index.js +35 -0
- package/packages/datadog-plugin-playwright/src/index.js +9 -4
- package/packages/datadog-plugin-vitest/src/index.js +32 -5
- package/packages/dd-trace/src/appsec/blocking.js +10 -1
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +11 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/code-injection-sensitive-analyzer.js +25 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +12 -7
- package/packages/dd-trace/src/appsec/rasp.js +121 -7
- package/packages/dd-trace/src/appsec/recommended.json +220 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +40 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -4
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +8 -7
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -4
- package/packages/dd-trace/src/ci-visibility/telemetry.js +29 -2
- package/packages/dd-trace/src/config.js +158 -153
- package/packages/dd-trace/src/data_streams.js +44 -0
- package/packages/dd-trace/src/datastreams/pathway.js +4 -2
- package/packages/dd-trace/src/log/index.js +32 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +22 -39
- package/packages/dd-trace/src/opentelemetry/span_context.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +23 -14
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +9 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +60 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +43 -0
- package/packages/dd-trace/src/opentracing/span_context.js +1 -0
- package/packages/dd-trace/src/opentracing/tracer.js +10 -6
- package/packages/dd-trace/src/plugins/ci_plugin.js +11 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +12 -1
- package/packages/dd-trace/src/plugins/util/git.js +14 -1
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/telemetry/index.js +1 -1
- package/packages/dd-trace/src/tracer.js +2 -0
|
@@ -17,11 +17,13 @@ function shaHash (checkpointString) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function computeHash (service, env, edgeTags, parentHash) {
|
|
20
|
-
const
|
|
20
|
+
const hashableEdgeTags = edgeTags.filter(item => item !== 'manual_checkpoint:true')
|
|
21
|
+
|
|
22
|
+
const key = `${service}${env}` + hashableEdgeTags.join('') + parentHash.toString()
|
|
21
23
|
if (cache.get(key)) {
|
|
22
24
|
return cache.get(key)
|
|
23
25
|
}
|
|
24
|
-
const currentHash = shaHash(`${service}${env}` +
|
|
26
|
+
const currentHash = shaHash(`${service}${env}` + hashableEdgeTags.join(''))
|
|
25
27
|
const buf = Buffer.concat([currentHash, parentHash], 16)
|
|
26
28
|
const val = shaHash(buf.toString())
|
|
27
29
|
cache.set(key, val)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const coalesce = require('koalas')
|
|
4
|
+
const { isTrue } = require('../util')
|
|
3
5
|
const { debugChannel, infoChannel, warnChannel, errorChannel } = require('./channels')
|
|
4
6
|
const logWriter = require('./writer')
|
|
5
7
|
|
|
@@ -20,13 +22,29 @@ function processMsg (msg) {
|
|
|
20
22
|
return typeof msg === 'function' ? msg() : msg
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
const config = {
|
|
26
|
+
enabled: false,
|
|
27
|
+
logger: undefined,
|
|
28
|
+
logLevel: 'debug'
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
const log = {
|
|
32
|
+
/**
|
|
33
|
+
* @returns Read-only version of logging config. To modify config, call `log.use` and `log.toggle`
|
|
34
|
+
*/
|
|
35
|
+
getConfig () {
|
|
36
|
+
return { ...config }
|
|
37
|
+
},
|
|
38
|
+
|
|
24
39
|
use (logger) {
|
|
40
|
+
config.logger = logger
|
|
25
41
|
logWriter.use(logger)
|
|
26
42
|
return this
|
|
27
43
|
},
|
|
28
44
|
|
|
29
45
|
toggle (enabled, logLevel) {
|
|
46
|
+
config.enabled = enabled
|
|
47
|
+
config.logLevel = logLevel
|
|
30
48
|
logWriter.toggle(enabled, logLevel)
|
|
31
49
|
return this
|
|
32
50
|
},
|
|
@@ -76,4 +94,18 @@ const log = {
|
|
|
76
94
|
|
|
77
95
|
log.reset()
|
|
78
96
|
|
|
97
|
+
const enabled = isTrue(coalesce(
|
|
98
|
+
process.env.DD_TRACE_DEBUG,
|
|
99
|
+
process.env.OTEL_LOG_LEVEL === 'debug',
|
|
100
|
+
config.enabled
|
|
101
|
+
))
|
|
102
|
+
|
|
103
|
+
const logLevel = coalesce(
|
|
104
|
+
process.env.DD_TRACE_LOG_LEVEL,
|
|
105
|
+
process.env.OTEL_LOG_LEVEL,
|
|
106
|
+
config.logLevel
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
log.toggle(enabled, logLevel)
|
|
110
|
+
|
|
79
111
|
module.exports = log
|
|
@@ -2,61 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
const { AsyncLocalStorage } = require('async_hooks')
|
|
4
4
|
const { trace, ROOT_CONTEXT } = require('@opentelemetry/api')
|
|
5
|
+
const DataDogSpanContext = require('../opentracing/span_context')
|
|
5
6
|
|
|
6
7
|
const SpanContext = require('./span_context')
|
|
7
8
|
const tracer = require('../../')
|
|
8
9
|
|
|
9
|
-
// Horrible hack to acquire the otherwise inaccessible SPAN_KEY so we can redirect it...
|
|
10
|
-
// This is used for getting the current span context in OpenTelemetry, but the SPAN_KEY value is
|
|
11
|
-
// not exposed as it's meant to be read-only from outside the module. We want to hijack this logic
|
|
12
|
-
// so we can instead get the span context from the datadog context manager instead.
|
|
13
|
-
let SPAN_KEY
|
|
14
|
-
trace.getSpan({
|
|
15
|
-
getValue (key) {
|
|
16
|
-
SPAN_KEY = key
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
// Whenever a value is acquired from the context map we should mostly delegate to the real getter,
|
|
21
|
-
// but when accessing the current span we should hijack that access to instead provide a fake span
|
|
22
|
-
// which we can use to get an OTel span context wrapping the datadog active scope span context.
|
|
23
|
-
function wrappedGetValue (target) {
|
|
24
|
-
return (key) => {
|
|
25
|
-
if (key === SPAN_KEY) {
|
|
26
|
-
return {
|
|
27
|
-
spanContext () {
|
|
28
|
-
const activeSpan = tracer.scope().active()
|
|
29
|
-
const context = activeSpan && activeSpan.context()
|
|
30
|
-
return new SpanContext(context)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return target.getValue(key)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
10
|
class ContextManager {
|
|
39
11
|
constructor () {
|
|
40
12
|
this._store = new AsyncLocalStorage()
|
|
41
13
|
}
|
|
42
14
|
|
|
43
15
|
active () {
|
|
44
|
-
const
|
|
16
|
+
const activeSpan = tracer.scope().active()
|
|
17
|
+
const store = this._store.getStore()
|
|
18
|
+
const context = (activeSpan && activeSpan.context()) || store || ROOT_CONTEXT
|
|
45
19
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
20
|
+
if (!(context instanceof DataDogSpanContext)) {
|
|
21
|
+
return context
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!context._otelSpanContext) {
|
|
25
|
+
const newSpanContext = new SpanContext(context)
|
|
26
|
+
context._otelSpanContext = newSpanContext
|
|
27
|
+
}
|
|
28
|
+
if (store && trace.getSpanContext(store) === context._otelSpanContext) {
|
|
29
|
+
return store
|
|
30
|
+
}
|
|
31
|
+
return trace.setSpanContext(store || ROOT_CONTEXT, context._otelSpanContext)
|
|
51
32
|
}
|
|
52
33
|
|
|
53
34
|
with (context, fn, thisArg, ...args) {
|
|
54
35
|
const span = trace.getSpan(context)
|
|
55
36
|
const ddScope = tracer.scope()
|
|
56
|
-
|
|
37
|
+
const run = () => {
|
|
57
38
|
const cb = thisArg == null ? fn : fn.bind(thisArg)
|
|
58
39
|
return this._store.run(context, cb, ...args)
|
|
59
|
-
}
|
|
40
|
+
}
|
|
41
|
+
if (span && span._ddSpan) {
|
|
42
|
+
return ddScope.activate(span._ddSpan, run)
|
|
43
|
+
}
|
|
44
|
+
return run()
|
|
60
45
|
}
|
|
61
46
|
|
|
62
47
|
bind (context, target) {
|
|
@@ -66,9 +51,7 @@ class ContextManager {
|
|
|
66
51
|
}
|
|
67
52
|
}
|
|
68
53
|
|
|
69
|
-
// Not part of the spec but the Node.js API expects these
|
|
70
54
|
enable () {}
|
|
71
55
|
disable () {}
|
|
72
56
|
}
|
|
73
|
-
|
|
74
57
|
module.exports = ContextManager
|
|
@@ -24,11 +24,11 @@ class SpanContext {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
get traceId () {
|
|
27
|
-
return this._ddContext.
|
|
27
|
+
return this._ddContext.toTraceId(true)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
get spanId () {
|
|
31
|
-
return this._ddContext.
|
|
31
|
+
return this._ddContext.toSpanId(true)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
get traceFlags () {
|
|
@@ -7,6 +7,7 @@ const Sampler = require('./sampler')
|
|
|
7
7
|
const Span = require('./span')
|
|
8
8
|
const id = require('../id')
|
|
9
9
|
const SpanContext = require('./span_context')
|
|
10
|
+
const TextMapPropagator = require('../opentracing/propagation/text_map')
|
|
10
11
|
|
|
11
12
|
class Tracer {
|
|
12
13
|
constructor (library, config, tracerProvider) {
|
|
@@ -22,6 +23,24 @@ class Tracer {
|
|
|
22
23
|
return this._tracerProvider.resource
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
_createSpanContextFromParent (parentSpanContext) {
|
|
27
|
+
return new SpanContext({
|
|
28
|
+
traceId: parentSpanContext._traceId,
|
|
29
|
+
spanId: id(),
|
|
30
|
+
parentId: parentSpanContext._spanId,
|
|
31
|
+
sampling: parentSpanContext._sampling,
|
|
32
|
+
baggageItems: Object.assign({}, parentSpanContext._baggageItems),
|
|
33
|
+
trace: parentSpanContext._trace,
|
|
34
|
+
tracestate: parentSpanContext._tracestate
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Extracted method to create span context for a new span
|
|
39
|
+
_createSpanContextForNewSpan (context) {
|
|
40
|
+
const { traceId, spanId, traceFlags, traceState } = context
|
|
41
|
+
return TextMapPropagator._convertOtelContextToDatadog(traceId, spanId, traceFlags, traceState)
|
|
42
|
+
}
|
|
43
|
+
|
|
25
44
|
startSpan (name, options = {}, context = api.context.active()) {
|
|
26
45
|
// remove span from context in case a root span is requested via options
|
|
27
46
|
if (options.root) {
|
|
@@ -29,21 +48,11 @@ class Tracer {
|
|
|
29
48
|
}
|
|
30
49
|
const parentSpan = api.trace.getSpan(context)
|
|
31
50
|
const parentSpanContext = parentSpan && parentSpan.spanContext()
|
|
32
|
-
|
|
33
51
|
let spanContext
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
spanContext = new SpanContext({
|
|
39
|
-
traceId: parent._traceId,
|
|
40
|
-
spanId: id(),
|
|
41
|
-
parentId: parent._spanId,
|
|
42
|
-
sampling: parent._sampling,
|
|
43
|
-
baggageItems: Object.assign({}, parent._baggageItems),
|
|
44
|
-
trace: parent._trace,
|
|
45
|
-
tracestate: parent._tracestate
|
|
46
|
-
})
|
|
52
|
+
if (parentSpanContext && api.trace.isSpanContextValid(parentSpanContext)) {
|
|
53
|
+
spanContext = parentSpanContext._ddContext
|
|
54
|
+
? this._createSpanContextFromParent(parentSpanContext._ddContext)
|
|
55
|
+
: this._createSpanContextForNewSpan(parentSpanContext)
|
|
47
56
|
} else {
|
|
48
57
|
spanContext = new SpanContext()
|
|
49
58
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { trace, context } = require('@opentelemetry/api')
|
|
3
|
+
const { trace, context, propagation } = require('@opentelemetry/api')
|
|
4
|
+
const { W3CTraceContextPropagator } = require('@opentelemetry/core')
|
|
4
5
|
|
|
5
6
|
const tracer = require('../../')
|
|
6
7
|
|
|
@@ -52,6 +53,13 @@ class TracerProvider {
|
|
|
52
53
|
if (!trace.setGlobalTracerProvider(this)) {
|
|
53
54
|
trace.getTracerProvider().setDelegate(this)
|
|
54
55
|
}
|
|
56
|
+
// The default propagator used is the W3C Trace Context propagator, users should be able to pass in others
|
|
57
|
+
// as needed
|
|
58
|
+
if (config.propagator) {
|
|
59
|
+
propagation.setGlobalPropagator(config.propagator)
|
|
60
|
+
} else {
|
|
61
|
+
propagation.setGlobalPropagator(new W3CTraceContextPropagator())
|
|
62
|
+
}
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
forceFlush () {
|
|
@@ -15,7 +15,7 @@ class LogPropagator {
|
|
|
15
15
|
|
|
16
16
|
if (spanContext) {
|
|
17
17
|
if (this._config.traceId128BitLoggingEnabled && spanContext._trace.tags['_dd.p.tid']) {
|
|
18
|
-
carrier.dd.trace_id = spanContext.
|
|
18
|
+
carrier.dd.trace_id = spanContext.toTraceId(true)
|
|
19
19
|
} else {
|
|
20
20
|
carrier.dd.trace_id = spanContext.toTraceId()
|
|
21
21
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const pick = require('../../../../datadog-core/src/utils/src/pick')
|
|
4
4
|
const id = require('../../id')
|
|
5
5
|
const DatadogSpanContext = require('../span_context')
|
|
6
|
+
const OtelSpanContext = require('../../opentelemetry/span_context')
|
|
6
7
|
const log = require('../../log')
|
|
7
8
|
const TraceState = require('./tracestate')
|
|
8
9
|
const tags = require('../../../../../ext/tags')
|
|
@@ -618,6 +619,65 @@ class TextMapPropagator {
|
|
|
618
619
|
|
|
619
620
|
return spanContext._traceId.toString(16)
|
|
620
621
|
}
|
|
622
|
+
|
|
623
|
+
static _convertOtelContextToDatadog (traceId, spanId, traceFlag, ts, meta = {}) {
|
|
624
|
+
const origin = null
|
|
625
|
+
let samplingPriority = traceFlag
|
|
626
|
+
|
|
627
|
+
ts = ts?.traceparent || null
|
|
628
|
+
|
|
629
|
+
if (ts) {
|
|
630
|
+
// Use TraceState.fromString to parse the tracestate header
|
|
631
|
+
const traceState = TraceState.fromString(ts)
|
|
632
|
+
let ddTraceStateData = null
|
|
633
|
+
|
|
634
|
+
// Extract Datadog specific trace state data
|
|
635
|
+
traceState.forVendor('dd', (state) => {
|
|
636
|
+
ddTraceStateData = state
|
|
637
|
+
return state // You might need to adjust this part based on actual logic needed
|
|
638
|
+
})
|
|
639
|
+
|
|
640
|
+
if (ddTraceStateData) {
|
|
641
|
+
// Assuming ddTraceStateData is now a Map or similar structure containing Datadog trace state data
|
|
642
|
+
// Extract values as needed, similar to the original logic
|
|
643
|
+
const samplingPriorityTs = ddTraceStateData.get('s')
|
|
644
|
+
const origin = ddTraceStateData.get('o')
|
|
645
|
+
// Convert Map to object for meta
|
|
646
|
+
const otherPropagatedTags = Object.fromEntries(ddTraceStateData.entries())
|
|
647
|
+
|
|
648
|
+
// Update meta and samplingPriority based on extracted values
|
|
649
|
+
Object.assign(meta, otherPropagatedTags)
|
|
650
|
+
samplingPriority = TextMapPropagator._getSamplingPriority(traceFlag, parseInt(samplingPriorityTs, 10), origin)
|
|
651
|
+
} else {
|
|
652
|
+
log.debug(`no dd list member in tracestate from incoming request: ${ts}`)
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
const spanContext = new OtelSpanContext({
|
|
657
|
+
traceId: id(traceId, 16), spanId: id(), tags: meta, parentId: id(spanId, 16)
|
|
658
|
+
})
|
|
659
|
+
|
|
660
|
+
spanContext._sampling = { priority: samplingPriority }
|
|
661
|
+
spanContext._trace = { origin }
|
|
662
|
+
return spanContext
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
static _getSamplingPriority (traceparentSampled, tracestateSamplingPriority, origin = null) {
|
|
666
|
+
const fromRumWithoutPriority = !tracestateSamplingPriority && origin === 'rum'
|
|
667
|
+
|
|
668
|
+
let samplingPriority
|
|
669
|
+
if (!fromRumWithoutPriority && traceparentSampled === 0 &&
|
|
670
|
+
(!tracestateSamplingPriority || tracestateSamplingPriority >= 0)) {
|
|
671
|
+
samplingPriority = 0
|
|
672
|
+
} else if (!fromRumWithoutPriority && traceparentSampled === 1 &&
|
|
673
|
+
(!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
|
|
674
|
+
samplingPriority = 1
|
|
675
|
+
} else {
|
|
676
|
+
samplingPriority = tracestateSamplingPriority
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
return samplingPriority
|
|
680
|
+
}
|
|
621
681
|
}
|
|
622
682
|
|
|
623
683
|
module.exports = TextMapPropagator
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const pick = require('../../../../datadog-core/src/utils/src/pick')
|
|
2
|
+
const log = require('../../log')
|
|
3
|
+
|
|
4
|
+
const { DsmPathwayCodec } = require('../../datastreams/pathway')
|
|
5
|
+
|
|
6
|
+
const base64Key = 'dd-pathway-ctx-base64'
|
|
7
|
+
const logKeys = [base64Key]
|
|
8
|
+
|
|
9
|
+
class DSMTextMapPropagator {
|
|
10
|
+
constructor (config) {
|
|
11
|
+
this.config = config
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
inject (ctx, carrier) {
|
|
15
|
+
if (!this.config.dsmEnabled) return
|
|
16
|
+
|
|
17
|
+
this._injectDatadogDSMContext(ctx, carrier)
|
|
18
|
+
|
|
19
|
+
log.debug(() => `Inject into carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
extract (carrier) {
|
|
23
|
+
if (!this.config.dsmEnabled) return
|
|
24
|
+
|
|
25
|
+
const dsmContext = this._extractDatadogDSMContext(carrier)
|
|
26
|
+
|
|
27
|
+
if (!dsmContext) return dsmContext
|
|
28
|
+
|
|
29
|
+
log.debug(() => `Extract from carrier (DSM): ${JSON.stringify(pick(carrier, logKeys))}.`)
|
|
30
|
+
return dsmContext
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_injectDatadogDSMContext (ctx, carrier) {
|
|
34
|
+
DsmPathwayCodec.encode(ctx, carrier)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_extractDatadogDSMContext (carrier) {
|
|
38
|
+
const ctx = DsmPathwayCodec.decode(carrier)
|
|
39
|
+
return ctx
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = DSMTextMapPropagator
|
|
@@ -5,6 +5,7 @@ const Span = require('./span')
|
|
|
5
5
|
const SpanProcessor = require('../span_processor')
|
|
6
6
|
const PrioritySampler = require('../priority_sampler')
|
|
7
7
|
const TextMapPropagator = require('./propagation/text_map')
|
|
8
|
+
const DSMTextMapPropagator = require('./propagation/text_map_dsm')
|
|
8
9
|
const HttpPropagator = require('./propagation/http')
|
|
9
10
|
const BinaryPropagator = require('./propagation/binary')
|
|
10
11
|
const LogPropagator = require('./propagation/log')
|
|
@@ -38,7 +39,8 @@ class DatadogTracer {
|
|
|
38
39
|
[formats.TEXT_MAP]: new TextMapPropagator(config),
|
|
39
40
|
[formats.HTTP_HEADERS]: new HttpPropagator(config),
|
|
40
41
|
[formats.BINARY]: new BinaryPropagator(config),
|
|
41
|
-
[formats.LOG]: new LogPropagator(config)
|
|
42
|
+
[formats.LOG]: new LogPropagator(config),
|
|
43
|
+
[formats.TEXT_MAP_DSM]: new DSMTextMapPropagator(config)
|
|
42
44
|
}
|
|
43
45
|
if (config.reportHostname) {
|
|
44
46
|
this._hostname = os.hostname()
|
|
@@ -71,14 +73,16 @@ class DatadogTracer {
|
|
|
71
73
|
return span
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
inject (
|
|
75
|
-
if (
|
|
76
|
-
|
|
76
|
+
inject (context, format, carrier) {
|
|
77
|
+
if (context instanceof Span) {
|
|
78
|
+
context = context.context()
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
if (format !== 'text_map_dsm') {
|
|
83
|
+
this._prioritySampler.sample(context)
|
|
84
|
+
}
|
|
85
|
+
this._propagators[format].inject(context, carrier)
|
|
82
86
|
} catch (e) {
|
|
83
87
|
log.error(e)
|
|
84
88
|
runtimeMetrics.increment('datadog.tracer.node.inject.errors', true)
|
|
@@ -16,7 +16,8 @@ const {
|
|
|
16
16
|
getTestSuiteCommonTags,
|
|
17
17
|
TEST_STATUS,
|
|
18
18
|
TEST_SKIPPED_BY_ITR,
|
|
19
|
-
ITR_CORRELATION_ID
|
|
19
|
+
ITR_CORRELATION_ID,
|
|
20
|
+
TEST_SOURCE_FILE
|
|
20
21
|
} = require('./util/test')
|
|
21
22
|
const Plugin = require('./plugin')
|
|
22
23
|
const { COMPONENT } = require('../constants')
|
|
@@ -144,7 +145,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
144
145
|
incrementCountMetric(name, {
|
|
145
146
|
testLevel,
|
|
146
147
|
testFramework,
|
|
147
|
-
isUnsupportedCIProvider: this.
|
|
148
|
+
isUnsupportedCIProvider: !this.ciProviderName,
|
|
148
149
|
...tags
|
|
149
150
|
})
|
|
150
151
|
},
|
|
@@ -178,7 +179,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
178
179
|
|
|
179
180
|
this.codeOwnersEntries = getCodeOwnersFileEntries(repositoryRoot)
|
|
180
181
|
|
|
181
|
-
this.
|
|
182
|
+
this.ciProviderName = ciProviderName
|
|
182
183
|
|
|
183
184
|
this.testConfiguration = {
|
|
184
185
|
repositoryUrl,
|
|
@@ -207,7 +208,13 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
207
208
|
...extraTags
|
|
208
209
|
}
|
|
209
210
|
|
|
210
|
-
const
|
|
211
|
+
const { [TEST_SOURCE_FILE]: testSourceFile } = extraTags
|
|
212
|
+
// We'll try with the test source file if available (it could be different from the test suite)
|
|
213
|
+
let codeOwners = getCodeOwnersForFilename(testSourceFile, this.codeOwnersEntries)
|
|
214
|
+
if (!codeOwners) {
|
|
215
|
+
codeOwners = getCodeOwnersForFilename(testSuite, this.codeOwnersEntries)
|
|
216
|
+
}
|
|
217
|
+
|
|
211
218
|
if (codeOwners) {
|
|
212
219
|
testTags[TEST_CODE_OWNERS] = codeOwners
|
|
213
220
|
}
|
|
@@ -69,6 +69,7 @@ module.exports = {
|
|
|
69
69
|
get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
|
|
70
70
|
get 'node:https' () { return require('../../../datadog-plugin-http/src') },
|
|
71
71
|
get 'node:net' () { return require('../../../datadog-plugin-net/src') },
|
|
72
|
+
get nyc () { return require('../../../datadog-plugin-nyc/src') },
|
|
72
73
|
get oracledb () { return require('../../../datadog-plugin-oracledb/src') },
|
|
73
74
|
get openai () { return require('../../../datadog-plugin-openai/src') },
|
|
74
75
|
get paperplane () { return require('../../../datadog-plugin-paperplane/src') },
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// TODO: move anything related to tracing to TracingPlugin instead
|
|
4
4
|
|
|
5
5
|
const dc = require('dc-polyfill')
|
|
6
|
+
const logger = require('../log')
|
|
6
7
|
const { storage } = require('../../../datadog-core')
|
|
7
8
|
|
|
8
9
|
class Subscription {
|
|
@@ -72,7 +73,17 @@ module.exports = class Plugin {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
addSub (channelName, handler) {
|
|
75
|
-
|
|
76
|
+
const plugin = this
|
|
77
|
+
const wrappedHandler = function () {
|
|
78
|
+
try {
|
|
79
|
+
return handler.apply(this, arguments)
|
|
80
|
+
} catch (e) {
|
|
81
|
+
logger.error('Error in plugin handler:', e)
|
|
82
|
+
logger.info('Disabling plugin:', plugin.id)
|
|
83
|
+
plugin.configure(false)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this._subscriptions.push(new Subscription(channelName, wrappedHandler))
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
addBind (channelName, transform) {
|
|
@@ -77,6 +77,18 @@ function isDirectory (path) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
function isGitAvailable () {
|
|
81
|
+
const isWindows = os.platform() === 'win32'
|
|
82
|
+
const command = isWindows ? 'where' : 'which'
|
|
83
|
+
try {
|
|
84
|
+
cp.execFileSync(command, ['git'], { stdio: 'pipe' })
|
|
85
|
+
return true
|
|
86
|
+
} catch (e) {
|
|
87
|
+
incrementCountMetric(TELEMETRY_GIT_COMMAND_ERRORS, { command: 'check_git', exitCode: 'missing' })
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
function isShallowRepository () {
|
|
81
93
|
return sanitizedExec(
|
|
82
94
|
'git',
|
|
@@ -342,5 +354,6 @@ module.exports = {
|
|
|
342
354
|
getCommitsRevList,
|
|
343
355
|
GIT_REV_LIST_MAX_BUFFER,
|
|
344
356
|
isShallowRepository,
|
|
345
|
-
unshallowRepository
|
|
357
|
+
unshallowRepository,
|
|
358
|
+
isGitAvailable
|
|
346
359
|
}
|
|
@@ -181,6 +181,7 @@ class Tracer extends NoopProxy {
|
|
|
181
181
|
if (!this._tracingInitialized) {
|
|
182
182
|
const prioritySampler = appsecStandalone.configure(config)
|
|
183
183
|
this._tracer = new DatadogTracer(config, prioritySampler)
|
|
184
|
+
this.dataStreamsCheckpointer = this._tracer.dataStreamsCheckpointer
|
|
184
185
|
this.appsec = new AppsecSdk(this._tracer, config)
|
|
185
186
|
this._tracingInitialized = true
|
|
186
187
|
}
|
|
@@ -317,7 +317,7 @@ function updateConfig (changes, config) {
|
|
|
317
317
|
'sampler.rules': 'DD_TRACE_SAMPLING_RULES'
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping'])
|
|
320
|
+
const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping', 'serviceMapping'])
|
|
321
321
|
|
|
322
322
|
const configuration = []
|
|
323
323
|
const names = [] // list of config names whose values have been changed
|
|
@@ -11,6 +11,7 @@ const { DataStreamsProcessor } = require('./datastreams/processor')
|
|
|
11
11
|
const { DsmPathwayCodec } = require('./datastreams/pathway')
|
|
12
12
|
const { DD_MAJOR } = require('../../../version')
|
|
13
13
|
const DataStreamsContext = require('./data_streams_context')
|
|
14
|
+
const { DataStreamsCheckpointer } = require('./data_streams')
|
|
14
15
|
const { flushStartupLogs } = require('../../datadog-instrumentations/src/check_require_cache')
|
|
15
16
|
const log = require('./log/writer')
|
|
16
17
|
|
|
@@ -23,6 +24,7 @@ class DatadogTracer extends Tracer {
|
|
|
23
24
|
constructor (config, prioritySampler) {
|
|
24
25
|
super(config, prioritySampler)
|
|
25
26
|
this._dataStreamsProcessor = new DataStreamsProcessor(config)
|
|
27
|
+
this.dataStreamsCheckpointer = new DataStreamsCheckpointer(this)
|
|
26
28
|
this._scope = new Scope()
|
|
27
29
|
setStartupLogConfig(config)
|
|
28
30
|
flushStartupLogs(log)
|