dd-trace 2.32.0 → 2.34.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/index.d.ts +8 -1
- package/package.json +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
- package/packages/datadog-instrumentations/src/jest.js +20 -17
- package/packages/datadog-instrumentations/src/mocha.js +8 -4
- package/packages/datadog-instrumentations/src/next.js +6 -1
- package/packages/datadog-instrumentations/src/pg.js +3 -4
- package/packages/datadog-instrumentations/src/playwright.js +11 -1
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqplib/src/client.js +3 -4
- package/packages/datadog-plugin-amqplib/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +3 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -0
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +4 -2
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +8 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +3 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +3 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +3 -1
- package/packages/datadog-plugin-http/src/client.js +2 -1
- package/packages/datadog-plugin-http2/src/client.js +2 -1
- package/packages/datadog-plugin-jest/src/util.js +10 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
- package/packages/datadog-plugin-pg/src/index.js +5 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +3 -1
- package/packages/datadog-plugin-rhea/src/producer.js +5 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +22 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +40 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +37 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +29 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +35 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +95 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +144 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +113 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +8 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -76
- package/packages/dd-trace/src/config.js +59 -25
- package/packages/dd-trace/src/constants.js +3 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -4
- package/packages/dd-trace/src/git_metadata_tagger.js +17 -0
- package/packages/dd-trace/src/git_properties.js +32 -0
- package/packages/dd-trace/src/plugin_manager.js +0 -2
- package/packages/dd-trace/src/plugins/client.js +2 -3
- package/packages/dd-trace/src/plugins/consumer.js +2 -17
- package/packages/dd-trace/src/plugins/incoming.js +7 -0
- package/packages/dd-trace/src/plugins/{outbound.js → outgoing.js} +2 -2
- package/packages/dd-trace/src/plugins/producer.js +2 -17
- package/packages/dd-trace/src/plugins/server.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +0 -11
- package/packages/dd-trace/src/plugins/util/ci.js +62 -7
- package/packages/dd-trace/src/plugins/util/tags.js +5 -1
- package/packages/dd-trace/src/plugins/util/test.js +34 -17
- package/packages/dd-trace/src/profiling/constants.js +0 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/serverless.js +25 -0
- package/packages/dd-trace/src/span_processor.js +3 -0
- package/packages/dd-trace/src/telemetry/send-data.js +13 -3
- package/packages/dd-trace/src/tracer.js +3 -2
- package/version.js +9 -0
- package/packages/dd-trace/src/plugins/inbound.js +0 -7
- package/packages/dd-trace/src/service-naming/index.js +0 -41
- package/packages/dd-trace/src/service-naming/schemas/definition.js +0 -28
- package/packages/dd-trace/src/service-naming/schemas/index.js +0 -6
- package/packages/dd-trace/src/service-naming/schemas/v0.js +0 -66
- package/packages/dd-trace/src/service-naming/schemas/v1.js +0 -58
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const { MANUAL_KEEP } = require('../../../../../ext/tags')
|
|
2
2
|
const LRU = require('lru-cache')
|
|
3
|
+
const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
|
|
3
4
|
const VULNERABILITIES_KEY = 'vulnerabilities'
|
|
4
5
|
const IAST_JSON_TAG_KEY = '_dd.iast.json'
|
|
5
6
|
const VULNERABILITY_HASHES_MAX_SIZE = 1000
|
|
@@ -60,57 +61,6 @@ function isValidVulnerability (vulnerability) {
|
|
|
60
61
|
vulnerability.location && vulnerability.location.spanId
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
function formatEvidence (evidence, sourcesIndexes) {
|
|
64
|
-
if (!evidence.ranges) {
|
|
65
|
-
return { value: evidence.value }
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const valueParts = []
|
|
69
|
-
let fromIndex = 0
|
|
70
|
-
evidence.ranges.forEach((range, rangeIndex) => {
|
|
71
|
-
if (fromIndex < range.start) {
|
|
72
|
-
valueParts.push({ value: evidence.value.substring(fromIndex, range.start) })
|
|
73
|
-
}
|
|
74
|
-
valueParts.push({ value: evidence.value.substring(range.start, range.end), source: sourcesIndexes[rangeIndex] })
|
|
75
|
-
fromIndex = range.end
|
|
76
|
-
})
|
|
77
|
-
if (fromIndex < evidence.value.length) {
|
|
78
|
-
valueParts.push({ value: evidence.value.substring(fromIndex) })
|
|
79
|
-
}
|
|
80
|
-
return { valueParts }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function extractSourcesFromVulnerability (vulnerability) {
|
|
84
|
-
if (!vulnerability.evidence.ranges) {
|
|
85
|
-
return []
|
|
86
|
-
}
|
|
87
|
-
return vulnerability.evidence.ranges.map(range => (
|
|
88
|
-
{
|
|
89
|
-
origin: range.iinfo.type,
|
|
90
|
-
name: range.iinfo.parameterName,
|
|
91
|
-
value: range.iinfo.parameterValue
|
|
92
|
-
}
|
|
93
|
-
))
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function jsonVulnerabilityFromVulnerability (vulnerability, sourcesIndexes) {
|
|
97
|
-
const jsonVulnerability = {
|
|
98
|
-
type: vulnerability.type,
|
|
99
|
-
hash: vulnerability.hash,
|
|
100
|
-
evidence: formatEvidence(vulnerability.evidence, sourcesIndexes),
|
|
101
|
-
location: {
|
|
102
|
-
spanId: vulnerability.location.spanId
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (vulnerability.location.path) {
|
|
106
|
-
jsonVulnerability.location.path = vulnerability.location.path
|
|
107
|
-
}
|
|
108
|
-
if (vulnerability.location.line) {
|
|
109
|
-
jsonVulnerability.location.line = vulnerability.location.line
|
|
110
|
-
}
|
|
111
|
-
return jsonVulnerability
|
|
112
|
-
}
|
|
113
|
-
|
|
114
64
|
function sendVulnerabilities (vulnerabilities, rootSpan) {
|
|
115
65
|
if (vulnerabilities && vulnerabilities.length) {
|
|
116
66
|
let span = rootSpan
|
|
@@ -124,31 +74,8 @@ function sendVulnerabilities (vulnerabilities, rootSpan) {
|
|
|
124
74
|
}
|
|
125
75
|
|
|
126
76
|
if (span && span.addTags) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
vulnerabilities: []
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
deduplicateVulnerabilities(vulnerabilities).forEach((vulnerability) => {
|
|
133
|
-
if (isValidVulnerability(vulnerability)) {
|
|
134
|
-
const sourcesIndexes = []
|
|
135
|
-
const vulnerabilitySources = extractSourcesFromVulnerability(vulnerability)
|
|
136
|
-
vulnerabilitySources.forEach((source) => {
|
|
137
|
-
let sourceIndex = jsonToSend.sources.findIndex(
|
|
138
|
-
existingSource =>
|
|
139
|
-
existingSource.origin === source.origin &&
|
|
140
|
-
existingSource.name === source.name &&
|
|
141
|
-
existingSource.value === source.value
|
|
142
|
-
)
|
|
143
|
-
if (sourceIndex === -1) {
|
|
144
|
-
sourceIndex = jsonToSend.sources.length
|
|
145
|
-
jsonToSend.sources.push(source)
|
|
146
|
-
}
|
|
147
|
-
sourcesIndexes.push(sourceIndex)
|
|
148
|
-
})
|
|
149
|
-
jsonToSend.vulnerabilities.push(jsonVulnerabilityFromVulnerability(vulnerability, sourcesIndexes))
|
|
150
|
-
}
|
|
151
|
-
})
|
|
77
|
+
const validAndDedupVulnerabilities = deduplicateVulnerabilities(vulnerabilities).filter(isValidVulnerability)
|
|
78
|
+
const jsonToSend = vulnerabilitiesFormatter.toJson(validAndDedupVulnerabilities)
|
|
152
79
|
|
|
153
80
|
if (jsonToSend.vulnerabilities.length > 0) {
|
|
154
81
|
const tags = {}
|
|
@@ -194,6 +121,7 @@ function deduplicateVulnerabilities (vulnerabilities) {
|
|
|
194
121
|
|
|
195
122
|
function start (config, _tracer) {
|
|
196
123
|
deduplicationEnabled = config.iast.deduplicationEnabled
|
|
124
|
+
vulnerabilitiesFormatter.setRedactVulnerabilities(config.iast.redactionEnabled)
|
|
197
125
|
if (deduplicationEnabled) {
|
|
198
126
|
startClearCacheTimer()
|
|
199
127
|
}
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const os = require('os')
|
|
5
|
+
const uuid = require('crypto-randomuuid')
|
|
5
6
|
const URL = require('url').URL
|
|
6
7
|
const log = require('./log')
|
|
7
8
|
const pkg = require('./pkg')
|
|
8
9
|
const coalesce = require('koalas')
|
|
9
10
|
const tagger = require('./tagger')
|
|
10
11
|
const { isTrue, isFalse } = require('./util')
|
|
11
|
-
const
|
|
12
|
+
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('./plugins/util/tags')
|
|
13
|
+
const { getGitMetadataFromGitProperties } = require('./git_properties')
|
|
12
14
|
|
|
13
15
|
const fromEntries = Object.fromEntries || (entries =>
|
|
14
16
|
entries.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {}))
|
|
@@ -31,19 +33,6 @@ function safeJsonParse (input) {
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
const namingVersions = ['v0', 'v1']
|
|
35
|
-
const defaultVersion = 'v0'
|
|
36
|
-
|
|
37
|
-
function validateNamingVersion (versionString) {
|
|
38
|
-
if (!namingVersions.includes(versionString)) {
|
|
39
|
-
log.warn(
|
|
40
|
-
`Unexpected input for config.spanAttributeSchema, picked default ${defaultVersion}`
|
|
41
|
-
)
|
|
42
|
-
return defaultVersion
|
|
43
|
-
}
|
|
44
|
-
return versionString
|
|
45
|
-
}
|
|
46
|
-
|
|
47
36
|
// Shallow clone with property name remapping
|
|
48
37
|
function remapify (input, mappings) {
|
|
49
38
|
if (!input) return
|
|
@@ -169,6 +158,8 @@ class Config {
|
|
|
169
158
|
process.env.DD_SERVICE_NAME ||
|
|
170
159
|
this.tags.service ||
|
|
171
160
|
process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
161
|
+
process.env.FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
|
|
162
|
+
process.env.K_SERVICE || // Google Cloud Function Name set by newer runtimes
|
|
172
163
|
pkg.name ||
|
|
173
164
|
'node'
|
|
174
165
|
const DD_SERVICE_MAPPING = coalesce(
|
|
@@ -193,9 +184,18 @@ class Config {
|
|
|
193
184
|
process.env.DD_TRACE_STARTUP_LOGS,
|
|
194
185
|
false
|
|
195
186
|
)
|
|
187
|
+
|
|
188
|
+
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
189
|
+
|
|
190
|
+
const isDeprecatedGCPFunction = process.env.FUNCTION_NAME !== undefined && process.env.GCP_PROJECT !== undefined
|
|
191
|
+
const isNewerGCPFunction = process.env.K_SERVICE !== undefined && process.env.FUNCTION_TARGET !== undefined
|
|
192
|
+
const isGCPFunction = isDeprecatedGCPFunction || isNewerGCPFunction
|
|
193
|
+
|
|
194
|
+
const inServerlessEnvironment = inAWSLambda || isGCPFunction
|
|
195
|
+
|
|
196
196
|
const DD_TRACE_TELEMETRY_ENABLED = coalesce(
|
|
197
197
|
process.env.DD_TRACE_TELEMETRY_ENABLED,
|
|
198
|
-
!
|
|
198
|
+
!inServerlessEnvironment
|
|
199
199
|
)
|
|
200
200
|
const DD_TELEMETRY_DEBUG_ENABLED = coalesce(
|
|
201
201
|
process.env.DD_TELEMETRY_DEBUG_ENABLED,
|
|
@@ -270,9 +270,7 @@ class Config {
|
|
|
270
270
|
process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
271
271
|
false
|
|
272
272
|
)
|
|
273
|
-
|
|
274
|
-
process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
275
|
-
)
|
|
273
|
+
|
|
276
274
|
const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
|
|
277
275
|
process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
278
276
|
'512'
|
|
@@ -281,7 +279,7 @@ class Config {
|
|
|
281
279
|
const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
|
|
282
280
|
options.stats,
|
|
283
281
|
process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
|
|
284
|
-
|
|
282
|
+
isGCPFunction
|
|
285
283
|
)
|
|
286
284
|
|
|
287
285
|
const DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = coalesce(
|
|
@@ -348,12 +346,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
348
346
|
maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
|
|
349
347
|
)
|
|
350
348
|
|
|
351
|
-
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
352
|
-
|
|
353
349
|
const remoteConfigOptions = options.remoteConfig || {}
|
|
354
350
|
const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
|
|
355
351
|
process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
|
|
356
|
-
!
|
|
352
|
+
!inServerlessEnvironment
|
|
357
353
|
)
|
|
358
354
|
const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
|
|
359
355
|
parseInt(remoteConfigOptions.pollInterval),
|
|
@@ -400,11 +396,22 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
400
396
|
true
|
|
401
397
|
)
|
|
402
398
|
|
|
399
|
+
const DD_IAST_REDACTION_ENABLED = coalesce(
|
|
400
|
+
iastOptions && iastOptions.redactionEnabled,
|
|
401
|
+
!isFalse(process.env.DD_IAST_REDACTION_ENABLED),
|
|
402
|
+
true
|
|
403
|
+
)
|
|
404
|
+
|
|
403
405
|
const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
|
|
404
406
|
process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
|
|
405
407
|
true
|
|
406
408
|
)
|
|
407
409
|
|
|
410
|
+
const DD_TRACE_GIT_METADATA_ENABLED = coalesce(
|
|
411
|
+
process.env.DD_TRACE_GIT_METADATA_ENABLED,
|
|
412
|
+
true
|
|
413
|
+
)
|
|
414
|
+
|
|
408
415
|
const ingestion = options.ingestion || {}
|
|
409
416
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
410
417
|
const sampler = {
|
|
@@ -436,7 +443,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
436
443
|
})
|
|
437
444
|
}
|
|
438
445
|
|
|
439
|
-
const defaultFlushInterval =
|
|
446
|
+
const defaultFlushInterval = inServerlessEnvironment ? 0 : 2000
|
|
440
447
|
|
|
441
448
|
this.tracing = !isFalse(DD_TRACING_ENABLED)
|
|
442
449
|
this.dbmPropagationMode = DD_DBM_PROPAGATION_MODE
|
|
@@ -479,7 +486,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
479
486
|
sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
|
|
480
487
|
exporters: DD_PROFILING_EXPORTERS
|
|
481
488
|
}
|
|
482
|
-
this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
483
489
|
this.lookup = options.lookup
|
|
484
490
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
485
491
|
// Disabled for CI Visibility's agentless
|
|
@@ -510,7 +516,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
510
516
|
requestSampling: DD_IAST_REQUEST_SAMPLING,
|
|
511
517
|
maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
|
|
512
518
|
maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
|
|
513
|
-
deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED
|
|
519
|
+
deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED,
|
|
520
|
+
redactionEnabled: DD_IAST_REDACTION_ENABLED
|
|
514
521
|
}
|
|
515
522
|
|
|
516
523
|
this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
|
|
@@ -519,6 +526,31 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
519
526
|
this.isGitUploadEnabled = this.isCiVisibility &&
|
|
520
527
|
(this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
|
|
521
528
|
|
|
529
|
+
this.gitMetadataEnabled = isTrue(DD_TRACE_GIT_METADATA_ENABLED)
|
|
530
|
+
|
|
531
|
+
if (this.gitMetadataEnabled) {
|
|
532
|
+
this.repositoryUrl = coalesce(
|
|
533
|
+
process.env.DD_GIT_REPOSITORY_URL,
|
|
534
|
+
this.tags[GIT_REPOSITORY_URL]
|
|
535
|
+
)
|
|
536
|
+
this.commitSHA = coalesce(
|
|
537
|
+
process.env.DD_GIT_COMMIT_SHA,
|
|
538
|
+
this.tags[GIT_COMMIT_SHA]
|
|
539
|
+
)
|
|
540
|
+
if (!this.repositoryUrl || !this.commitSHA) {
|
|
541
|
+
const DD_GIT_PROPERTIES_FILE = coalesce(
|
|
542
|
+
process.env.DD_GIT_PROPERTIES_FILE,
|
|
543
|
+
`${process.cwd()}/git.properties`
|
|
544
|
+
)
|
|
545
|
+
const gitPropertiesString = maybeFile(DD_GIT_PROPERTIES_FILE)
|
|
546
|
+
if (gitPropertiesString) {
|
|
547
|
+
const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
|
|
548
|
+
this.commitSHA = this.commitSHA || commitSHA
|
|
549
|
+
this.repositoryUrl = this.repositoryUrl || repositoryUrl
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
522
554
|
this.stats = {
|
|
523
555
|
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
524
556
|
}
|
|
@@ -526,6 +558,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
526
558
|
this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
527
559
|
this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
528
560
|
|
|
561
|
+
this.isGCPFunction = isGCPFunction
|
|
562
|
+
|
|
529
563
|
tagger.add(this.tags, {
|
|
530
564
|
service: this.service,
|
|
531
565
|
env: this.env,
|
|
@@ -25,5 +25,7 @@ module.exports = {
|
|
|
25
25
|
ERROR_MESSAGE: 'error.message',
|
|
26
26
|
ERROR_STACK: 'error.stack',
|
|
27
27
|
COMPONENT: 'component',
|
|
28
|
-
CLIENT_PORT_KEY: 'network.destination.port'
|
|
28
|
+
CLIENT_PORT_KEY: 'network.destination.port',
|
|
29
|
+
SCI_REPOSITORY_URL: '_dd.git.repository_url',
|
|
30
|
+
SCI_COMMIT_SHA: '_dd.git.commit.sha'
|
|
29
31
|
}
|
|
@@ -129,12 +129,17 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
129
129
|
_encodeEventContent (bytes, content) {
|
|
130
130
|
const keysLength = Object.keys(content).length
|
|
131
131
|
|
|
132
|
+
let totalKeysLength = keysLength
|
|
132
133
|
if (content.meta.test_session_id) {
|
|
133
|
-
|
|
134
|
-
} else {
|
|
135
|
-
this._encodeMapPrefix(bytes, keysLength)
|
|
134
|
+
totalKeysLength = totalKeysLength + 1
|
|
136
135
|
}
|
|
137
|
-
|
|
136
|
+
if (content.meta.test_module_id) {
|
|
137
|
+
totalKeysLength = totalKeysLength + 1
|
|
138
|
+
}
|
|
139
|
+
if (content.meta.test_suite_id) {
|
|
140
|
+
totalKeysLength = totalKeysLength + 1
|
|
141
|
+
}
|
|
142
|
+
this._encodeMapPrefix(bytes, totalKeysLength)
|
|
138
143
|
if (content.type) {
|
|
139
144
|
this._encodeString(bytes, 'type')
|
|
140
145
|
this._encodeString(bytes, content.type)
|
|
@@ -170,15 +175,20 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
170
175
|
this._encodeString(bytes, 'test_session_id')
|
|
171
176
|
this._encodeId(bytes, id(content.meta.test_session_id, 10))
|
|
172
177
|
delete content.meta.test_session_id
|
|
178
|
+
}
|
|
173
179
|
|
|
180
|
+
if (content.meta.test_module_id) {
|
|
174
181
|
this._encodeString(bytes, 'test_module_id')
|
|
175
182
|
this._encodeId(bytes, id(content.meta.test_module_id, 10))
|
|
176
183
|
delete content.meta.test_module_id
|
|
184
|
+
}
|
|
177
185
|
|
|
186
|
+
if (content.meta.test_suite_id) {
|
|
178
187
|
this._encodeString(bytes, 'test_suite_id')
|
|
179
188
|
this._encodeId(bytes, id(content.meta.test_suite_id, 10))
|
|
180
189
|
delete content.meta.test_suite_id
|
|
181
190
|
}
|
|
191
|
+
|
|
182
192
|
this._encodeString(bytes, 'meta')
|
|
183
193
|
this._encodeMap(bytes, content.meta)
|
|
184
194
|
this._encodeString(bytes, 'metrics')
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { SCI_COMMIT_SHA, SCI_REPOSITORY_URL } = require('./constants')
|
|
2
|
+
|
|
3
|
+
class GitMetadataTagger {
|
|
4
|
+
constructor (config) {
|
|
5
|
+
this._config = config
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
tagGitMetadata (spanContext) {
|
|
9
|
+
if (this._config.gitMetadataEnabled) {
|
|
10
|
+
// These tags are added only to the local root span
|
|
11
|
+
spanContext._trace.tags[SCI_COMMIT_SHA] = this._config.commitSHA
|
|
12
|
+
spanContext._trace.tags[SCI_REPOSITORY_URL] = this._config.repositoryUrl
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = GitMetadataTagger
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const commitSHARegex = /git\.commit\.sha=([a-f\d]{40})/
|
|
2
|
+
const repositoryUrlRegex = /git\.repository_url=([\w\d:@/.-]+)/
|
|
3
|
+
|
|
4
|
+
function getGitMetadataFromGitProperties (gitPropertiesString) {
|
|
5
|
+
if (!gitPropertiesString) {
|
|
6
|
+
return {}
|
|
7
|
+
}
|
|
8
|
+
const commitSHAMatch = gitPropertiesString.match(commitSHARegex)
|
|
9
|
+
const repositoryUrlMatch = gitPropertiesString.match(repositoryUrlRegex)
|
|
10
|
+
|
|
11
|
+
const repositoryUrl = repositoryUrlMatch ? repositoryUrlMatch[1] : undefined
|
|
12
|
+
let parsedUrl = repositoryUrl
|
|
13
|
+
|
|
14
|
+
if (repositoryUrl) {
|
|
15
|
+
try {
|
|
16
|
+
// repository URLs can contain username and password, so we want to filter those out
|
|
17
|
+
parsedUrl = new URL(repositoryUrl)
|
|
18
|
+
if (parsedUrl.password) {
|
|
19
|
+
parsedUrl = `${parsedUrl.origin}${parsedUrl.pathname}`
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// if protocol isn't https, no password will be used
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
commitSHA: commitSHAMatch ? commitSHAMatch[1] : undefined,
|
|
28
|
+
repositoryUrl: parsedUrl
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { getGitMetadataFromGitProperties }
|
|
@@ -4,7 +4,6 @@ const { channel } = require('../../diagnostics_channel')
|
|
|
4
4
|
const { isFalse } = require('./util')
|
|
5
5
|
const plugins = require('./plugins')
|
|
6
6
|
const log = require('./log')
|
|
7
|
-
const Nomenclature = require('./service-naming')
|
|
8
7
|
|
|
9
8
|
const loadChannel = channel('dd-trace:instrumentation:load')
|
|
10
9
|
|
|
@@ -97,7 +96,6 @@ module.exports = class PluginManager {
|
|
|
97
96
|
// like instrumenter.enable()
|
|
98
97
|
configure (config = {}) {
|
|
99
98
|
this._tracerConfig = config
|
|
100
|
-
Nomenclature.configure(config)
|
|
101
99
|
|
|
102
100
|
for (const name in pluginClasses) {
|
|
103
101
|
this.loadPlugin(name)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutgoingPlugin = require('./outgoing')
|
|
4
4
|
|
|
5
|
-
class ClientPlugin extends
|
|
5
|
+
class ClientPlugin extends OutgoingPlugin {
|
|
6
6
|
static get operation () { return 'request' }
|
|
7
|
-
static get kind () { return 'client' }
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
module.exports = ClientPlugin
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const IncomingPlugin = require('./incoming')
|
|
4
4
|
|
|
5
|
-
class ConsumerPlugin extends
|
|
5
|
+
class ConsumerPlugin extends IncomingPlugin {
|
|
6
6
|
static get operation () { return 'receive' }
|
|
7
|
-
static get kind () { return 'consumer' }
|
|
8
|
-
static get type () { return 'messaging' }
|
|
9
|
-
|
|
10
|
-
startSpan (options) {
|
|
11
|
-
const spanDefaults = {
|
|
12
|
-
service: this.config.service || this.serviceName(),
|
|
13
|
-
kind: this.constructor.kind
|
|
14
|
-
}
|
|
15
|
-
Object.keys(spanDefaults).forEach(
|
|
16
|
-
key => {
|
|
17
|
-
if (!options[key]) options[key] = spanDefaults[key]
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
return super.startSpan(this.operationName(), options)
|
|
21
|
-
}
|
|
22
7
|
}
|
|
23
8
|
|
|
24
9
|
module.exports = ConsumerPlugin
|
|
@@ -4,7 +4,7 @@ const { CLIENT_PORT_KEY } = require('../constants')
|
|
|
4
4
|
const TracingPlugin = require('./tracing')
|
|
5
5
|
|
|
6
6
|
// TODO: Exit span on finish when AsyncResource instances are removed.
|
|
7
|
-
class
|
|
7
|
+
class OutgoingPlugin extends TracingPlugin {
|
|
8
8
|
constructor (...args) {
|
|
9
9
|
super(...args)
|
|
10
10
|
|
|
@@ -29,4 +29,4 @@ class OutboundPlugin extends TracingPlugin {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
module.exports =
|
|
32
|
+
module.exports = OutgoingPlugin
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutgoingPlugin = require('./outgoing')
|
|
4
4
|
|
|
5
|
-
class ProducerPlugin extends
|
|
5
|
+
class ProducerPlugin extends OutgoingPlugin {
|
|
6
6
|
static get operation () { return 'publish' }
|
|
7
|
-
static get kind () { return 'producer' }
|
|
8
|
-
static get type () { return 'messaging' }
|
|
9
|
-
|
|
10
|
-
startSpan (options) {
|
|
11
|
-
const spanDefaults = {
|
|
12
|
-
service: this.config.service || this.serviceName(),
|
|
13
|
-
kind: this.constructor.kind
|
|
14
|
-
}
|
|
15
|
-
Object.keys(spanDefaults).forEach(
|
|
16
|
-
key => {
|
|
17
|
-
if (!options[key]) options[key] = spanDefaults[key]
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
return super.startSpan(this.operationName(), options)
|
|
21
|
-
}
|
|
22
7
|
}
|
|
23
8
|
|
|
24
9
|
module.exports = ProducerPlugin
|
|
@@ -4,7 +4,6 @@ const Plugin = require('./plugin')
|
|
|
4
4
|
const { storage } = require('../../../datadog-core')
|
|
5
5
|
const analyticsSampler = require('../analytics_sampler')
|
|
6
6
|
const { COMPONENT } = require('../constants')
|
|
7
|
-
const Nomenclature = require('../service-naming')
|
|
8
7
|
|
|
9
8
|
class TracingPlugin extends Plugin {
|
|
10
9
|
constructor (...args) {
|
|
@@ -32,16 +31,6 @@ class TracingPlugin extends Plugin {
|
|
|
32
31
|
return store && store.span
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
serviceName (serviceArgs) {
|
|
36
|
-
const { type, id, kind } = this.constructor
|
|
37
|
-
return Nomenclature.serviceName(type, kind, id, serviceArgs)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
operationName (opNameArgs) {
|
|
41
|
-
const { type, id, kind } = this.constructor
|
|
42
|
-
return Nomenclature.opName(type, kind, id, opNameArgs)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
34
|
configure (config) {
|
|
46
35
|
return super.configure({
|
|
47
36
|
...config,
|
|
@@ -20,7 +20,9 @@ const {
|
|
|
20
20
|
CI_STAGE_NAME,
|
|
21
21
|
CI_ENV_VARS,
|
|
22
22
|
GIT_COMMIT_COMMITTER_NAME,
|
|
23
|
-
GIT_COMMIT_COMMITTER_EMAIL
|
|
23
|
+
GIT_COMMIT_COMMITTER_EMAIL,
|
|
24
|
+
CI_NODE_LABELS,
|
|
25
|
+
CI_NODE_NAME
|
|
24
26
|
} = require('./tags')
|
|
25
27
|
|
|
26
28
|
// Receives a string with the form 'John Doe <john.doe@gmail.com>'
|
|
@@ -108,7 +110,9 @@ module.exports = {
|
|
|
108
110
|
GIT_COMMIT: JENKINS_GIT_COMMIT,
|
|
109
111
|
GIT_URL: JENKINS_GIT_REPOSITORY_URL,
|
|
110
112
|
GIT_URL_1: JENKINS_GIT_REPOSITORY_URL_1,
|
|
111
|
-
DD_CUSTOM_TRACE_ID
|
|
113
|
+
DD_CUSTOM_TRACE_ID,
|
|
114
|
+
NODE_NAME,
|
|
115
|
+
NODE_LABELS
|
|
112
116
|
} = env
|
|
113
117
|
|
|
114
118
|
tags = {
|
|
@@ -119,7 +123,18 @@ module.exports = {
|
|
|
119
123
|
[GIT_COMMIT_SHA]: JENKINS_GIT_COMMIT,
|
|
120
124
|
[GIT_REPOSITORY_URL]: JENKINS_GIT_REPOSITORY_URL || JENKINS_GIT_REPOSITORY_URL_1,
|
|
121
125
|
[CI_WORKSPACE_PATH]: WORKSPACE,
|
|
122
|
-
[CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID })
|
|
126
|
+
[CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID }),
|
|
127
|
+
[CI_NODE_NAME]: NODE_NAME
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (NODE_LABELS) {
|
|
131
|
+
let nodeLabels
|
|
132
|
+
try {
|
|
133
|
+
nodeLabels = JSON.stringify(NODE_LABELS.split(' '))
|
|
134
|
+
tags[CI_NODE_LABELS] = nodeLabels
|
|
135
|
+
} catch (e) {
|
|
136
|
+
// ignore errors
|
|
137
|
+
}
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags/')
|
|
@@ -159,7 +174,9 @@ module.exports = {
|
|
|
159
174
|
CI_COMMIT_TIMESTAMP,
|
|
160
175
|
CI_COMMIT_AUTHOR,
|
|
161
176
|
CI_PROJECT_URL: GITLAB_PROJECT_URL,
|
|
162
|
-
CI_JOB_ID: GITLAB_CI_JOB_ID
|
|
177
|
+
CI_JOB_ID: GITLAB_CI_JOB_ID,
|
|
178
|
+
CI_RUNNER_ID,
|
|
179
|
+
CI_RUNNER_TAGS
|
|
163
180
|
} = env
|
|
164
181
|
|
|
165
182
|
const { name, email } = parseEmailAndName(CI_COMMIT_AUTHOR)
|
|
@@ -186,7 +203,9 @@ module.exports = {
|
|
|
186
203
|
CI_PROJECT_URL: GITLAB_PROJECT_URL,
|
|
187
204
|
CI_PIPELINE_ID: GITLAB_PIPELINE_ID,
|
|
188
205
|
CI_JOB_ID: GITLAB_CI_JOB_ID
|
|
189
|
-
})
|
|
206
|
+
}),
|
|
207
|
+
[CI_NODE_LABELS]: CI_RUNNER_TAGS,
|
|
208
|
+
[CI_NODE_NAME]: CI_RUNNER_ID
|
|
190
209
|
}
|
|
191
210
|
}
|
|
192
211
|
|
|
@@ -448,9 +467,17 @@ module.exports = {
|
|
|
448
467
|
BUILDKITE_BUILD_CHECKOUT_PATH,
|
|
449
468
|
BUILDKITE_BUILD_AUTHOR,
|
|
450
469
|
BUILDKITE_BUILD_AUTHOR_EMAIL,
|
|
451
|
-
BUILDKITE_MESSAGE
|
|
470
|
+
BUILDKITE_MESSAGE,
|
|
471
|
+
BUILDKITE_AGENT_ID
|
|
452
472
|
} = env
|
|
453
473
|
|
|
474
|
+
const extraTags = Object.keys(env).filter(envVar =>
|
|
475
|
+
envVar.startsWith('BUILDKITE_AGENT_META_DATA_')
|
|
476
|
+
).map((metadataKey) => {
|
|
477
|
+
const key = metadataKey.replace('BUILDKITE_AGENT_META_DATA_', '').toLowerCase()
|
|
478
|
+
return `${key}:${env[metadataKey]}`
|
|
479
|
+
})
|
|
480
|
+
|
|
454
481
|
tags = {
|
|
455
482
|
[CI_PROVIDER_NAME]: 'buildkite',
|
|
456
483
|
[CI_PIPELINE_ID]: BUILDKITE_BUILD_ID,
|
|
@@ -469,7 +496,9 @@ module.exports = {
|
|
|
469
496
|
[CI_ENV_VARS]: JSON.stringify({
|
|
470
497
|
BUILDKITE_BUILD_ID,
|
|
471
498
|
BUILDKITE_JOB_ID
|
|
472
|
-
})
|
|
499
|
+
}),
|
|
500
|
+
[CI_NODE_NAME]: BUILDKITE_AGENT_ID,
|
|
501
|
+
[CI_NODE_LABELS]: JSON.stringify(extraTags)
|
|
473
502
|
}
|
|
474
503
|
}
|
|
475
504
|
|
|
@@ -546,6 +575,32 @@ module.exports = {
|
|
|
546
575
|
}
|
|
547
576
|
}
|
|
548
577
|
|
|
578
|
+
if (env.CF_BUILD_ID) {
|
|
579
|
+
const {
|
|
580
|
+
CF_BUILD_ID,
|
|
581
|
+
CF_PIPELINE_NAME,
|
|
582
|
+
CF_BUILD_URL,
|
|
583
|
+
CF_STEP_NAME,
|
|
584
|
+
CF_BRANCH
|
|
585
|
+
} = env
|
|
586
|
+
tags = {
|
|
587
|
+
[CI_PROVIDER_NAME]: 'codefresh',
|
|
588
|
+
[CI_PIPELINE_ID]: CF_BUILD_ID,
|
|
589
|
+
[CI_PIPELINE_NAME]: CF_PIPELINE_NAME,
|
|
590
|
+
[CI_PIPELINE_URL]: CF_BUILD_URL,
|
|
591
|
+
[CI_JOB_NAME]: CF_STEP_NAME,
|
|
592
|
+
[CI_ENV_VARS]: JSON.stringify({
|
|
593
|
+
CF_BUILD_ID
|
|
594
|
+
})
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const isTag = CF_BRANCH && CF_BRANCH.includes('tags/')
|
|
598
|
+
const refKey = isTag ? GIT_TAG : GIT_BRANCH
|
|
599
|
+
const ref = normalizeRef(CF_BRANCH)
|
|
600
|
+
|
|
601
|
+
tags[refKey] = ref
|
|
602
|
+
}
|
|
603
|
+
|
|
549
604
|
normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde)
|
|
550
605
|
normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository)
|
|
551
606
|
normalizeTag(tags, GIT_BRANCH, normalizeRef)
|
|
@@ -19,6 +19,8 @@ const CI_WORKSPACE_PATH = 'ci.workspace_path'
|
|
|
19
19
|
const CI_JOB_URL = 'ci.job.url'
|
|
20
20
|
const CI_JOB_NAME = 'ci.job.name'
|
|
21
21
|
const CI_STAGE_NAME = 'ci.stage.name'
|
|
22
|
+
const CI_NODE_NAME = 'ci.node.name'
|
|
23
|
+
const CI_NODE_LABELS = 'ci.node.labels'
|
|
22
24
|
|
|
23
25
|
const CI_ENV_VARS = '_dd.ci.env_vars'
|
|
24
26
|
|
|
@@ -43,5 +45,7 @@ module.exports = {
|
|
|
43
45
|
CI_JOB_URL,
|
|
44
46
|
CI_JOB_NAME,
|
|
45
47
|
CI_STAGE_NAME,
|
|
46
|
-
CI_ENV_VARS
|
|
48
|
+
CI_ENV_VARS,
|
|
49
|
+
CI_NODE_NAME,
|
|
50
|
+
CI_NODE_LABELS
|
|
47
51
|
}
|