dd-trace 3.19.0 → 3.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/index.d.ts +8 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/grpc/client.js +9 -5
- package/packages/datadog-instrumentations/src/grpc/server.js +8 -4
- 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
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const sensitiveHandler = require('./evidence-redaction/sensitive-handler')
|
|
2
|
+
|
|
3
|
+
class VulnerabilityFormatter {
|
|
4
|
+
constructor () {
|
|
5
|
+
this._redactVulnearbilities = true
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
setRedactVulnerabilities (shouldRedactVulnerabilities) {
|
|
9
|
+
this._redactVulnearbilities = shouldRedactVulnerabilities
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
extractSourcesFromVulnerability (vulnerability) {
|
|
13
|
+
if (!vulnerability.evidence.ranges) {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
return vulnerability.evidence.ranges.map(range => (
|
|
17
|
+
{
|
|
18
|
+
origin: range.iinfo.type,
|
|
19
|
+
name: range.iinfo.parameterName,
|
|
20
|
+
value: range.iinfo.parameterValue
|
|
21
|
+
}
|
|
22
|
+
))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getRedactedValueParts (type, evidence, sourcesIndexes, sources) {
|
|
26
|
+
const scrubbingResult = sensitiveHandler.scrubEvidence(type, evidence, sourcesIndexes, sources)
|
|
27
|
+
if (scrubbingResult) {
|
|
28
|
+
const { redactedValueParts, redactedSources } = scrubbingResult
|
|
29
|
+
redactedSources.forEach(i => {
|
|
30
|
+
delete sources[i].value
|
|
31
|
+
sources[i].redacted = true
|
|
32
|
+
})
|
|
33
|
+
return { valueParts: redactedValueParts }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return this.getUnredactedValueParts(evidence, sourcesIndexes)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getUnredactedValueParts (evidence, sourcesIndexes) {
|
|
40
|
+
const valueParts = []
|
|
41
|
+
let fromIndex = 0
|
|
42
|
+
evidence.ranges.forEach((range, rangeIndex) => {
|
|
43
|
+
if (fromIndex < range.start) {
|
|
44
|
+
valueParts.push({ value: evidence.value.substring(fromIndex, range.start) })
|
|
45
|
+
}
|
|
46
|
+
valueParts.push({ value: evidence.value.substring(range.start, range.end), source: sourcesIndexes[rangeIndex] })
|
|
47
|
+
fromIndex = range.end
|
|
48
|
+
})
|
|
49
|
+
if (fromIndex < evidence.value.length) {
|
|
50
|
+
valueParts.push({ value: evidence.value.substring(fromIndex) })
|
|
51
|
+
}
|
|
52
|
+
return { valueParts }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
formatEvidence (type, evidence, sourcesIndexes, sources) {
|
|
56
|
+
if (!evidence.ranges) {
|
|
57
|
+
return { value: evidence.value }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return this._redactVulnearbilities
|
|
61
|
+
? this.getRedactedValueParts(type, evidence, sourcesIndexes, sources)
|
|
62
|
+
: this.getUnredactedValueParts(evidence, sourcesIndexes)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
formatVulnerability (vulnerability, sourcesIndexes, sources) {
|
|
66
|
+
const formattedVulnerability = {
|
|
67
|
+
type: vulnerability.type,
|
|
68
|
+
hash: vulnerability.hash,
|
|
69
|
+
evidence: this.formatEvidence(vulnerability.type, vulnerability.evidence, sourcesIndexes, sources),
|
|
70
|
+
location: {
|
|
71
|
+
spanId: vulnerability.location.spanId
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (vulnerability.location.path) {
|
|
75
|
+
formattedVulnerability.location.path = vulnerability.location.path
|
|
76
|
+
}
|
|
77
|
+
if (vulnerability.location.line) {
|
|
78
|
+
formattedVulnerability.location.line = vulnerability.location.line
|
|
79
|
+
}
|
|
80
|
+
return formattedVulnerability
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
toJson (vulnerabilitiesToFormat) {
|
|
84
|
+
const sources = []
|
|
85
|
+
|
|
86
|
+
const vulnerabilities = vulnerabilitiesToFormat.map(vulnerability => {
|
|
87
|
+
const vulnerabilitySources = this.extractSourcesFromVulnerability(vulnerability)
|
|
88
|
+
const sourcesIndexes = []
|
|
89
|
+
vulnerabilitySources.forEach((source) => {
|
|
90
|
+
let sourceIndex = sources.findIndex(
|
|
91
|
+
existingSource =>
|
|
92
|
+
existingSource.origin === source.origin &&
|
|
93
|
+
existingSource.name === source.name &&
|
|
94
|
+
existingSource.value === source.value
|
|
95
|
+
)
|
|
96
|
+
if (sourceIndex === -1) {
|
|
97
|
+
sourceIndex = sources.length
|
|
98
|
+
sources.push(source)
|
|
99
|
+
}
|
|
100
|
+
sourcesIndexes.push(sourceIndex)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
return this.formatVulnerability(vulnerability, sourcesIndexes, sources)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
sources,
|
|
108
|
+
vulnerabilities
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = new VulnerabilityFormatter()
|
|
@@ -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 }), {}))
|
|
@@ -34,19 +36,6 @@ function safeJsonParse (input) {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
const namingVersions = ['v0', 'v1']
|
|
38
|
-
const defaultVersion = 'v0'
|
|
39
|
-
|
|
40
|
-
function validateNamingVersion (versionString) {
|
|
41
|
-
if (!namingVersions.includes(versionString)) {
|
|
42
|
-
log.warn(
|
|
43
|
-
`Unexpected input for config.spanAttributeSchema, picked default ${defaultVersion}`
|
|
44
|
-
)
|
|
45
|
-
return defaultVersion
|
|
46
|
-
}
|
|
47
|
-
return versionString
|
|
48
|
-
}
|
|
49
|
-
|
|
50
39
|
// Shallow clone with property name remapping
|
|
51
40
|
function remapify (input, mappings) {
|
|
52
41
|
if (!input) return
|
|
@@ -172,6 +161,8 @@ class Config {
|
|
|
172
161
|
process.env.DD_SERVICE_NAME ||
|
|
173
162
|
this.tags.service ||
|
|
174
163
|
process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
164
|
+
process.env.FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
|
|
165
|
+
process.env.K_SERVICE || // Google Cloud Function Name set by newer runtimes
|
|
175
166
|
pkg.name ||
|
|
176
167
|
'node'
|
|
177
168
|
const DD_SERVICE_MAPPING = coalesce(
|
|
@@ -196,9 +187,18 @@ class Config {
|
|
|
196
187
|
process.env.DD_TRACE_STARTUP_LOGS,
|
|
197
188
|
false
|
|
198
189
|
)
|
|
190
|
+
|
|
191
|
+
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
192
|
+
|
|
193
|
+
const isDeprecatedGCPFunction = process.env.FUNCTION_NAME !== undefined && process.env.GCP_PROJECT !== undefined
|
|
194
|
+
const isNewerGCPFunction = process.env.K_SERVICE !== undefined && process.env.FUNCTION_TARGET !== undefined
|
|
195
|
+
const isGCPFunction = isDeprecatedGCPFunction || isNewerGCPFunction
|
|
196
|
+
|
|
197
|
+
const inServerlessEnvironment = inAWSLambda || isGCPFunction
|
|
198
|
+
|
|
199
199
|
const DD_TRACE_TELEMETRY_ENABLED = coalesce(
|
|
200
200
|
process.env.DD_TRACE_TELEMETRY_ENABLED,
|
|
201
|
-
!
|
|
201
|
+
!inServerlessEnvironment
|
|
202
202
|
)
|
|
203
203
|
const DD_TELEMETRY_DEBUG_ENABLED = coalesce(
|
|
204
204
|
process.env.DD_TELEMETRY_DEBUG_ENABLED,
|
|
@@ -273,9 +273,7 @@ class Config {
|
|
|
273
273
|
process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
274
274
|
false
|
|
275
275
|
)
|
|
276
|
-
|
|
277
|
-
process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
278
|
-
)
|
|
276
|
+
|
|
279
277
|
const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
|
|
280
278
|
process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
281
279
|
'512'
|
|
@@ -284,7 +282,7 @@ class Config {
|
|
|
284
282
|
const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
|
|
285
283
|
options.stats,
|
|
286
284
|
process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
|
|
287
|
-
|
|
285
|
+
isGCPFunction
|
|
288
286
|
)
|
|
289
287
|
|
|
290
288
|
const DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = coalesce(
|
|
@@ -351,12 +349,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
351
349
|
maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
|
|
352
350
|
)
|
|
353
351
|
|
|
354
|
-
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
355
|
-
|
|
356
352
|
const remoteConfigOptions = options.remoteConfig || {}
|
|
357
353
|
const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
|
|
358
354
|
process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
|
|
359
|
-
!
|
|
355
|
+
!inServerlessEnvironment
|
|
360
356
|
)
|
|
361
357
|
const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
|
|
362
358
|
parseInt(remoteConfigOptions.pollInterval),
|
|
@@ -403,11 +399,22 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
403
399
|
true
|
|
404
400
|
)
|
|
405
401
|
|
|
402
|
+
const DD_IAST_REDACTION_ENABLED = coalesce(
|
|
403
|
+
iastOptions && iastOptions.redactionEnabled,
|
|
404
|
+
!isFalse(process.env.DD_IAST_REDACTION_ENABLED),
|
|
405
|
+
true
|
|
406
|
+
)
|
|
407
|
+
|
|
406
408
|
const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
|
|
407
409
|
process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
|
|
408
410
|
true
|
|
409
411
|
)
|
|
410
412
|
|
|
413
|
+
const DD_TRACE_GIT_METADATA_ENABLED = coalesce(
|
|
414
|
+
process.env.DD_TRACE_GIT_METADATA_ENABLED,
|
|
415
|
+
true
|
|
416
|
+
)
|
|
417
|
+
|
|
411
418
|
const ingestion = options.ingestion || {}
|
|
412
419
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
413
420
|
const sampler = {
|
|
@@ -439,7 +446,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
439
446
|
})
|
|
440
447
|
}
|
|
441
448
|
|
|
442
|
-
const defaultFlushInterval =
|
|
449
|
+
const defaultFlushInterval = inServerlessEnvironment ? 0 : 2000
|
|
443
450
|
|
|
444
451
|
this.tracing = !isFalse(DD_TRACING_ENABLED)
|
|
445
452
|
this.dbmPropagationMode = DD_DBM_PROPAGATION_MODE
|
|
@@ -482,7 +489,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
482
489
|
sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
|
|
483
490
|
exporters: DD_PROFILING_EXPORTERS
|
|
484
491
|
}
|
|
485
|
-
this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
486
492
|
this.lookup = options.lookup
|
|
487
493
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
488
494
|
// Disabled for CI Visibility's agentless
|
|
@@ -513,7 +519,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
513
519
|
requestSampling: DD_IAST_REQUEST_SAMPLING,
|
|
514
520
|
maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
|
|
515
521
|
maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
|
|
516
|
-
deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED
|
|
522
|
+
deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED,
|
|
523
|
+
redactionEnabled: DD_IAST_REDACTION_ENABLED
|
|
517
524
|
}
|
|
518
525
|
|
|
519
526
|
this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
|
|
@@ -522,6 +529,31 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
522
529
|
this.isGitUploadEnabled = this.isCiVisibility &&
|
|
523
530
|
(this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
|
|
524
531
|
|
|
532
|
+
this.gitMetadataEnabled = isTrue(DD_TRACE_GIT_METADATA_ENABLED)
|
|
533
|
+
|
|
534
|
+
if (this.gitMetadataEnabled) {
|
|
535
|
+
this.repositoryUrl = coalesce(
|
|
536
|
+
process.env.DD_GIT_REPOSITORY_URL,
|
|
537
|
+
this.tags[GIT_REPOSITORY_URL]
|
|
538
|
+
)
|
|
539
|
+
this.commitSHA = coalesce(
|
|
540
|
+
process.env.DD_GIT_COMMIT_SHA,
|
|
541
|
+
this.tags[GIT_COMMIT_SHA]
|
|
542
|
+
)
|
|
543
|
+
if (!this.repositoryUrl || !this.commitSHA) {
|
|
544
|
+
const DD_GIT_PROPERTIES_FILE = coalesce(
|
|
545
|
+
process.env.DD_GIT_PROPERTIES_FILE,
|
|
546
|
+
`${process.cwd()}/git.properties`
|
|
547
|
+
)
|
|
548
|
+
const gitPropertiesString = maybeFile(DD_GIT_PROPERTIES_FILE)
|
|
549
|
+
if (gitPropertiesString) {
|
|
550
|
+
const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
|
|
551
|
+
this.commitSHA = this.commitSHA || commitSHA
|
|
552
|
+
this.repositoryUrl = this.repositoryUrl || repositoryUrl
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
525
557
|
this.stats = {
|
|
526
558
|
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
527
559
|
}
|
|
@@ -529,6 +561,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
529
561
|
this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
530
562
|
this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
531
563
|
|
|
564
|
+
this.isGCPFunction = isGCPFunction
|
|
565
|
+
|
|
532
566
|
tagger.add(this.tags, {
|
|
533
567
|
service: this.service,
|
|
534
568
|
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,
|