dd-trace 4.18.0 → 4.23.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 +3 -2
- package/README.md +3 -3
- package/ext/kinds.d.ts +1 -0
- package/ext/kinds.js +2 -1
- package/ext/tags.d.ts +2 -1
- package/ext/tags.js +6 -1
- package/index.d.ts +29 -0
- package/package.json +12 -11
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-esbuild/index.js +1 -20
- package/packages/datadog-instrumentations/src/aerospike.js +47 -0
- package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
- package/packages/datadog-instrumentations/src/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/couchbase.js +5 -4
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/graphql.js +18 -4
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +10 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +19 -3
- package/packages/datadog-instrumentations/src/http/client.js +12 -2
- package/packages/datadog-instrumentations/src/http/server.js +7 -4
- package/packages/datadog-instrumentations/src/http2/client.js +3 -1
- package/packages/datadog-instrumentations/src/http2/server.js +3 -1
- package/packages/datadog-instrumentations/src/jest.js +12 -6
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-instrumentations/src/next.js +18 -6
- package/packages/datadog-instrumentations/src/restify.js +14 -1
- package/packages/datadog-instrumentations/src/rhea.js +15 -9
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-cucumber/src/index.js +34 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
- package/packages/datadog-plugin-graphql/src/resolve.js +26 -18
- package/packages/datadog-plugin-http/src/client.js +19 -2
- package/packages/datadog-plugin-jest/src/index.js +38 -4
- package/packages/datadog-plugin-kafkajs/src/consumer.js +59 -6
- package/packages/datadog-plugin-kafkajs/src/producer.js +64 -6
- package/packages/datadog-plugin-mocha/src/index.js +32 -1
- package/packages/datadog-plugin-next/src/index.js +40 -14
- package/packages/datadog-plugin-playwright/src/index.js +17 -1
- package/packages/dd-trace/src/appsec/activation.js +29 -0
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +48 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
- package/packages/dd-trace/src/appsec/blocking.js +95 -43
- package/packages/dd-trace/src/appsec/channels.js +5 -2
- package/packages/dd-trace/src/appsec/graphql.js +146 -0
- 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/iast-log.js +1 -1
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- 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 +33 -32
- package/packages/dd-trace/src/appsec/recommended.json +1737 -120
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +40 -15
- package/packages/dd-trace/src/appsec/reporter.js +50 -34
- package/packages/dd-trace/src/appsec/rule_manager.js +9 -6
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +28 -13
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -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 +110 -59
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +40 -7
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +26 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
- package/packages/dd-trace/src/config.js +145 -63
- package/packages/dd-trace/src/datastreams/processor.js +166 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
- package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
- package/packages/dd-trace/src/format.js +6 -1
- package/packages/dd-trace/src/id.js +12 -0
- package/packages/dd-trace/src/iitm.js +1 -1
- package/packages/dd-trace/src/log/channels.js +1 -1
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/opentelemetry/span.js +95 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +14 -5
- package/packages/dd-trace/src/opentracing/span.js +6 -0
- package/packages/dd-trace/src/opentracing/span_context.js +5 -2
- package/packages/dd-trace/src/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +46 -9
- package/packages/dd-trace/src/plugins/database.js +1 -1
- package/packages/dd-trace/src/plugins/index.js +6 -0
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +6 -19
- package/packages/dd-trace/src/plugins/util/exec.js +23 -2
- package/packages/dd-trace/src/plugins/util/git.js +98 -22
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
- package/packages/dd-trace/src/plugins/util/test.js +3 -2
- package/packages/dd-trace/src/plugins/util/url.js +26 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +4 -16
- package/packages/dd-trace/src/priority_sampler.js +30 -38
- package/packages/dd-trace/src/profiler.js +5 -3
- package/packages/dd-trace/src/profiling/config.js +26 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/profiler.js +17 -10
- package/packages/dd-trace/src/profiling/profilers/events.js +264 -0
- package/packages/dd-trace/src/profiling/profilers/shared.js +39 -0
- package/packages/dd-trace/src/profiling/profilers/space.js +2 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +121 -58
- package/packages/dd-trace/src/proxy.js +25 -1
- package/packages/dd-trace/src/ritm.js +1 -1
- package/packages/dd-trace/src/sampling_rule.js +130 -0
- 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/span_processor.js +4 -0
- package/packages/dd-trace/src/span_sampler.js +6 -64
- 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 +56 -10
- package/packages/dd-trace/src/telemetry/index.js +171 -41
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +47 -5
- package/packages/dd-trace/src/tracer.js +8 -2
- package/scripts/install_plugin_modules.js +11 -3
- package/packages/diagnostics_channel/index.js +0 -3
- package/packages/diagnostics_channel/src/index.js +0 -121
|
@@ -3,8 +3,13 @@ const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
|
3
3
|
const { AgentEncoder } = require('./0.4')
|
|
4
4
|
const { version: ddTraceVersion } = require('../../../../package.json')
|
|
5
5
|
const id = require('../../../dd-trace/src/id')
|
|
6
|
-
const
|
|
6
|
+
const {
|
|
7
|
+
distributionMetric,
|
|
8
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
9
|
+
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT
|
|
10
|
+
} = require('../ci-visibility/telemetry')
|
|
7
11
|
|
|
12
|
+
const ENCODING_VERSION = 1
|
|
8
13
|
const ALLOWED_CONTENT_TYPES = ['test_session_end', 'test_module_end', 'test_suite_end', 'test']
|
|
9
14
|
|
|
10
15
|
const TEST_SUITE_KEYS_LENGTH = 12
|
|
@@ -247,6 +252,8 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
_encode (bytes, trace) {
|
|
255
|
+
const startTime = Date.now()
|
|
256
|
+
|
|
250
257
|
const rawEvents = trace.map(formatSpan)
|
|
251
258
|
|
|
252
259
|
const testSessionEvents = rawEvents.filter(
|
|
@@ -261,9 +268,15 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
261
268
|
for (const event of events) {
|
|
262
269
|
this._encodeEvent(bytes, event)
|
|
263
270
|
}
|
|
271
|
+
distributionMetric(
|
|
272
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
273
|
+
{ endpoint: 'test_cycle' },
|
|
274
|
+
Date.now() - startTime
|
|
275
|
+
)
|
|
264
276
|
}
|
|
265
277
|
|
|
266
278
|
makePayload () {
|
|
279
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT, { endpoint: 'test_cycle' }, this._eventCount)
|
|
267
280
|
const bytes = this._traceBytes
|
|
268
281
|
const eventsOffset = this._eventsOffset
|
|
269
282
|
const eventsCount = this._eventCount
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
const { AgentEncoder } = require('./0.4')
|
|
3
3
|
const Chunk = require('./chunk')
|
|
4
4
|
|
|
5
|
+
const {
|
|
6
|
+
distributionMetric,
|
|
7
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
8
|
+
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT
|
|
9
|
+
} = require('../ci-visibility/telemetry')
|
|
5
10
|
const FormData = require('../exporters/common/form-data')
|
|
6
11
|
|
|
7
12
|
const COVERAGE_PAYLOAD_VERSION = 2
|
|
@@ -21,8 +26,16 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
encode (coverage) {
|
|
29
|
+
const startTime = Date.now()
|
|
30
|
+
|
|
24
31
|
this._coveragesCount++
|
|
25
32
|
this.encodeCodeCoverage(this._coverageBytes, coverage)
|
|
33
|
+
|
|
34
|
+
distributionMetric(
|
|
35
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
36
|
+
{ endpoint: 'code_coverage' },
|
|
37
|
+
Date.now() - startTime
|
|
38
|
+
)
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
encodeCodeCoverage (bytes, coverage) {
|
|
@@ -73,6 +86,7 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
|
73
86
|
}
|
|
74
87
|
|
|
75
88
|
makePayload () {
|
|
89
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT, { endpoint: 'code_coverage' }, this._coveragesCount)
|
|
76
90
|
const bytes = this._coverageBytes
|
|
77
91
|
|
|
78
92
|
const coveragesOffset = this._coveragesOffset
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { URL, format } = require('url')
|
|
2
2
|
|
|
3
3
|
const request = require('./request')
|
|
4
|
+
const { incrementCountMetric, TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION } = require('../../ci-visibility/telemetry')
|
|
4
5
|
|
|
5
6
|
function fetchAgentInfo (url, callback) {
|
|
6
7
|
request('', {
|
|
@@ -49,6 +50,9 @@ class AgentInfoExporter {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
_export (payload, writer = this._writer, timerKey = '_timer') {
|
|
53
|
+
if (this._config.isCiVisibility) {
|
|
54
|
+
incrementCountMetric(TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION, {}, payload.length)
|
|
55
|
+
}
|
|
52
56
|
writer.append(payload)
|
|
53
57
|
|
|
54
58
|
const { flushInterval } = this._config
|
|
@@ -14,7 +14,7 @@ const SPAN_SAMPLING_MECHANISM = constants.SPAN_SAMPLING_MECHANISM
|
|
|
14
14
|
const SPAN_SAMPLING_RULE_RATE = constants.SPAN_SAMPLING_RULE_RATE
|
|
15
15
|
const SPAN_SAMPLING_MAX_PER_SECOND = constants.SPAN_SAMPLING_MAX_PER_SECOND
|
|
16
16
|
const SAMPLING_MECHANISM_SPAN = constants.SAMPLING_MECHANISM_SPAN
|
|
17
|
-
const { MEASURED, BASE_SERVICE } = tags
|
|
17
|
+
const { MEASURED, BASE_SERVICE, ANALYTICS } = tags
|
|
18
18
|
const ORIGIN_KEY = constants.ORIGIN_KEY
|
|
19
19
|
const HOSTNAME_KEY = constants.HOSTNAME_KEY
|
|
20
20
|
const TOP_LEVEL_KEY = constants.TOP_LEVEL_KEY
|
|
@@ -24,6 +24,7 @@ const ERROR_STACK = constants.ERROR_STACK
|
|
|
24
24
|
const ERROR_TYPE = constants.ERROR_TYPE
|
|
25
25
|
|
|
26
26
|
const map = {
|
|
27
|
+
'operation.name': 'name',
|
|
27
28
|
'service.name': 'service',
|
|
28
29
|
'span.type': 'type',
|
|
29
30
|
'resource.name': 'resource'
|
|
@@ -83,6 +84,7 @@ function extractTags (trace, span) {
|
|
|
83
84
|
|
|
84
85
|
for (const tag in tags) {
|
|
85
86
|
switch (tag) {
|
|
87
|
+
case 'operation.name':
|
|
86
88
|
case 'service.name':
|
|
87
89
|
case 'span.type':
|
|
88
90
|
case 'resource.name':
|
|
@@ -92,6 +94,9 @@ function extractTags (trace, span) {
|
|
|
92
94
|
case 'http.status_code':
|
|
93
95
|
addTag(trace.meta, {}, tag, tags[tag] && String(tags[tag]))
|
|
94
96
|
break
|
|
97
|
+
case 'analytics.event':
|
|
98
|
+
addTag({}, trace.metrics, ANALYTICS, tags[tag] === undefined || tags[tag] ? 1 : 0)
|
|
99
|
+
break
|
|
95
100
|
case HOSTNAME_KEY:
|
|
96
101
|
case MEASURED:
|
|
97
102
|
addTag({}, trace.metrics, tag, tags[tag] === undefined || tags[tag] ? 1 : 0)
|
|
@@ -42,6 +42,18 @@ class Identifier {
|
|
|
42
42
|
toJSON () {
|
|
43
43
|
return this.toString()
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
equals (other) {
|
|
47
|
+
const length = this._buffer.length
|
|
48
|
+
const otherLength = other._buffer.length
|
|
49
|
+
|
|
50
|
+
// Only compare the bytes available in both IDs.
|
|
51
|
+
for (let i = length, j = otherLength; i >= 0 && j >= 0; i--, j--) {
|
|
52
|
+
if (this._buffer[i] !== other._buffer[j]) return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
// Create a buffer, using an optional hexadecimal value if provided.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const semver = require('semver')
|
|
4
4
|
const logger = require('./log')
|
|
5
5
|
const { addHook } = require('import-in-the-middle')
|
|
6
|
-
const dc = require('
|
|
6
|
+
const dc = require('dc-polyfill')
|
|
7
7
|
|
|
8
8
|
if (semver.satisfies(process.versions.node, '>=14.13.1')) {
|
|
9
9
|
const moduleLoadStartChannel = dc.channel('dd-trace:moduleLoadStart')
|
|
@@ -11,6 +11,7 @@ const tracer = require('../../')
|
|
|
11
11
|
const DatadogSpan = require('../opentracing/span')
|
|
12
12
|
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../constants')
|
|
13
13
|
const { SERVICE_NAME, RESOURCE_NAME } = require('../../../../ext/tags')
|
|
14
|
+
const kinds = require('../../../../ext/kinds')
|
|
14
15
|
|
|
15
16
|
const SpanContext = require('./span_context')
|
|
16
17
|
|
|
@@ -19,6 +20,93 @@ function hrTimeToMilliseconds (time) {
|
|
|
19
20
|
return time[0] * 1e3 + time[1] / 1e6
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
const spanKindNames = {
|
|
24
|
+
[api.SpanKind.INTERNAL]: kinds.INTERNAL,
|
|
25
|
+
[api.SpanKind.SERVER]: kinds.SERVER,
|
|
26
|
+
[api.SpanKind.CLIENT]: kinds.CLIENT,
|
|
27
|
+
[api.SpanKind.PRODUCER]: kinds.PRODUCER,
|
|
28
|
+
[api.SpanKind.CONSUMER]: kinds.CONSUMER
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Several of these attributes are not yet supported by the Node.js OTel API.
|
|
33
|
+
* We check for old equivalents where we can, but not all had equivalents.
|
|
34
|
+
*/
|
|
35
|
+
function spanNameMapper (spanName, kind, attributes) {
|
|
36
|
+
if (spanName) return spanName
|
|
37
|
+
|
|
38
|
+
const opName = attributes['operation.name']
|
|
39
|
+
if (opName) return opName
|
|
40
|
+
|
|
41
|
+
const { INTERNAL, SERVER, CLIENT } = api.SpanKind
|
|
42
|
+
|
|
43
|
+
// HTTP server and client requests
|
|
44
|
+
// TODO: Drop http.method when http.request.method is supported.
|
|
45
|
+
for (const key of ['http.method', 'http.request.method']) {
|
|
46
|
+
if (key in attributes) {
|
|
47
|
+
if (kind === SERVER) {
|
|
48
|
+
return 'http.server.request'
|
|
49
|
+
}
|
|
50
|
+
if (kind === CLIENT) {
|
|
51
|
+
return 'http.client.request'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Databases
|
|
57
|
+
const dbSystem = attributes['db.system']
|
|
58
|
+
if (dbSystem && kind === CLIENT) {
|
|
59
|
+
return `${dbSystem}.query`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Messaging
|
|
63
|
+
const msgSys = attributes['messaging.system']
|
|
64
|
+
const msgOp = attributes['messaging.operation']
|
|
65
|
+
if (msgSys && msgOp && kind !== INTERNAL) {
|
|
66
|
+
return `${msgSys}.${msgOp}`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// RPC (and AWS)
|
|
70
|
+
const rpcSystem = attributes['rpc.system']
|
|
71
|
+
if (rpcSystem) {
|
|
72
|
+
if (kind === CLIENT) {
|
|
73
|
+
return rpcSystem === 'aws-api'
|
|
74
|
+
? `aws.${attributes['rpc.service'] || 'client'}.request`
|
|
75
|
+
: `${rpcSystem}.client.request`
|
|
76
|
+
}
|
|
77
|
+
if (kind === SERVER) {
|
|
78
|
+
return `${rpcSystem}.server.request`
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// FaaS
|
|
83
|
+
const faasProvider = attributes['faas.invoked_provider']
|
|
84
|
+
const faasName = attributes['faas.invoked_name']
|
|
85
|
+
const faasTrigger = attributes['faas.trigger']
|
|
86
|
+
if (kind === CLIENT && faasProvider && faasName) {
|
|
87
|
+
return `${faasProvider}.${faasName}.invoke`
|
|
88
|
+
}
|
|
89
|
+
if (kind === SERVER && faasTrigger) {
|
|
90
|
+
return `${faasTrigger}.invoke`
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// GraphQL
|
|
94
|
+
// NOTE: Not part of Semantic Convention spec yet, but is used in the GraphQL
|
|
95
|
+
// integration.
|
|
96
|
+
const isGraphQL = 'graphql.operation.type' in attributes
|
|
97
|
+
if (isGraphQL) return 'graphql.server.request'
|
|
98
|
+
|
|
99
|
+
// Network
|
|
100
|
+
// TODO: Doesn't exist yet. No equivalent.
|
|
101
|
+
const protocol = attributes['network.protocol.name']
|
|
102
|
+
const protocolPrefix = protocol ? `${protocol}.` : ''
|
|
103
|
+
if (kind === SERVER) return `${protocolPrefix}server.request`
|
|
104
|
+
if (kind === CLIENT) return `${protocolPrefix}client.request`
|
|
105
|
+
|
|
106
|
+
// If all else fails, default to stringified span.kind.
|
|
107
|
+
return spanKindNames[kind]
|
|
108
|
+
}
|
|
109
|
+
|
|
22
110
|
class Span {
|
|
23
111
|
constructor (
|
|
24
112
|
parentTracer,
|
|
@@ -27,7 +115,8 @@ class Span {
|
|
|
27
115
|
spanContext,
|
|
28
116
|
kind,
|
|
29
117
|
links = [],
|
|
30
|
-
timeInput
|
|
118
|
+
timeInput,
|
|
119
|
+
attributes
|
|
31
120
|
) {
|
|
32
121
|
const { _tracer } = tracer
|
|
33
122
|
|
|
@@ -35,7 +124,7 @@ class Span {
|
|
|
35
124
|
const startTime = hrTimeToMilliseconds(hrStartTime)
|
|
36
125
|
|
|
37
126
|
this._ddSpan = new DatadogSpan(_tracer, _tracer._processor, _tracer._prioritySampler, {
|
|
38
|
-
operationName: spanName,
|
|
127
|
+
operationName: spanNameMapper(spanName, kind, attributes),
|
|
39
128
|
context: spanContext._ddContext,
|
|
40
129
|
startTime,
|
|
41
130
|
hostname: _tracer._hostname,
|
|
@@ -46,6 +135,10 @@ class Span {
|
|
|
46
135
|
}
|
|
47
136
|
}, _tracer._debug)
|
|
48
137
|
|
|
138
|
+
if (attributes) {
|
|
139
|
+
this.setAttributes(attributes)
|
|
140
|
+
}
|
|
141
|
+
|
|
49
142
|
this._parentTracer = parentTracer
|
|
50
143
|
this._context = context
|
|
51
144
|
|
|
@@ -78,23 +78,22 @@ class Tracer {
|
|
|
78
78
|
// return api.trace.wrapSpanContext(spanContext)
|
|
79
79
|
// }
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
return new Span(
|
|
82
82
|
this,
|
|
83
83
|
context,
|
|
84
84
|
name,
|
|
85
85
|
spanContext,
|
|
86
86
|
spanKind,
|
|
87
87
|
links,
|
|
88
|
-
options.startTime
|
|
88
|
+
options.startTime,
|
|
89
|
+
|
|
90
|
+
// Set initial span attributes. The attributes object may have been mutated
|
|
91
|
+
// by the sampler, so we sanitize the merged attributes before setting them.
|
|
92
|
+
sanitizeAttributes(
|
|
93
|
+
// Object.assign(attributes, samplingResult.attributes)
|
|
94
|
+
attributes
|
|
95
|
+
)
|
|
89
96
|
)
|
|
90
|
-
// Set initial span attributes. The attributes object may have been mutated
|
|
91
|
-
// by the sampler, so we sanitize the merged attributes before setting them.
|
|
92
|
-
const initAttributes = sanitizeAttributes(
|
|
93
|
-
// Object.assign(attributes, samplingResult.attributes)
|
|
94
|
-
attributes
|
|
95
|
-
)
|
|
96
|
-
span.setAttributes(initAttributes)
|
|
97
|
-
return span
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
startActiveSpan (name, options, context, fn) {
|
|
@@ -236,11 +236,20 @@ class TextMapPropagator {
|
|
|
236
236
|
_extractDatadogContext (carrier) {
|
|
237
237
|
const spanContext = this._extractGenericContext(carrier, traceKey, spanKey, 10)
|
|
238
238
|
|
|
239
|
-
if (spanContext)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
239
|
+
if (!spanContext) return spanContext
|
|
240
|
+
|
|
241
|
+
this._extractOrigin(carrier, spanContext)
|
|
242
|
+
this._extractBaggageItems(carrier, spanContext)
|
|
243
|
+
this._extractSamplingPriority(carrier, spanContext)
|
|
244
|
+
this._extractTags(carrier, spanContext)
|
|
245
|
+
|
|
246
|
+
if (this._config.tracePropagationExtractFirst) return spanContext
|
|
247
|
+
|
|
248
|
+
const tc = this._extractTraceparentContext(carrier)
|
|
249
|
+
|
|
250
|
+
if (tc && spanContext._traceId.equals(tc._traceId)) {
|
|
251
|
+
spanContext._traceparent = tc._traceparent
|
|
252
|
+
spanContext._tracestate = tc._tracestate
|
|
244
253
|
}
|
|
245
254
|
|
|
246
255
|
return spanContext
|
|
@@ -12,6 +12,8 @@ const runtimeMetrics = require('../runtime_metrics')
|
|
|
12
12
|
const log = require('../log')
|
|
13
13
|
const { storage } = require('../../../datadog-core')
|
|
14
14
|
const telemetryMetrics = require('../telemetry/metrics')
|
|
15
|
+
const { channel } = require('dc-polyfill')
|
|
16
|
+
const spanleak = require('../spanleak')
|
|
15
17
|
|
|
16
18
|
const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
|
|
17
19
|
|
|
@@ -30,6 +32,8 @@ const integrationCounters = {
|
|
|
30
32
|
span_finished: {}
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
const finishCh = channel('dd-trace:span:finish')
|
|
36
|
+
|
|
33
37
|
function getIntegrationCounter (event, integration) {
|
|
34
38
|
const counters = integrationCounters[event]
|
|
35
39
|
|
|
@@ -87,6 +91,7 @@ class DatadogSpan {
|
|
|
87
91
|
|
|
88
92
|
unfinishedRegistry.register(this, operationName, this)
|
|
89
93
|
}
|
|
94
|
+
spanleak.addSpan(this, operationName)
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
toString () {
|
|
@@ -176,6 +181,7 @@ class DatadogSpan {
|
|
|
176
181
|
this._duration = finishTime - this._startTime
|
|
177
182
|
this._spanContext._trace.finished.push(this)
|
|
178
183
|
this._spanContext._isFinished = true
|
|
184
|
+
finishCh.publish(this)
|
|
179
185
|
this._processor.process(this)
|
|
180
186
|
}
|
|
181
187
|
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { AUTO_KEEP } = require('../../../../ext/priority')
|
|
4
4
|
|
|
5
|
+
// the lowercase, hex encoded upper 64 bits of a 128-bit trace id, if present
|
|
6
|
+
const TRACE_ID_128 = '_dd.p.tid'
|
|
7
|
+
|
|
5
8
|
class DatadogSpanContext {
|
|
6
9
|
constructor (props) {
|
|
7
10
|
props = props || {}
|
|
@@ -35,8 +38,8 @@ class DatadogSpanContext {
|
|
|
35
38
|
|
|
36
39
|
toTraceparent () {
|
|
37
40
|
const flags = this._sampling.priority >= AUTO_KEEP ? '01' : '00'
|
|
38
|
-
const traceId = this._traceId.toBuffer().length <= 8 && this._trace.tags[
|
|
39
|
-
? this._trace.tags[
|
|
41
|
+
const traceId = this._traceId.toBuffer().length <= 8 && this._trace.tags[TRACE_ID_128]
|
|
42
|
+
? this._trace.tags[TRACE_ID_128] + this._traceId.toString(16).padStart(16, '0')
|
|
40
43
|
: this._traceId.toString(16).padStart(32, '0')
|
|
41
44
|
const spanId = this._spanId.toString(16).padStart(16, '0')
|
|
42
45
|
const version = (this._traceparent && this._traceparent.version) || '00'
|
|
@@ -22,10 +22,10 @@ class DatadogTracer {
|
|
|
22
22
|
constructor (config) {
|
|
23
23
|
const Exporter = getExporter(config.experimental.exporter)
|
|
24
24
|
|
|
25
|
+
this._config = config
|
|
25
26
|
this._service = config.service
|
|
26
27
|
this._version = config.version
|
|
27
28
|
this._env = config.env
|
|
28
|
-
this._tags = config.tags
|
|
29
29
|
this._logInjection = config.logInjection
|
|
30
30
|
this._debug = config.debug
|
|
31
31
|
this._prioritySampler = new PrioritySampler(config.env, config.sampler)
|
|
@@ -64,7 +64,7 @@ class DatadogTracer {
|
|
|
64
64
|
integrationName: options.integrationName
|
|
65
65
|
}, this._debug)
|
|
66
66
|
|
|
67
|
-
span.addTags(this.
|
|
67
|
+
span.addTags(this._config.tags)
|
|
68
68
|
span.addTags(options.tags)
|
|
69
69
|
|
|
70
70
|
return span
|
|
@@ -20,6 +20,14 @@ const {
|
|
|
20
20
|
const Plugin = require('./plugin')
|
|
21
21
|
const { COMPONENT } = require('../constants')
|
|
22
22
|
const log = require('../log')
|
|
23
|
+
const {
|
|
24
|
+
incrementCountMetric,
|
|
25
|
+
distributionMetric,
|
|
26
|
+
TELEMETRY_EVENT_CREATED,
|
|
27
|
+
TELEMETRY_ITR_SKIPPED
|
|
28
|
+
} = require('../ci-visibility/telemetry')
|
|
29
|
+
const { CI_PROVIDER_NAME, GIT_REPOSITORY_URL, GIT_COMMIT_SHA, GIT_BRANCH } = require('./util/tags')
|
|
30
|
+
const { OS_VERSION, OS_PLATFORM, OS_ARCHITECTURE, RUNTIME_NAME, RUNTIME_VERSION } = require('./util/env')
|
|
23
31
|
|
|
24
32
|
module.exports = class CiPlugin extends Plugin {
|
|
25
33
|
constructor (...args) {
|
|
@@ -71,6 +79,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
71
79
|
...testSessionSpanMetadata
|
|
72
80
|
}
|
|
73
81
|
})
|
|
82
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'session')
|
|
74
83
|
this.testModuleSpan = this.tracer.startSpan(`${this.constructor.id}.test_module`, {
|
|
75
84
|
childOf: this.testSessionSpan,
|
|
76
85
|
tags: {
|
|
@@ -79,6 +88,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
79
88
|
...testModuleSpanMetadata
|
|
80
89
|
}
|
|
81
90
|
})
|
|
91
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'module')
|
|
82
92
|
})
|
|
83
93
|
|
|
84
94
|
this.addSub(`ci:${this.constructor.id}:itr:skipped-suites`, ({ skippedSuites, frameworkVersion }) => {
|
|
@@ -97,25 +107,49 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
97
107
|
}
|
|
98
108
|
}).finish()
|
|
99
109
|
})
|
|
110
|
+
this.telemetry.count(TELEMETRY_ITR_SKIPPED, { testLevel: 'suite' }, skippedSuites.length)
|
|
100
111
|
})
|
|
101
112
|
}
|
|
102
113
|
|
|
114
|
+
get telemetry () {
|
|
115
|
+
const testFramework = this.constructor.id
|
|
116
|
+
return {
|
|
117
|
+
ciVisEvent: function (name, testLevel, tags = {}) {
|
|
118
|
+
incrementCountMetric(name, {
|
|
119
|
+
testLevel,
|
|
120
|
+
testFramework,
|
|
121
|
+
isUnsupportedCIProvider: this.isUnsupportedCIProvider,
|
|
122
|
+
...tags
|
|
123
|
+
})
|
|
124
|
+
},
|
|
125
|
+
count: function (name, tags, value = 1) {
|
|
126
|
+
incrementCountMetric(name, tags, value)
|
|
127
|
+
},
|
|
128
|
+
distribution: function (name, tags, measure) {
|
|
129
|
+
distributionMetric(name, tags, measure)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
103
134
|
configure (config) {
|
|
104
135
|
super.configure(config)
|
|
105
136
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.id, this.config)
|
|
106
137
|
this.codeOwnersEntries = getCodeOwnersFileEntries()
|
|
107
138
|
|
|
108
139
|
const {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
140
|
+
[GIT_REPOSITORY_URL]: repositoryUrl,
|
|
141
|
+
[GIT_COMMIT_SHA]: sha,
|
|
142
|
+
[OS_VERSION]: osVersion,
|
|
143
|
+
[OS_PLATFORM]: osPlatform,
|
|
144
|
+
[OS_ARCHITECTURE]: osArchitecture,
|
|
145
|
+
[RUNTIME_NAME]: runtimeName,
|
|
146
|
+
[RUNTIME_VERSION]: runtimeVersion,
|
|
147
|
+
[GIT_BRANCH]: branch,
|
|
148
|
+
[CI_PROVIDER_NAME]: ciProviderName
|
|
117
149
|
} = this.testEnvironmentMetadata
|
|
118
150
|
|
|
151
|
+
this.isUnsupportedCIProvider = !ciProviderName
|
|
152
|
+
|
|
119
153
|
this.testConfiguration = {
|
|
120
154
|
repositoryUrl,
|
|
121
155
|
sha,
|
|
@@ -124,7 +158,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
124
158
|
osArchitecture,
|
|
125
159
|
runtimeName,
|
|
126
160
|
runtimeVersion,
|
|
127
|
-
branch
|
|
161
|
+
branch,
|
|
162
|
+
testLevel: 'suite'
|
|
128
163
|
}
|
|
129
164
|
}
|
|
130
165
|
|
|
@@ -169,6 +204,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
169
204
|
}
|
|
170
205
|
}
|
|
171
206
|
|
|
207
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'test', { hasCodeOwners: !!codeOwners })
|
|
208
|
+
|
|
172
209
|
const testSpan = this.tracer
|
|
173
210
|
.startSpan(`${this.constructor.id}.test`, {
|
|
174
211
|
childOf,
|
|
@@ -36,7 +36,7 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
36
36
|
const { encodedDddbs, encodedDde, encodedDdps, encodedDdpv } = this.serviceTags
|
|
37
37
|
|
|
38
38
|
return `dddbs='${encodedDddbs}',dde='${encodedDde}',` +
|
|
39
|
-
|
|
39
|
+
`ddps='${encodedDdps}',ddpv='${encodedDdpv}'`
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
getDbmServiceName (span, tracerService) {
|
|
@@ -17,6 +17,7 @@ module.exports = {
|
|
|
17
17
|
get '@opensearch-project/opensearch' () { return require('../../../datadog-plugin-opensearch/src') },
|
|
18
18
|
get '@redis/client' () { return require('../../../datadog-plugin-redis/src') },
|
|
19
19
|
get '@smithy/smithy-client' () { return require('../../../datadog-plugin-aws-sdk/src') },
|
|
20
|
+
get 'aerospike' () { return require('../../../datadog-plugin-aerospike/src') },
|
|
20
21
|
get 'amqp10' () { return require('../../../datadog-plugin-amqp10/src') },
|
|
21
22
|
get 'amqplib' () { return require('../../../datadog-plugin-amqplib/src') },
|
|
22
23
|
get 'aws-sdk' () { return require('../../../datadog-plugin-aws-sdk/src') },
|
|
@@ -58,6 +59,11 @@ module.exports = {
|
|
|
58
59
|
get 'mysql2' () { return require('../../../datadog-plugin-mysql2/src') },
|
|
59
60
|
get 'net' () { return require('../../../datadog-plugin-net/src') },
|
|
60
61
|
get 'next' () { return require('../../../datadog-plugin-next/src') },
|
|
62
|
+
get 'node:dns' () { return require('../../../datadog-plugin-dns/src') },
|
|
63
|
+
get 'node:http' () { return require('../../../datadog-plugin-http/src') },
|
|
64
|
+
get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
|
|
65
|
+
get 'node:https' () { return require('../../../datadog-plugin-http/src') },
|
|
66
|
+
get 'node:net' () { return require('../../../datadog-plugin-net/src') },
|
|
61
67
|
get 'oracledb' () { return require('../../../datadog-plugin-oracledb/src') },
|
|
62
68
|
get 'openai' () { return require('../../../datadog-plugin-openai/src') },
|
|
63
69
|
get 'paperplane' () { return require('../../../datadog-plugin-paperplane/src') },
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const URL = require('url').URL
|
|
2
|
-
|
|
3
1
|
const {
|
|
4
2
|
GIT_BRANCH,
|
|
5
3
|
GIT_COMMIT_SHA,
|
|
@@ -24,6 +22,7 @@ const {
|
|
|
24
22
|
CI_NODE_LABELS,
|
|
25
23
|
CI_NODE_NAME
|
|
26
24
|
} = require('./tags')
|
|
25
|
+
const { filterSensitiveInfoFromRepository } = require('./url')
|
|
27
26
|
|
|
28
27
|
// Receives a string with the form 'John Doe <john.doe@gmail.com>'
|
|
29
28
|
// and returns { name: 'John Doe', email: 'john.doe@gmail.com' }
|
|
@@ -67,20 +66,6 @@ function normalizeRef (ref) {
|
|
|
67
66
|
return ref.replace(/origin\/|refs\/heads\/|tags\//gm, '')
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
function filterSensitiveInfoFromRepository (repositoryUrl) {
|
|
71
|
-
if (repositoryUrl.startsWith('git@')) {
|
|
72
|
-
return repositoryUrl
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const { protocol, hostname, pathname } = new URL(repositoryUrl)
|
|
77
|
-
|
|
78
|
-
return `${protocol}//${hostname}${pathname}`
|
|
79
|
-
} catch (e) {
|
|
80
|
-
return ''
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
69
|
function resolveTilde (filePath) {
|
|
85
70
|
if (!filePath || typeof filePath !== 'string') {
|
|
86
71
|
return ''
|
|
@@ -271,20 +256,22 @@ module.exports = {
|
|
|
271
256
|
const ref = GITHUB_HEAD_REF || GITHUB_REF || ''
|
|
272
257
|
const refKey = ref.includes('tags/') ? GIT_TAG : GIT_BRANCH
|
|
273
258
|
|
|
259
|
+
// Both pipeline URL and job URL include GITHUB_SERVER_URL, which can include user credentials,
|
|
260
|
+
// so we pass them through `filterSensitiveInfoFromRepository`.
|
|
274
261
|
tags = {
|
|
275
262
|
[CI_PIPELINE_ID]: GITHUB_RUN_ID,
|
|
276
263
|
[CI_PIPELINE_NAME]: GITHUB_WORKFLOW,
|
|
277
264
|
[CI_PIPELINE_NUMBER]: GITHUB_RUN_NUMBER,
|
|
278
|
-
[CI_PIPELINE_URL]: pipelineURL,
|
|
265
|
+
[CI_PIPELINE_URL]: filterSensitiveInfoFromRepository(pipelineURL),
|
|
279
266
|
[CI_PROVIDER_NAME]: 'github',
|
|
280
267
|
[GIT_COMMIT_SHA]: GITHUB_SHA,
|
|
281
268
|
[GIT_REPOSITORY_URL]: repositoryURL,
|
|
282
|
-
[CI_JOB_URL]: jobUrl,
|
|
269
|
+
[CI_JOB_URL]: filterSensitiveInfoFromRepository(jobUrl),
|
|
283
270
|
[CI_JOB_NAME]: GITHUB_JOB,
|
|
284
271
|
[CI_WORKSPACE_PATH]: GITHUB_WORKSPACE,
|
|
285
272
|
[refKey]: ref,
|
|
286
273
|
[CI_ENV_VARS]: JSON.stringify({
|
|
287
|
-
GITHUB_SERVER_URL,
|
|
274
|
+
GITHUB_SERVER_URL: filterSensitiveInfoFromRepository(GITHUB_SERVER_URL),
|
|
288
275
|
GITHUB_REPOSITORY,
|
|
289
276
|
GITHUB_RUN_ID,
|
|
290
277
|
GITHUB_RUN_ATTEMPT
|