dd-trace 2.28.0 → 2.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +1 -2
- package/README.md +4 -0
- package/ci/init.js +9 -1
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +6 -2
- package/package.json +18 -17
- package/packages/datadog-instrumentations/src/cucumber.js +80 -3
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -27
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +35 -3
- package/packages/datadog-instrumentations/src/mariadb.js +130 -11
- package/packages/datadog-instrumentations/src/mocha.js +30 -6
- package/packages/datadog-instrumentations/src/mongodb-core.js +8 -2
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +32 -4
- package/packages/datadog-instrumentations/src/playwright.js +2 -2
- package/packages/datadog-plugin-amqp10/src/consumer.js +1 -1
- package/packages/datadog-plugin-amqp10/src/index.js +1 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -2
- package/packages/datadog-plugin-amqplib/src/client.js +3 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
- package/packages/datadog-plugin-amqplib/src/index.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +7 -2
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -0
- package/packages/datadog-plugin-bunyan/src/index.js +1 -1
- package/packages/datadog-plugin-cassandra-driver/src/index.js +3 -2
- package/packages/datadog-plugin-connect/src/index.js +1 -1
- package/packages/datadog-plugin-couchbase/src/index.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +33 -6
- package/packages/datadog-plugin-cypress/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/plugin.js +40 -33
- package/packages/datadog-plugin-dns/src/index.js +1 -1
- package/packages/datadog-plugin-dns/src/lookup.js +1 -1
- package/packages/datadog-plugin-dns/src/lookup_service.js +1 -1
- package/packages/datadog-plugin-dns/src/resolve.js +1 -1
- package/packages/datadog-plugin-dns/src/reverse.js +1 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-express/src/index.js +1 -1
- package/packages/datadog-plugin-fastify/src/index.js +1 -1
- package/packages/datadog-plugin-find-my-way/src/index.js +1 -1
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +5 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +7 -6
- package/packages/datadog-plugin-graphql/src/execute.js +1 -1
- package/packages/datadog-plugin-graphql/src/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/parse.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- package/packages/datadog-plugin-graphql/src/validate.js +1 -1
- package/packages/datadog-plugin-grpc/src/client.js +1 -1
- package/packages/datadog-plugin-grpc/src/index.js +1 -1
- package/packages/datadog-plugin-grpc/src/server.js +1 -1
- package/packages/datadog-plugin-hapi/src/index.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +2 -2
- package/packages/datadog-plugin-http/src/index.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +2 -2
- package/packages/datadog-plugin-http2/src/client.js +4 -3
- package/packages/datadog-plugin-http2/src/index.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +2 -2
- package/packages/datadog-plugin-ioredis/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +53 -19
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -1
- package/packages/datadog-plugin-koa/src/index.js +1 -1
- package/packages/datadog-plugin-mariadb/src/index.js +18 -1
- package/packages/datadog-plugin-memcached/src/index.js +3 -2
- package/packages/datadog-plugin-microgateway-core/src/index.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +13 -9
- package/packages/datadog-plugin-moleculer/src/client.js +1 -1
- package/packages/datadog-plugin-moleculer/src/index.js +1 -1
- package/packages/datadog-plugin-moleculer/src/server.js +1 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +3 -2
- package/packages/datadog-plugin-mysql2/src/index.js +1 -1
- package/packages/datadog-plugin-net/src/index.js +9 -75
- package/packages/datadog-plugin-net/src/ipc.js +1 -1
- package/packages/datadog-plugin-net/src/tcp.js +3 -2
- package/packages/datadog-plugin-next/src/index.js +3 -3
- package/packages/datadog-plugin-opensearch/src/index.js +1 -1
- package/packages/datadog-plugin-oracledb/src/index.js +3 -2
- package/packages/datadog-plugin-paperplane/src/index.js +1 -1
- package/packages/datadog-plugin-paperplane/src/logger.js +1 -1
- package/packages/datadog-plugin-paperplane/src/server.js +1 -1
- package/packages/datadog-plugin-pg/src/index.js +3 -2
- package/packages/datadog-plugin-pino/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +5 -4
- package/packages/datadog-plugin-redis/src/index.js +3 -2
- package/packages/datadog-plugin-restify/src/index.js +1 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
- package/packages/datadog-plugin-rhea/src/index.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +3 -2
- package/packages/datadog-plugin-router/src/index.js +8 -8
- package/packages/datadog-plugin-sharedb/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +3 -2
- package/packages/datadog-plugin-web/src/index.js +1 -1
- package/packages/datadog-plugin-winston/src/index.js +1 -1
- package/packages/dd-trace/src/appsec/gateway/engine/runner.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/iast-log.js +111 -0
- package/packages/dd-trace/src/appsec/iast/index.js +7 -4
- package/packages/dd-trace/src/appsec/iast/path-line.js +3 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +5 -3
- package/packages/dd-trace/src/appsec/iast/telemetry/log_collector.js +96 -0
- package/packages/dd-trace/src/appsec/iast/telemetry/logs.js +87 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +27 -2
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +27 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -9
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -7
- package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/index.js +33 -0
- package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/writer.js +37 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +8 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +8 -2
- package/packages/dd-trace/src/config.js +23 -4
- package/packages/dd-trace/src/constants.js +2 -1
- package/packages/dd-trace/src/datastreams/encoding.js +80 -0
- package/packages/dd-trace/src/exporter.js +7 -9
- package/packages/dd-trace/src/exporters/common/agents.js +42 -0
- package/packages/dd-trace/src/exporters/common/docker.js +4 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -4
- package/packages/dd-trace/src/lambda/handler.js +14 -6
- package/packages/dd-trace/src/opentracing/span.js +5 -0
- package/packages/dd-trace/src/plugin_manager.js +7 -7
- package/packages/dd-trace/src/plugins/ci_plugin.js +16 -16
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/outgoing.js +2 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +12 -0
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +23 -27
- package/packages/dd-trace/src/plugins/util/test.js +26 -7
- package/packages/dd-trace/src/profiling/config.js +87 -20
- package/packages/dd-trace/src/profiling/constants.js +16 -0
- package/packages/dd-trace/src/profiling/exporter_cli.js +62 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +21 -8
- package/packages/dd-trace/src/profiling/profilers/space.js +21 -1
- package/packages/dd-trace/src/span_sampler.js +3 -2
- package/packages/dd-trace/src/telemetry/index.js +16 -2
- package/packages/dd-trace/src/util.js +10 -1
- package/scripts/install_plugin_modules.js +5 -1
- package/scripts/junit_report.js +0 -25
- package/scripts/tdd.js +0 -34
|
@@ -4,8 +4,11 @@ const VULNERABILITIES_KEY = 'vulnerabilities'
|
|
|
4
4
|
const IAST_JSON_TAG_KEY = '_dd.iast.json'
|
|
5
5
|
const VULNERABILITY_HASHES_MAX_SIZE = 1000
|
|
6
6
|
const VULNERABILITY_HASHES = new LRU({ max: VULNERABILITY_HASHES_MAX_SIZE })
|
|
7
|
+
const RESET_VULNERABILITY_CACHE_INTERVAL = 60 * 60 * 1000 // 1 hour
|
|
7
8
|
|
|
8
9
|
let tracer
|
|
10
|
+
let resetVulnerabilityCacheTimer
|
|
11
|
+
let deduplicationEnabled = true
|
|
9
12
|
|
|
10
13
|
function createVulnerability (type, evidence, spanId, location) {
|
|
11
14
|
if (type && evidence) {
|
|
@@ -164,7 +167,20 @@ function clearCache () { // only for test purposes
|
|
|
164
167
|
VULNERABILITY_HASHES.clear()
|
|
165
168
|
}
|
|
166
169
|
|
|
170
|
+
function startClearCacheTimer () {
|
|
171
|
+
resetVulnerabilityCacheTimer = setInterval(clearCache, RESET_VULNERABILITY_CACHE_INTERVAL)
|
|
172
|
+
resetVulnerabilityCacheTimer.unref()
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function stopClearCacheTimer () {
|
|
176
|
+
if (resetVulnerabilityCacheTimer) {
|
|
177
|
+
clearInterval(resetVulnerabilityCacheTimer)
|
|
178
|
+
resetVulnerabilityCacheTimer = null
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
167
182
|
function deduplicateVulnerabilities (vulnerabilities) {
|
|
183
|
+
if (!deduplicationEnabled) return vulnerabilities
|
|
168
184
|
const deduplicated = vulnerabilities.filter((vulnerability) => {
|
|
169
185
|
const key = `${vulnerability.type}${vulnerability.hash}`
|
|
170
186
|
if (!VULNERABILITY_HASHES.get(key)) {
|
|
@@ -176,14 +192,23 @@ function deduplicateVulnerabilities (vulnerabilities) {
|
|
|
176
192
|
return deduplicated
|
|
177
193
|
}
|
|
178
194
|
|
|
179
|
-
function
|
|
195
|
+
function start (config, _tracer) {
|
|
196
|
+
deduplicationEnabled = config.iast.deduplicationEnabled
|
|
197
|
+
if (deduplicationEnabled) {
|
|
198
|
+
startClearCacheTimer()
|
|
199
|
+
}
|
|
180
200
|
tracer = _tracer
|
|
181
201
|
}
|
|
182
202
|
|
|
203
|
+
function stop () {
|
|
204
|
+
stopClearCacheTimer()
|
|
205
|
+
}
|
|
206
|
+
|
|
183
207
|
module.exports = {
|
|
184
208
|
createVulnerability,
|
|
185
209
|
addVulnerability,
|
|
186
210
|
sendVulnerabilities,
|
|
187
211
|
clearCache,
|
|
188
|
-
|
|
212
|
+
start,
|
|
213
|
+
stop
|
|
189
214
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class JSONEncoder {
|
|
4
|
+
constructor () {
|
|
5
|
+
this.payloads = []
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
encode (payload) {
|
|
9
|
+
this.payloads.push(payload)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
count () {
|
|
13
|
+
return this.payloads.length
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
reset () {
|
|
17
|
+
this.payloads = []
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
makePayload () {
|
|
21
|
+
const data = JSON.stringify(this.payloads)
|
|
22
|
+
this.reset()
|
|
23
|
+
return data
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { JSONEncoder }
|
|
@@ -178,23 +178,16 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
178
178
|
this._export(trace)
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
exportCoverage (
|
|
181
|
+
exportCoverage (formattedCoverage) {
|
|
182
182
|
// Until it's initialized, we just store the coverages as is
|
|
183
183
|
if (!this._isInitialized) {
|
|
184
|
-
this._coverageBuffer.push(
|
|
184
|
+
this._coverageBuffer.push(formattedCoverage)
|
|
185
185
|
return
|
|
186
186
|
}
|
|
187
187
|
if (!this.canReportCodeCoverage()) {
|
|
188
188
|
return
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
const { span, coverageFiles } = coveragePayload
|
|
192
|
-
const formattedCoverage = {
|
|
193
|
-
traceId: span.context()._traceId,
|
|
194
|
-
spanId: span.context()._spanId,
|
|
195
|
-
files: coverageFiles
|
|
196
|
-
}
|
|
197
|
-
|
|
198
191
|
this._export(formattedCoverage, this._coverageWriter, '_coverageTimer')
|
|
199
192
|
}
|
|
200
193
|
|
|
@@ -15,18 +15,18 @@ const {
|
|
|
15
15
|
unshallowRepository
|
|
16
16
|
} = require('../../../plugins/util/git')
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const isValidSha1 = (sha) => /^[0-9a-f]{40}$/.test(sha)
|
|
19
|
+
const isValidSha256 = (sha) => /^[0-9a-f]{64}$/.test(sha)
|
|
19
20
|
|
|
20
|
-
function
|
|
21
|
+
function validateCommits (commits) {
|
|
21
22
|
return commits.map(({ id: commitSha, type }) => {
|
|
22
23
|
if (type !== 'commit') {
|
|
23
24
|
throw new Error('Invalid commit type response')
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
throw new Error('Invalid commit format')
|
|
26
|
+
if (isValidSha1(commitSha) || isValidSha256(commitSha)) {
|
|
27
|
+
return commitSha.replace(/[^0-9a-f]+/g, '')
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
throw new Error('Invalid commit format')
|
|
30
30
|
})
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -84,7 +84,7 @@ function getCommitsToExclude ({ url, isEvpProxy, repositoryUrl }, callback) {
|
|
|
84
84
|
}
|
|
85
85
|
let commitsToExclude
|
|
86
86
|
try {
|
|
87
|
-
commitsToExclude =
|
|
87
|
+
commitsToExclude = validateCommits(JSON.parse(response).data)
|
|
88
88
|
} catch (e) {
|
|
89
89
|
return callback(new Error(`Can't parse commits to exclude response: ${e.message}`))
|
|
90
90
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Writer = require('./writer')
|
|
4
|
+
const {
|
|
5
|
+
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
6
|
+
JEST_WORKER_TRACE_PAYLOAD_CODE
|
|
7
|
+
} = require('../../../plugins/util/test')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Lightweight exporter whose writers only do simple JSON serialization
|
|
11
|
+
* of trace and coverage payloads, which they send to the jest main process.
|
|
12
|
+
*/
|
|
13
|
+
class JestWorkerCiVisibilityExporter {
|
|
14
|
+
constructor () {
|
|
15
|
+
this._writer = new Writer(JEST_WORKER_TRACE_PAYLOAD_CODE)
|
|
16
|
+
this._coverageWriter = new Writer(JEST_WORKER_COVERAGE_PAYLOAD_CODE)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export (payload) {
|
|
20
|
+
this._writer.append(payload)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exportCoverage (formattedCoverage) {
|
|
24
|
+
this._coverageWriter.append(formattedCoverage)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
flush () {
|
|
28
|
+
this._writer.flush()
|
|
29
|
+
this._coverageWriter.flush()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = JestWorkerCiVisibilityExporter
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const { JSONEncoder } = require('../../encode/json-encoder')
|
|
3
|
+
|
|
4
|
+
class Writer {
|
|
5
|
+
constructor (interprocessCode) {
|
|
6
|
+
this._encoder = new JSONEncoder()
|
|
7
|
+
// Code used to identify the type of payload being sent to the main process
|
|
8
|
+
this._interprocessCode = interprocessCode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
flush () {
|
|
12
|
+
const count = this._encoder.count()
|
|
13
|
+
|
|
14
|
+
if (count > 0) {
|
|
15
|
+
const payload = this._encoder.makePayload()
|
|
16
|
+
|
|
17
|
+
this._sendPayload(payload)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
append (payload) {
|
|
22
|
+
this._encoder.encode(payload)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_sendPayload (data) {
|
|
26
|
+
// Only available when `child_process` is used for the jest worker.
|
|
27
|
+
// eslint-disable-next-line
|
|
28
|
+
// https://github.com/facebook/jest/blob/bb39cb2c617a3334bf18daeca66bd87b7ccab28b/packages/jest-worker/README.md#experimental-worker
|
|
29
|
+
// If worker_threads is used, this will not work
|
|
30
|
+
// TODO: make it compatible with worker_threads
|
|
31
|
+
if (process.send) { // it only works if process.send is available
|
|
32
|
+
process.send([this._interprocessCode, data])
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = Writer
|
package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js
CHANGED
|
@@ -36,9 +36,15 @@ function getItrConfiguration ({
|
|
|
36
36
|
process.env.DATADOG_APPLICATION_KEY ||
|
|
37
37
|
process.env.DD_APPLICATION_KEY
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const messagePrefix = 'Request to settings endpoint was not done because Datadog'
|
|
40
|
+
|
|
41
|
+
if (!appKey) {
|
|
42
|
+
return done(new Error(`${messagePrefix} application key is not defined.`))
|
|
43
|
+
}
|
|
44
|
+
if (!apiKey) {
|
|
45
|
+
return done(new Error(`${messagePrefix} API key is not defined.`))
|
|
41
46
|
}
|
|
47
|
+
|
|
42
48
|
options.headers['dd-api-key'] = apiKey
|
|
43
49
|
options.headers['dd-application-key'] = appKey
|
|
44
50
|
}
|
|
@@ -35,9 +35,15 @@ function getSkippableSuites ({
|
|
|
35
35
|
process.env.DATADOG_APPLICATION_KEY ||
|
|
36
36
|
process.env.DD_APPLICATION_KEY
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const messagePrefix = 'Skippable suites were not fetched because Datadog'
|
|
39
|
+
|
|
40
|
+
if (!appKey) {
|
|
41
|
+
return done(new Error(`${messagePrefix} application key is not defined.`))
|
|
42
|
+
}
|
|
43
|
+
if (!apiKey) {
|
|
44
|
+
return done(new Error(`${messagePrefix} API key is not defined.`))
|
|
40
45
|
}
|
|
46
|
+
|
|
41
47
|
options.headers['dd-api-key'] = apiKey
|
|
42
48
|
options.headers['dd-application-key'] = appKey
|
|
43
49
|
}
|
|
@@ -158,7 +158,7 @@ class Config {
|
|
|
158
158
|
|
|
159
159
|
const DD_CIVISIBILITY_ITR_ENABLED = coalesce(
|
|
160
160
|
process.env.DD_CIVISIBILITY_ITR_ENABLED,
|
|
161
|
-
|
|
161
|
+
true
|
|
162
162
|
)
|
|
163
163
|
|
|
164
164
|
const DD_SERVICE = options.service ||
|
|
@@ -194,6 +194,10 @@ class Config {
|
|
|
194
194
|
process.env.DD_TRACE_TELEMETRY_ENABLED,
|
|
195
195
|
!process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
196
196
|
)
|
|
197
|
+
const DD_TELEMETRY_DEBUG_ENABLED = coalesce(
|
|
198
|
+
process.env.DD_TELEMETRY_DEBUG_ENABLED,
|
|
199
|
+
false
|
|
200
|
+
)
|
|
197
201
|
const DD_TRACE_AGENT_PROTOCOL_VERSION = coalesce(
|
|
198
202
|
options.protocolVersion,
|
|
199
203
|
process.env.DD_TRACE_AGENT_PROTOCOL_VERSION,
|
|
@@ -349,6 +353,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
349
353
|
process.env.DD_IAST_ENABLED,
|
|
350
354
|
false
|
|
351
355
|
)
|
|
356
|
+
const DD_TELEMETRY_LOG_COLLECTION_ENABLED = coalesce(
|
|
357
|
+
process.env.DD_TELEMETRY_LOG_COLLECTION_ENABLED,
|
|
358
|
+
DD_IAST_ENABLED
|
|
359
|
+
)
|
|
352
360
|
|
|
353
361
|
const defaultIastRequestSampling = 30
|
|
354
362
|
const iastRequestSampling = coalesce(
|
|
@@ -371,6 +379,12 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
371
379
|
2
|
|
372
380
|
)
|
|
373
381
|
|
|
382
|
+
const DD_IAST_DEDUPLICATION_ENABLED = coalesce(
|
|
383
|
+
iastOptions && iastOptions.deduplicationEnabled,
|
|
384
|
+
process.env.DD_IAST_DEDUPLICATION_ENABLED && isTrue(process.env.DD_IAST_DEDUPLICATION_ENABLED),
|
|
385
|
+
true
|
|
386
|
+
)
|
|
387
|
+
|
|
374
388
|
const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
|
|
375
389
|
process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
|
|
376
390
|
true
|
|
@@ -453,7 +467,11 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
453
467
|
this.lookup = options.lookup
|
|
454
468
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
455
469
|
// Disabled for CI Visibility's agentless
|
|
456
|
-
this.
|
|
470
|
+
this.telemetry = {
|
|
471
|
+
enabled: DD_TRACE_EXPORTER !== 'datadog' && isTrue(DD_TRACE_TELEMETRY_ENABLED),
|
|
472
|
+
logCollection: isTrue(DD_TELEMETRY_LOG_COLLECTION_ENABLED),
|
|
473
|
+
debug: isTrue(DD_TELEMETRY_DEBUG_ENABLED)
|
|
474
|
+
}
|
|
457
475
|
this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
|
|
458
476
|
this.tagsHeaderMaxLength = parseInt(DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
|
|
459
477
|
this.appsec = {
|
|
@@ -474,14 +492,15 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
474
492
|
enabled: isTrue(DD_IAST_ENABLED),
|
|
475
493
|
requestSampling: DD_IAST_REQUEST_SAMPLING,
|
|
476
494
|
maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
|
|
477
|
-
maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS
|
|
495
|
+
maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
|
|
496
|
+
deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED
|
|
478
497
|
}
|
|
479
498
|
|
|
480
499
|
this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
|
|
481
500
|
|
|
482
501
|
this.isIntelligentTestRunnerEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_ITR_ENABLED)
|
|
483
502
|
this.isGitUploadEnabled = this.isCiVisibility &&
|
|
484
|
-
(this.isIntelligentTestRunnerEnabled
|
|
503
|
+
(this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
|
|
485
504
|
|
|
486
505
|
this.stats = {
|
|
487
506
|
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// encodes positive and negative numbers, using zig zag encoding to reduce the size of the variable length encoding.
|
|
2
|
+
// uses high and low part to ensure those parts are under the limit for byte operations in javascript (32 bits)
|
|
3
|
+
// maximum number possible to encode is MAX_SAFE_INTEGER/2 (using zig zag shifts the bits by 1 to the left)
|
|
4
|
+
function encodeVarint (v) {
|
|
5
|
+
const sign = v >= 0 ? 0 : 1
|
|
6
|
+
// we leave the least significant bit for the sign.
|
|
7
|
+
const double = Math.abs(v) * 2
|
|
8
|
+
if (double > Number.MAX_SAFE_INTEGER) {
|
|
9
|
+
return undefined
|
|
10
|
+
}
|
|
11
|
+
const high = Math.floor(double / 0x100000000)
|
|
12
|
+
const low = (double & 0xffffffff) | sign
|
|
13
|
+
return encodeUvarint64(low, high)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// decodes positive and negative numbers, using zig zag encoding to reduce the size of the variable length encoding.
|
|
17
|
+
// uses high and low part to ensure those parts are under the limit for byte operations in javascript (32 bits)
|
|
18
|
+
function decodeVarint (b) {
|
|
19
|
+
const [low, high] = decodeUvarint64(b)
|
|
20
|
+
if (low === undefined || high === undefined) {
|
|
21
|
+
return undefined
|
|
22
|
+
}
|
|
23
|
+
const positive = (low & 1) === 0
|
|
24
|
+
const abs = (low >>> 1) + high * 0x80000000
|
|
25
|
+
return positive ? abs : -abs
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const maxVarLen64 = 9
|
|
29
|
+
|
|
30
|
+
function encodeUvarint64 (low, high) {
|
|
31
|
+
const result = new Uint8Array(maxVarLen64)
|
|
32
|
+
let i = 0
|
|
33
|
+
// if first byte is 1, the number is negative in javascript, but we want to interpret it as positive
|
|
34
|
+
while ((high !== 0 || low < 0 || low > 0x80) && i < maxVarLen64 - 1) {
|
|
35
|
+
result[i] = (low & 0x7f) | 0x80
|
|
36
|
+
low >>>= 7
|
|
37
|
+
low |= (high & 0x7f) << 25
|
|
38
|
+
high >>>= 7
|
|
39
|
+
i++
|
|
40
|
+
}
|
|
41
|
+
result[i] = low & 0x7f
|
|
42
|
+
return result.slice(0, i + 1)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function decodeUvarint64 (
|
|
46
|
+
bytes
|
|
47
|
+
) {
|
|
48
|
+
let low = 0
|
|
49
|
+
let high = 0
|
|
50
|
+
let s = 0
|
|
51
|
+
for (let i = 0; ; i++) {
|
|
52
|
+
if (bytes.length <= i) {
|
|
53
|
+
return [undefined, undefined]
|
|
54
|
+
}
|
|
55
|
+
const n = bytes[i]
|
|
56
|
+
if (n < 0x80 || i === maxVarLen64 - 1) {
|
|
57
|
+
bytes = bytes.slice(i + 1)
|
|
58
|
+
if (s < 32) {
|
|
59
|
+
low |= n << s
|
|
60
|
+
}
|
|
61
|
+
if (s > 0) {
|
|
62
|
+
high |= s - 32 > 0 ? n << (s - 32) : n >> (32 - s)
|
|
63
|
+
}
|
|
64
|
+
return [low, high]
|
|
65
|
+
}
|
|
66
|
+
if (s < 32) {
|
|
67
|
+
low |= (n & 0x7f) << s
|
|
68
|
+
}
|
|
69
|
+
if (s > 0) {
|
|
70
|
+
high |=
|
|
71
|
+
s - 32 > 0 ? (n & 0x7f) << (s - 32) : (n & 0x7f) >> (32 - s)
|
|
72
|
+
}
|
|
73
|
+
s += 7
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
encodeVarint,
|
|
79
|
+
decodeVarint
|
|
80
|
+
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const AgentExporter = require('./exporters/agent')
|
|
4
|
-
const LogExporter = require('./exporters/log')
|
|
5
|
-
const AgentlessCiVisibilityExporter = require('./ci-visibility/exporters/agentless')
|
|
6
|
-
const AgentProxyCiVisibilityExporter = require('./ci-visibility/exporters/agent-proxy')
|
|
7
3
|
const exporters = require('../../../ext/exporters')
|
|
8
4
|
const fs = require('fs')
|
|
9
5
|
const constants = require('./constants')
|
|
@@ -14,14 +10,16 @@ module.exports = name => {
|
|
|
14
10
|
|
|
15
11
|
switch (name) {
|
|
16
12
|
case exporters.LOG:
|
|
17
|
-
return
|
|
13
|
+
return require('./exporters/log')
|
|
18
14
|
case exporters.AGENT:
|
|
19
|
-
return
|
|
15
|
+
return require('./exporters/agent')
|
|
20
16
|
case exporters.DATADOG:
|
|
21
|
-
return
|
|
17
|
+
return require('./ci-visibility/exporters/agentless')
|
|
22
18
|
case exporters.AGENT_PROXY:
|
|
23
|
-
return
|
|
19
|
+
return require('./ci-visibility/exporters/agent-proxy')
|
|
20
|
+
case exporters.JEST_WORKER:
|
|
21
|
+
return require('./ci-visibility/exporters/jest-worker')
|
|
24
22
|
default:
|
|
25
|
-
return inAWSLambda && !usingLambdaExtension ?
|
|
23
|
+
return inAWSLambda && !usingLambdaExtension ? require('./exporters/log') : require('./exporters/agent')
|
|
26
24
|
}
|
|
27
25
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const http = require('http')
|
|
4
|
+
const https = require('https')
|
|
5
|
+
const { storage } = require('../../../../datadog-core')
|
|
6
|
+
|
|
7
|
+
const keepAlive = true
|
|
8
|
+
const maxSockets = 1
|
|
9
|
+
|
|
10
|
+
function createAgentClass (BaseAgent) {
|
|
11
|
+
class CustomAgent extends BaseAgent {
|
|
12
|
+
constructor () {
|
|
13
|
+
super({ keepAlive, maxSockets })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createConnection (...args) {
|
|
17
|
+
return this._noop(() => super.createConnection(...args))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
keepSocketAlive (...args) {
|
|
21
|
+
return this._noop(() => super.keepSocketAlive(...args))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
reuseSocket (...args) {
|
|
25
|
+
return this._noop(() => super.reuseSocket(...args))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_noop (callback) {
|
|
29
|
+
return storage.run({ noop: true }, callback)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return CustomAgent
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const HttpAgent = createAgentClass(http.Agent)
|
|
37
|
+
const HttpsAgent = createAgentClass(https.Agent)
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
httpAgent: new HttpAgent(),
|
|
41
|
+
HttpsAgent: new HttpsAgent()
|
|
42
|
+
}
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// The second part is the PCF / Garden regexp. We currently assume no suffix($) to avoid matching pod UIDs
|
|
6
|
+
// See https://github.com/DataDog/datadog-agent/blob/7.40.x/pkg/util/cgroups/reader.go#L50
|
|
7
|
+
const uuidSource =
|
|
8
|
+
'[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}|[0-9a-f]{8}(?:-[0-9a-f]{4}){4}$'
|
|
6
9
|
const containerSource = '[0-9a-f]{64}'
|
|
7
10
|
const taskSource = '[0-9a-f]{32}-\\d+'
|
|
8
11
|
const entityReg = new RegExp(`.*(${uuidSource}|${containerSource}|${taskSource})(?:\\.scope)?$`, 'm')
|
|
@@ -8,14 +8,11 @@ const http = require('http')
|
|
|
8
8
|
const https = require('https')
|
|
9
9
|
const { parse: urlParse } = require('url')
|
|
10
10
|
const docker = require('./docker')
|
|
11
|
+
const { httpAgent, httpsAgent } = require('./agents')
|
|
11
12
|
const { storage } = require('../../../../datadog-core')
|
|
12
13
|
const log = require('../../log')
|
|
13
14
|
|
|
14
|
-
const keepAlive = true
|
|
15
|
-
const maxSockets = 1
|
|
16
15
|
const maxActiveRequests = 8
|
|
17
|
-
const httpAgent = new http.Agent({ keepAlive, maxSockets })
|
|
18
|
-
const httpsAgent = new https.Agent({ keepAlive, maxSockets })
|
|
19
16
|
const containerId = docker.id()
|
|
20
17
|
|
|
21
18
|
let activeRequests = 0
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const log = require('../log')
|
|
3
4
|
const { channel } = require('../../../datadog-instrumentations/src/helpers/instrument')
|
|
4
5
|
const { ERROR_MESSAGE, ERROR_TYPE } = require('../constants')
|
|
5
6
|
const { ImpendingTimeout } = require('./runtime/errors')
|
|
@@ -42,13 +43,20 @@ function checkTimeout (context) {
|
|
|
42
43
|
*/
|
|
43
44
|
function crashFlush () {
|
|
44
45
|
const activeSpan = tracer.scope().active()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
if (activeSpan !== null) {
|
|
47
|
+
const error = new ImpendingTimeout('Datadog detected an impending timeout')
|
|
48
|
+
activeSpan.addTags({
|
|
49
|
+
[ERROR_MESSAGE]: error.message,
|
|
50
|
+
[ERROR_TYPE]: error.name
|
|
51
|
+
})
|
|
52
|
+
} else {
|
|
53
|
+
log.warn('An impending timeout was reached, but no root span was found. No error will be tagged.')
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
tracer._processor.killAll()
|
|
51
|
-
activeSpan
|
|
57
|
+
if (activeSpan !== null) {
|
|
58
|
+
activeSpan.finish()
|
|
59
|
+
}
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
/**
|
|
@@ -32,6 +32,11 @@ class DatadogSpan {
|
|
|
32
32
|
this._processor = processor
|
|
33
33
|
this._prioritySampler = prioritySampler
|
|
34
34
|
this._store = storage.getStore()
|
|
35
|
+
this._duration = undefined
|
|
36
|
+
|
|
37
|
+
// For internal use only. You probably want `context()._name`.
|
|
38
|
+
// This name property is not updated when the span name changes.
|
|
39
|
+
// This is necessary for span count metrics.
|
|
35
40
|
this._name = operationName
|
|
36
41
|
|
|
37
42
|
this._spanContext = this._createContext(parent)
|
|
@@ -28,17 +28,17 @@ loadChannel.subscribe(({ name }) => {
|
|
|
28
28
|
const Plugin = plugins[name]
|
|
29
29
|
|
|
30
30
|
if (!Plugin || typeof Plugin !== 'function') return
|
|
31
|
-
if (!pluginClasses[Plugin.
|
|
32
|
-
const envName = `DD_TRACE_${Plugin.
|
|
31
|
+
if (!pluginClasses[Plugin.id]) {
|
|
32
|
+
const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
|
|
33
33
|
const enabled = process.env[envName.replace(/[^a-z0-9_]/ig, '_')]
|
|
34
34
|
|
|
35
35
|
// TODO: remove the need to load the plugin class in order to disable the plugin
|
|
36
|
-
if (isFalse(enabled) || disabledPlugins.has(Plugin.
|
|
37
|
-
log.debug(`Plugin "${Plugin.
|
|
36
|
+
if (isFalse(enabled) || disabledPlugins.has(Plugin.id)) {
|
|
37
|
+
log.debug(`Plugin "${Plugin.id}" was disabled via configuration option.`)
|
|
38
38
|
|
|
39
|
-
pluginClasses[Plugin.
|
|
39
|
+
pluginClasses[Plugin.id] = null
|
|
40
40
|
} else {
|
|
41
|
-
pluginClasses[Plugin.
|
|
41
|
+
pluginClasses[Plugin.id] = Plugin
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
})
|
|
@@ -56,7 +56,7 @@ module.exports = class PluginManager {
|
|
|
56
56
|
|
|
57
57
|
if (!Plugin || typeof Plugin !== 'function') return
|
|
58
58
|
|
|
59
|
-
this.loadPlugin(Plugin.
|
|
59
|
+
this.loadPlugin(Plugin.id)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
loadChannel.subscribe(this._loadedSubscriber)
|