dd-trace 5.24.0 → 5.25.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 -0
- package/index.d.ts +335 -0
- package/package.json +13 -7
- package/packages/datadog-code-origin/index.js +4 -4
- package/packages/datadog-core/src/utils/src/parse-tags.js +33 -0
- package/packages/datadog-esbuild/index.js +4 -2
- package/packages/datadog-instrumentations/src/amqplib.js +65 -5
- package/packages/datadog-instrumentations/src/child_process.js +135 -27
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +9 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +123 -63
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -2
- package/packages/datadog-instrumentations/src/multer.js +37 -0
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/url.js +84 -0
- package/packages/datadog-instrumentations/src/utils/src/extract-package-and-module-path.js +7 -4
- package/packages/datadog-plugin-amqplib/src/consumer.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-fastify/src/code_origin.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +8 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +8 -0
- package/packages/datadog-plugin-grpc/src/client.js +3 -0
- package/packages/datadog-plugin-grpc/src/server.js +3 -0
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +6 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -4
- package/packages/datadog-plugin-kafkajs/src/producer.js +10 -4
- package/packages/datadog-plugin-mocha/src/index.js +4 -1
- package/packages/datadog-plugin-openai/src/index.js +9 -1015
- package/packages/datadog-plugin-openai/src/tracing.js +1023 -0
- package/packages/dd-trace/src/appsec/addresses.js +2 -0
- package/packages/dd-trace/src/appsec/channels.js +3 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +55 -7
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -2
- package/packages/dd-trace/src/appsec/index.js +3 -0
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +49 -0
- package/packages/dd-trace/src/appsec/rasp/index.js +3 -0
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +4 -3
- package/packages/dd-trace/src/appsec/rasp/utils.js +3 -2
- package/packages/dd-trace/src/appsec/recommended.json +2 -4
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +1 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +2 -0
- package/packages/dd-trace/src/appsec/reporter.js +5 -4
- package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -3
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +4 -0
- package/packages/dd-trace/src/azure_metadata.js +120 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +97 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +90 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +19 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +53 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +8 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +43 -0
- package/packages/dd-trace/src/config.js +75 -6
- package/packages/dd-trace/src/constants.js +3 -1
- package/packages/dd-trace/src/datastreams/pathway.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +9 -13
- package/packages/dd-trace/src/debugger/devtools_client/send.js +15 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +57 -23
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +12 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +31 -20
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +6 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +11 -2
- package/packages/dd-trace/src/debugger/index.js +10 -3
- package/packages/dd-trace/src/llmobs/constants/tags.js +34 -0
- package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
- package/packages/dd-trace/src/llmobs/constants/writers.js +13 -0
- package/packages/dd-trace/src/llmobs/index.js +103 -0
- package/packages/dd-trace/src/llmobs/noop.js +82 -0
- package/packages/dd-trace/src/llmobs/plugins/base.js +65 -0
- package/packages/dd-trace/src/llmobs/plugins/openai.js +205 -0
- package/packages/dd-trace/src/llmobs/sdk.js +377 -0
- package/packages/dd-trace/src/llmobs/span_processor.js +195 -0
- package/packages/dd-trace/src/llmobs/storage.js +7 -0
- package/packages/dd-trace/src/llmobs/tagger.js +322 -0
- package/packages/dd-trace/src/llmobs/util.js +176 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +111 -0
- package/packages/dd-trace/src/llmobs/writers/evaluations.js +29 -0
- package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +23 -0
- package/packages/dd-trace/src/llmobs/writers/spans/agentless.js +17 -0
- package/packages/dd-trace/src/llmobs/writers/spans/base.js +49 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -0
- package/packages/dd-trace/src/noop/span.js +3 -0
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +73 -12
- package/packages/dd-trace/src/opentracing/span.js +12 -0
- package/packages/dd-trace/src/opentracing/tracer.js +8 -1
- package/packages/dd-trace/src/payload-tagging/config/aws.json +71 -3
- package/packages/dd-trace/src/plugins/outbound.js +9 -0
- package/packages/dd-trace/src/priority_sampler.js +16 -0
- package/packages/dd-trace/src/profiling/config.js +3 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +7 -5
- package/packages/dd-trace/src/profiling/profilers/wall.js +2 -1
- package/packages/dd-trace/src/proxy.js +8 -1
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/telemetry/index.js +11 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { workerData: { breakpointSetChannel, breakpointHitChannel } } = require('worker_threads')
|
|
4
|
+
// TODO: move debugger/devtools_client/session to common place
|
|
5
|
+
const session = require('../../../debugger/devtools_client/session')
|
|
6
|
+
// TODO: move debugger/devtools_client/snapshot to common place
|
|
7
|
+
const { getLocalStateForCallFrame } = require('../../../debugger/devtools_client/snapshot')
|
|
8
|
+
// TODO: move debugger/devtools_client/state to common place
|
|
9
|
+
const {
|
|
10
|
+
findScriptFromPartialPath,
|
|
11
|
+
getStackFromCallFrames
|
|
12
|
+
} = require('../../../debugger/devtools_client/state')
|
|
13
|
+
const log = require('../../../log')
|
|
14
|
+
|
|
15
|
+
let sessionStarted = false
|
|
16
|
+
|
|
17
|
+
const breakpointIdToSnapshotId = new Map()
|
|
18
|
+
const breakpointIdToProbe = new Map()
|
|
19
|
+
|
|
20
|
+
session.on('Debugger.paused', async ({ params: { hitBreakpoints: [hitBreakpoint], callFrames } }) => {
|
|
21
|
+
const probe = breakpointIdToProbe.get(hitBreakpoint)
|
|
22
|
+
if (!probe) {
|
|
23
|
+
log.warn(`No probe found for breakpoint ${hitBreakpoint}`)
|
|
24
|
+
return session.post('Debugger.resume')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const stack = getStackFromCallFrames(callFrames)
|
|
28
|
+
|
|
29
|
+
const getLocalState = await getLocalStateForCallFrame(callFrames[0])
|
|
30
|
+
|
|
31
|
+
await session.post('Debugger.resume')
|
|
32
|
+
|
|
33
|
+
const snapshotId = breakpointIdToSnapshotId.get(hitBreakpoint)
|
|
34
|
+
|
|
35
|
+
const snapshot = {
|
|
36
|
+
id: snapshotId,
|
|
37
|
+
timestamp: Date.now(),
|
|
38
|
+
probe: {
|
|
39
|
+
id: probe.probeId,
|
|
40
|
+
version: '0',
|
|
41
|
+
location: probe.location
|
|
42
|
+
},
|
|
43
|
+
stack,
|
|
44
|
+
language: 'javascript'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const state = getLocalState()
|
|
48
|
+
if (state) {
|
|
49
|
+
snapshot.captures = {
|
|
50
|
+
lines: { [probe.location.lines[0]]: { locals: state } }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
breakpointHitChannel.postMessage({ snapshot })
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// TODO: add option to remove breakpoint
|
|
58
|
+
breakpointSetChannel.on('message', async ({ snapshotId, probe: { id: probeId, file, line } }) => {
|
|
59
|
+
await addBreakpoint(snapshotId, { probeId, file, line })
|
|
60
|
+
breakpointSetChannel.postMessage({ probeId })
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
async function addBreakpoint (snapshotId, probe) {
|
|
64
|
+
if (!sessionStarted) await start()
|
|
65
|
+
const { file, line } = probe
|
|
66
|
+
|
|
67
|
+
probe.location = { file, lines: [String(line)] }
|
|
68
|
+
|
|
69
|
+
const script = findScriptFromPartialPath(file)
|
|
70
|
+
if (!script) throw new Error(`No loaded script found for ${file}`)
|
|
71
|
+
|
|
72
|
+
const [path, scriptId] = script
|
|
73
|
+
|
|
74
|
+
log.debug(`Adding breakpoint at ${path}:${line}`)
|
|
75
|
+
|
|
76
|
+
const { breakpointId } = await session.post('Debugger.setBreakpoint', {
|
|
77
|
+
location: {
|
|
78
|
+
scriptId,
|
|
79
|
+
lineNumber: line - 1
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
breakpointIdToProbe.set(breakpointId, probe)
|
|
84
|
+
breakpointIdToSnapshotId.set(breakpointId, snapshotId)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function start () {
|
|
88
|
+
sessionStarted = true
|
|
89
|
+
return session.post('Debugger.enable') // return instead of await to reduce number of promises created
|
|
90
|
+
}
|
|
@@ -7,6 +7,7 @@ const CiVisibilityExporter = require('../ci-visibility-exporter')
|
|
|
7
7
|
|
|
8
8
|
const AGENT_EVP_PROXY_PATH_PREFIX = '/evp_proxy/v'
|
|
9
9
|
const AGENT_EVP_PROXY_PATH_REGEX = /\/evp_proxy\/v(\d+)\/?/
|
|
10
|
+
const AGENT_DEBUGGER_INPUT = '/debugger/v1/input'
|
|
10
11
|
|
|
11
12
|
function getLatestEvpProxyVersion (err, agentInfo) {
|
|
12
13
|
if (err) {
|
|
@@ -24,6 +25,10 @@ function getLatestEvpProxyVersion (err, agentInfo) {
|
|
|
24
25
|
}, 0)
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
function getCanForwardDebuggerLogs (err, agentInfo) {
|
|
29
|
+
return !err && agentInfo.endpoints.some(endpoint => endpoint === AGENT_DEBUGGER_INPUT)
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
28
33
|
constructor (config) {
|
|
29
34
|
super(config)
|
|
@@ -33,7 +38,8 @@ class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
33
38
|
prioritySampler,
|
|
34
39
|
lookup,
|
|
35
40
|
protocolVersion,
|
|
36
|
-
headers
|
|
41
|
+
headers,
|
|
42
|
+
isTestDynamicInstrumentationEnabled
|
|
37
43
|
} = config
|
|
38
44
|
|
|
39
45
|
this.getAgentInfo((err, agentInfo) => {
|
|
@@ -60,6 +66,18 @@ class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
60
66
|
url: this._url,
|
|
61
67
|
evpProxyPrefix
|
|
62
68
|
})
|
|
69
|
+
if (isTestDynamicInstrumentationEnabled) {
|
|
70
|
+
const canFowardLogs = getCanForwardDebuggerLogs(err, agentInfo)
|
|
71
|
+
if (canFowardLogs) {
|
|
72
|
+
const DynamicInstrumentationLogsWriter = require('../agentless/di-logs-writer')
|
|
73
|
+
this._logsWriter = new DynamicInstrumentationLogsWriter({
|
|
74
|
+
url: this._url,
|
|
75
|
+
tags,
|
|
76
|
+
isAgentProxy: true
|
|
77
|
+
})
|
|
78
|
+
this._canForwardLogs = true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
63
81
|
} else {
|
|
64
82
|
this._writer = new AgentWriter({
|
|
65
83
|
url: this._url,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const request = require('../../../exporters/common/request')
|
|
3
|
+
const log = require('../../../log')
|
|
4
|
+
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
5
|
+
const { JSONEncoder } = require('../../encode/json-encoder')
|
|
6
|
+
|
|
7
|
+
const BaseWriter = require('../../../exporters/common/writer')
|
|
8
|
+
|
|
9
|
+
// Writer used by the integration between Dynamic Instrumentation and Test Visibility
|
|
10
|
+
// It is used to encode and send logs to both the logs intake directly and the
|
|
11
|
+
// `/debugger/v1/input` endpoint in the agent, which is a proxy to the logs intake.
|
|
12
|
+
class DynamicInstrumentationLogsWriter extends BaseWriter {
|
|
13
|
+
constructor ({ url, timeout, isAgentProxy = false }) {
|
|
14
|
+
super(...arguments)
|
|
15
|
+
this._url = url
|
|
16
|
+
this._encoder = new JSONEncoder()
|
|
17
|
+
this._isAgentProxy = isAgentProxy
|
|
18
|
+
this.timeout = timeout
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_sendPayload (data, _, done) {
|
|
22
|
+
const options = {
|
|
23
|
+
path: '/api/v2/logs',
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers: {
|
|
26
|
+
'dd-api-key': process.env.DATADOG_API_KEY || process.env.DD_API_KEY,
|
|
27
|
+
'Content-Type': 'application/json'
|
|
28
|
+
},
|
|
29
|
+
// TODO: what's a good value for timeout for the logs intake?
|
|
30
|
+
timeout: this.timeout || 15000,
|
|
31
|
+
url: this._url
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (this._isAgentProxy) {
|
|
35
|
+
delete options.headers['dd-api-key']
|
|
36
|
+
options.path = '/debugger/v1/input'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
log.debug(() => `Request to the logs intake: ${safeJSONStringify(options)}`)
|
|
40
|
+
|
|
41
|
+
request(data, options, (err, res) => {
|
|
42
|
+
if (err) {
|
|
43
|
+
log.error(err)
|
|
44
|
+
done()
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
log.debug(`Response from the logs intake: ${res}`)
|
|
48
|
+
done()
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = DynamicInstrumentationLogsWriter
|
|
@@ -9,10 +9,11 @@ const log = require('../../../log')
|
|
|
9
9
|
class AgentlessCiVisibilityExporter extends CiVisibilityExporter {
|
|
10
10
|
constructor (config) {
|
|
11
11
|
super(config)
|
|
12
|
-
const { tags, site, url } = config
|
|
12
|
+
const { tags, site, url, isTestDynamicInstrumentationEnabled } = config
|
|
13
13
|
// we don't need to request /info because we are using agentless by configuration
|
|
14
14
|
this._isInitialized = true
|
|
15
15
|
this._resolveCanUseCiVisProtocol(true)
|
|
16
|
+
this._canForwardLogs = true
|
|
16
17
|
|
|
17
18
|
this._url = url || new URL(`https://citestcycle-intake.${site}`)
|
|
18
19
|
this._writer = new Writer({ url: this._url, tags })
|
|
@@ -20,6 +21,12 @@ class AgentlessCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
20
21
|
this._coverageUrl = url || new URL(`https://citestcov-intake.${site}`)
|
|
21
22
|
this._coverageWriter = new CoverageWriter({ url: this._coverageUrl })
|
|
22
23
|
|
|
24
|
+
if (isTestDynamicInstrumentationEnabled) {
|
|
25
|
+
const DynamicInstrumentationLogsWriter = require('./di-logs-writer')
|
|
26
|
+
this._logsUrl = url || new URL(`https://http-intake.logs.${site}`)
|
|
27
|
+
this._logsWriter = new DynamicInstrumentationLogsWriter({ url: this._logsUrl, tags })
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
this._apiUrl = url || new URL(`https://api.${site}`)
|
|
24
31
|
// Agentless is always gzip compatible
|
|
25
32
|
this._isGzipCompatible = true
|
|
@@ -8,6 +8,7 @@ const { getSkippableSuites: getSkippableSuitesRequest } = require('../intelligen
|
|
|
8
8
|
const { getKnownTests: getKnownTestsRequest } = require('../early-flake-detection/get-known-tests')
|
|
9
9
|
const log = require('../../log')
|
|
10
10
|
const AgentInfoExporter = require('../../exporters/common/agent-info-exporter')
|
|
11
|
+
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../../plugins/util/tags')
|
|
11
12
|
|
|
12
13
|
function getTestConfigurationTags (tags) {
|
|
13
14
|
if (!tags) {
|
|
@@ -36,6 +37,7 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
36
37
|
super(config)
|
|
37
38
|
this._timer = undefined
|
|
38
39
|
this._coverageTimer = undefined
|
|
40
|
+
this._logsTimer = undefined
|
|
39
41
|
this._coverageBuffer = []
|
|
40
42
|
// The library can use new features like ITR and test suite level visibility
|
|
41
43
|
// AKA CI Vis Protocol
|
|
@@ -255,6 +257,47 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
255
257
|
this._export(formattedCoverage, this._coverageWriter, '_coverageTimer')
|
|
256
258
|
}
|
|
257
259
|
|
|
260
|
+
formatLogMessage (testConfiguration, logMessage) {
|
|
261
|
+
const {
|
|
262
|
+
[GIT_REPOSITORY_URL]: gitRepositoryUrl,
|
|
263
|
+
[GIT_COMMIT_SHA]: gitCommitSha
|
|
264
|
+
} = testConfiguration
|
|
265
|
+
|
|
266
|
+
const { service, env, version } = this._config
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
ddtags: [
|
|
270
|
+
...(logMessage.ddtags || []),
|
|
271
|
+
`${GIT_REPOSITORY_URL}:${gitRepositoryUrl}`,
|
|
272
|
+
`${GIT_COMMIT_SHA}:${gitCommitSha}`
|
|
273
|
+
].join(','),
|
|
274
|
+
level: 'error',
|
|
275
|
+
service,
|
|
276
|
+
dd: {
|
|
277
|
+
...(logMessage.dd || []),
|
|
278
|
+
service,
|
|
279
|
+
env,
|
|
280
|
+
version
|
|
281
|
+
},
|
|
282
|
+
ddsource: 'dd_debugger',
|
|
283
|
+
...logMessage
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// DI logs
|
|
288
|
+
exportDiLogs (testConfiguration, logMessage) {
|
|
289
|
+
// TODO: could we lose logs if it's not initialized?
|
|
290
|
+
if (!this._config.isTestDynamicInstrumentationEnabled || !this._isInitialized || !this._canForwardLogs) {
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
this._export(
|
|
295
|
+
this.formatLogMessage(testConfiguration, logMessage),
|
|
296
|
+
this._logsWriter,
|
|
297
|
+
'_logsTimer'
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
258
301
|
flush (done = () => {}) {
|
|
259
302
|
if (!this._isInitialized) {
|
|
260
303
|
return done()
|
|
@@ -17,7 +17,7 @@ const { getGitMetadataFromGitProperties, removeUserSensitiveInfo } = require('./
|
|
|
17
17
|
const { updateConfig } = require('./telemetry')
|
|
18
18
|
const telemetryMetrics = require('./telemetry/metrics')
|
|
19
19
|
const { getIsGCPFunction, getIsAzureFunction } = require('./serverless')
|
|
20
|
-
const { ORIGIN_KEY } = require('./constants')
|
|
20
|
+
const { ORIGIN_KEY, GRPC_CLIENT_ERROR_STATUSES, GRPC_SERVER_ERROR_STATUSES } = require('./constants')
|
|
21
21
|
const { appendRules } = require('./payload-tagging/config')
|
|
22
22
|
|
|
23
23
|
const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
|
|
@@ -462,6 +462,9 @@ class Config {
|
|
|
462
462
|
this._setValue(defaults, 'appsec.stackTrace.maxDepth', 32)
|
|
463
463
|
this._setValue(defaults, 'appsec.stackTrace.maxStackTraces', 2)
|
|
464
464
|
this._setValue(defaults, 'appsec.wafTimeout', 5e3) // µs
|
|
465
|
+
this._setValue(defaults, 'baggageMaxBytes', 8192)
|
|
466
|
+
this._setValue(defaults, 'baggageMaxItems', 64)
|
|
467
|
+
this._setValue(defaults, 'ciVisibilityTestSessionName', '')
|
|
465
468
|
this._setValue(defaults, 'clientIpEnabled', false)
|
|
466
469
|
this._setValue(defaults, 'clientIpHeader', null)
|
|
467
470
|
this._setValue(defaults, 'codeOriginForSpans.enabled', false)
|
|
@@ -477,6 +480,8 @@ class Config {
|
|
|
477
480
|
this._setValue(defaults, 'flushInterval', 2000)
|
|
478
481
|
this._setValue(defaults, 'flushMinSpans', 1000)
|
|
479
482
|
this._setValue(defaults, 'gitMetadataEnabled', true)
|
|
483
|
+
this._setValue(defaults, 'grpc.client.error.statuses', GRPC_CLIENT_ERROR_STATUSES)
|
|
484
|
+
this._setValue(defaults, 'grpc.server.error.statuses', GRPC_SERVER_ERROR_STATUSES)
|
|
480
485
|
this._setValue(defaults, 'headerTags', [])
|
|
481
486
|
this._setValue(defaults, 'hostname', '127.0.0.1')
|
|
482
487
|
this._setValue(defaults, 'iast.cookieFilterPattern', '.{32,}')
|
|
@@ -499,8 +504,13 @@ class Config {
|
|
|
499
504
|
this._setValue(defaults, 'isGitUploadEnabled', false)
|
|
500
505
|
this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
|
|
501
506
|
this._setValue(defaults, 'isManualApiEnabled', false)
|
|
507
|
+
this._setValue(defaults, 'llmobs.agentlessEnabled', false)
|
|
508
|
+
this._setValue(defaults, 'llmobs.enabled', false)
|
|
509
|
+
this._setValue(defaults, 'llmobs.mlApp', undefined)
|
|
502
510
|
this._setValue(defaults, 'ciVisibilityTestSessionName', '')
|
|
503
511
|
this._setValue(defaults, 'ciVisAgentlessLogSubmissionEnabled', false)
|
|
512
|
+
this._setValue(defaults, 'legacyBaggageEnabled', true)
|
|
513
|
+
this._setValue(defaults, 'isTestDynamicInstrumentationEnabled', false)
|
|
504
514
|
this._setValue(defaults, 'logInjection', false)
|
|
505
515
|
this._setValue(defaults, 'lookup', undefined)
|
|
506
516
|
this._setValue(defaults, 'memcachedCommandEnabled', false)
|
|
@@ -520,7 +530,7 @@ class Config {
|
|
|
520
530
|
this._setValue(defaults, 'reportHostname', false)
|
|
521
531
|
this._setValue(defaults, 'runtimeMetrics', false)
|
|
522
532
|
this._setValue(defaults, 'sampleRate', undefined)
|
|
523
|
-
this._setValue(defaults, 'sampler.rateLimit',
|
|
533
|
+
this._setValue(defaults, 'sampler.rateLimit', 100)
|
|
524
534
|
this._setValue(defaults, 'sampler.rules', [])
|
|
525
535
|
this._setValue(defaults, 'sampler.spanSamplingRules', [])
|
|
526
536
|
this._setValue(defaults, 'scope', undefined)
|
|
@@ -541,11 +551,12 @@ class Config {
|
|
|
541
551
|
this._setValue(defaults, 'telemetry.heartbeatInterval', 60000)
|
|
542
552
|
this._setValue(defaults, 'telemetry.logCollection', false)
|
|
543
553
|
this._setValue(defaults, 'telemetry.metrics', true)
|
|
554
|
+
this._setValue(defaults, 'traceEnabled', true)
|
|
544
555
|
this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
|
|
545
556
|
this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
|
|
546
557
|
this._setValue(defaults, 'tracePropagationExtractFirst', false)
|
|
547
|
-
this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext'])
|
|
548
|
-
this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext'])
|
|
558
|
+
this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext', 'baggage'])
|
|
559
|
+
this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext', 'baggage'])
|
|
549
560
|
this._setValue(defaults, 'tracePropagationStyle.otelPropagators', false)
|
|
550
561
|
this._setValue(defaults, 'tracing', true)
|
|
551
562
|
this._setValue(defaults, 'url', undefined)
|
|
@@ -584,6 +595,8 @@ class Config {
|
|
|
584
595
|
DD_EXPERIMENTAL_API_SECURITY_ENABLED,
|
|
585
596
|
DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,
|
|
586
597
|
DD_EXPERIMENTAL_PROFILING_ENABLED,
|
|
598
|
+
DD_GRPC_CLIENT_ERROR_STATUSES,
|
|
599
|
+
DD_GRPC_SERVER_ERROR_STATUSES,
|
|
587
600
|
JEST_WORKER_ID,
|
|
588
601
|
DD_IAST_COOKIE_FILTER_PATTERN,
|
|
589
602
|
DD_IAST_DEDUPLICATION_ENABLED,
|
|
@@ -599,6 +612,9 @@ class Config {
|
|
|
599
612
|
DD_INSTRUMENTATION_TELEMETRY_ENABLED,
|
|
600
613
|
DD_INSTRUMENTATION_CONFIG_ID,
|
|
601
614
|
DD_LOGS_INJECTION,
|
|
615
|
+
DD_LLMOBS_AGENTLESS_ENABLED,
|
|
616
|
+
DD_LLMOBS_ENABLED,
|
|
617
|
+
DD_LLMOBS_ML_APP,
|
|
602
618
|
DD_OPENAI_LOGS_ENABLED,
|
|
603
619
|
DD_OPENAI_SPAN_CHAR_LIMIT,
|
|
604
620
|
DD_PROFILING_ENABLED,
|
|
@@ -625,14 +641,18 @@ class Config {
|
|
|
625
641
|
DD_TRACE_AGENT_HOSTNAME,
|
|
626
642
|
DD_TRACE_AGENT_PORT,
|
|
627
643
|
DD_TRACE_AGENT_PROTOCOL_VERSION,
|
|
644
|
+
DD_TRACE_BAGGAGE_MAX_BYTES,
|
|
645
|
+
DD_TRACE_BAGGAGE_MAX_ITEMS,
|
|
628
646
|
DD_TRACE_CLIENT_IP_ENABLED,
|
|
629
647
|
DD_TRACE_CLIENT_IP_HEADER,
|
|
648
|
+
DD_TRACE_ENABLED,
|
|
630
649
|
DD_TRACE_EXPERIMENTAL_EXPORTER,
|
|
631
650
|
DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
632
651
|
DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
|
|
633
652
|
DD_TRACE_GIT_METADATA_ENABLED,
|
|
634
653
|
DD_TRACE_GLOBAL_TAGS,
|
|
635
654
|
DD_TRACE_HEADER_TAGS,
|
|
655
|
+
DD_TRACE_LEGACY_BAGGAGE_ENABLED,
|
|
636
656
|
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
637
657
|
DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
|
|
638
658
|
DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
|
|
@@ -704,6 +724,8 @@ class Config {
|
|
|
704
724
|
this._envUnprocessed['appsec.stackTrace.maxStackTraces'] = DD_APPSEC_MAX_STACK_TRACES
|
|
705
725
|
this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
|
|
706
726
|
this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
|
|
727
|
+
this._setValue(env, 'baggageMaxBytes', DD_TRACE_BAGGAGE_MAX_BYTES)
|
|
728
|
+
this._setValue(env, 'baggageMaxItems', DD_TRACE_BAGGAGE_MAX_ITEMS)
|
|
707
729
|
this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
|
|
708
730
|
this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
|
|
709
731
|
this._setBoolean(env, 'codeOriginForSpans.enabled', DD_CODE_ORIGIN_FOR_SPANS_ENABLED)
|
|
@@ -713,6 +735,7 @@ class Config {
|
|
|
713
735
|
this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
|
|
714
736
|
this._setBoolean(env, 'dynamicInstrumentationEnabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED)
|
|
715
737
|
this._setString(env, 'env', DD_ENV || tags.env)
|
|
738
|
+
this._setBoolean(env, 'traceEnabled', DD_TRACE_ENABLED)
|
|
716
739
|
this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
|
|
717
740
|
this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
|
|
718
741
|
this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
|
|
@@ -720,6 +743,8 @@ class Config {
|
|
|
720
743
|
this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
|
|
721
744
|
this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
|
|
722
745
|
this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
|
|
746
|
+
this._setIntegerRangeSet(env, 'grpc.client.error.statuses', DD_GRPC_CLIENT_ERROR_STATUSES)
|
|
747
|
+
this._setIntegerRangeSet(env, 'grpc.server.error.statuses', DD_GRPC_SERVER_ERROR_STATUSES)
|
|
723
748
|
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
724
749
|
this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
|
|
725
750
|
this._setString(env, 'iast.cookieFilterPattern', DD_IAST_COOKIE_FILTER_PATTERN)
|
|
@@ -741,6 +766,10 @@ class Config {
|
|
|
741
766
|
this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
|
|
742
767
|
this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
|
|
743
768
|
this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
|
|
769
|
+
this._setBoolean(env, 'legacyBaggageEnabled', DD_TRACE_LEGACY_BAGGAGE_ENABLED)
|
|
770
|
+
this._setBoolean(env, 'llmobs.agentlessEnabled', DD_LLMOBS_AGENTLESS_ENABLED)
|
|
771
|
+
this._setBoolean(env, 'llmobs.enabled', DD_LLMOBS_ENABLED)
|
|
772
|
+
this._setString(env, 'llmobs.mlApp', DD_LLMOBS_ML_APP)
|
|
744
773
|
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
|
|
745
774
|
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
|
|
746
775
|
this._setBoolean(env, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
|
|
@@ -874,6 +903,8 @@ class Config {
|
|
|
874
903
|
this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
|
|
875
904
|
this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
|
|
876
905
|
this._setString(opts, 'clientIpHeader', options.clientIpHeader)
|
|
906
|
+
this._setValue(opts, 'baggageMaxBytes', options.baggageMaxBytes)
|
|
907
|
+
this._setValue(opts, 'baggageMaxItems', options.baggageMaxItems)
|
|
877
908
|
this._setBoolean(opts, 'codeOriginForSpans.enabled', options.codeOriginForSpans?.enabled)
|
|
878
909
|
this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
|
|
879
910
|
if (options.dogstatsd) {
|
|
@@ -911,6 +942,9 @@ class Config {
|
|
|
911
942
|
}
|
|
912
943
|
this._setString(opts, 'iast.telemetryVerbosity', options.iast && options.iast.telemetryVerbosity)
|
|
913
944
|
this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
|
|
945
|
+
this._setBoolean(opts, 'legacyBaggageEnabled', options.legacyBaggageEnabled)
|
|
946
|
+
this._setBoolean(opts, 'llmobs.agentlessEnabled', options.llmobs?.agentlessEnabled)
|
|
947
|
+
this._setString(opts, 'llmobs.mlApp', options.llmobs?.mlApp)
|
|
914
948
|
this._setBoolean(opts, 'logInjection', options.logInjection)
|
|
915
949
|
this._setString(opts, 'lookup', options.lookup)
|
|
916
950
|
this._setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
|
|
@@ -946,6 +980,15 @@ class Config {
|
|
|
946
980
|
this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
|
|
947
981
|
this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
|
|
948
982
|
this._setString(opts, 'version', options.version || tags.version)
|
|
983
|
+
|
|
984
|
+
// For LLMObs, we want the environment variable to take precedence over the options.
|
|
985
|
+
// This is reliant on environment config being set before options.
|
|
986
|
+
// This is to make sure the origins of each value are tracked appropriately for telemetry.
|
|
987
|
+
// We'll only set `llmobs.enabled` on the opts when it's not set on the environment, and options.llmobs is provided.
|
|
988
|
+
const llmobsEnabledEnv = this._env['llmobs.enabled']
|
|
989
|
+
if (llmobsEnabledEnv == null && options.llmobs) {
|
|
990
|
+
this._setBoolean(opts, 'llmobs.enabled', !!options.llmobs)
|
|
991
|
+
}
|
|
949
992
|
}
|
|
950
993
|
|
|
951
994
|
_isCiVisibility () {
|
|
@@ -1045,7 +1088,8 @@ class Config {
|
|
|
1045
1088
|
DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
|
|
1046
1089
|
DD_CIVISIBILITY_FLAKY_RETRY_COUNT,
|
|
1047
1090
|
DD_TEST_SESSION_NAME,
|
|
1048
|
-
DD_AGENTLESS_LOG_SUBMISSION_ENABLED
|
|
1091
|
+
DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
|
|
1092
|
+
DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED
|
|
1049
1093
|
} = process.env
|
|
1050
1094
|
|
|
1051
1095
|
if (DD_CIVISIBILITY_AGENTLESS_URL) {
|
|
@@ -1063,6 +1107,7 @@ class Config {
|
|
|
1063
1107
|
this._setBoolean(calc, 'isManualApiEnabled', !isFalse(this._isCiVisibilityManualApiEnabled()))
|
|
1064
1108
|
this._setString(calc, 'ciVisibilityTestSessionName', DD_TEST_SESSION_NAME)
|
|
1065
1109
|
this._setBoolean(calc, 'ciVisAgentlessLogSubmissionEnabled', isTrue(DD_AGENTLESS_LOG_SUBMISSION_ENABLED))
|
|
1110
|
+
this._setBoolean(calc, 'isTestDynamicInstrumentationEnabled', isTrue(DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED))
|
|
1066
1111
|
}
|
|
1067
1112
|
this._setString(calc, 'dogstatsd.hostname', this._getHostname())
|
|
1068
1113
|
this._setBoolean(calc, 'isGitUploadEnabled',
|
|
@@ -1155,7 +1200,11 @@ class Config {
|
|
|
1155
1200
|
}
|
|
1156
1201
|
|
|
1157
1202
|
if (typeof value === 'string') {
|
|
1158
|
-
value = value.split(',')
|
|
1203
|
+
value = value.split(',').map(item => {
|
|
1204
|
+
// Trim each item and remove whitespace around the colon
|
|
1205
|
+
const [key, val] = item.split(':').map(part => part.trim())
|
|
1206
|
+
return val !== undefined ? `${key}:${val}` : key
|
|
1207
|
+
})
|
|
1159
1208
|
}
|
|
1160
1209
|
|
|
1161
1210
|
if (Array.isArray(value)) {
|
|
@@ -1163,6 +1212,26 @@ class Config {
|
|
|
1163
1212
|
}
|
|
1164
1213
|
}
|
|
1165
1214
|
|
|
1215
|
+
_setIntegerRangeSet (obj, name, value) {
|
|
1216
|
+
if (value == null) {
|
|
1217
|
+
return this._setValue(obj, name, null)
|
|
1218
|
+
}
|
|
1219
|
+
value = value.split(',')
|
|
1220
|
+
const result = []
|
|
1221
|
+
|
|
1222
|
+
value.forEach(val => {
|
|
1223
|
+
if (val.includes('-')) {
|
|
1224
|
+
const [start, end] = val.split('-').map(Number)
|
|
1225
|
+
for (let i = start; i <= end; i++) {
|
|
1226
|
+
result.push(i)
|
|
1227
|
+
}
|
|
1228
|
+
} else {
|
|
1229
|
+
result.push(Number(val))
|
|
1230
|
+
}
|
|
1231
|
+
})
|
|
1232
|
+
this._setValue(obj, name, result)
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1166
1235
|
_setSamplingRule (obj, name, value) {
|
|
1167
1236
|
if (value == null) {
|
|
1168
1237
|
return this._setValue(obj, name, null)
|
|
@@ -44,5 +44,7 @@ module.exports = {
|
|
|
44
44
|
SCHEMA_ID: 'schema.id',
|
|
45
45
|
SCHEMA_TOPIC: 'schema.topic',
|
|
46
46
|
SCHEMA_OPERATION: 'schema.operation',
|
|
47
|
-
SCHEMA_NAME: 'schema.name'
|
|
47
|
+
SCHEMA_NAME: 'schema.name',
|
|
48
|
+
GRPC_CLIENT_ERROR_STATUSES: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
|
49
|
+
GRPC_SERVER_ERROR_STATUSES: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
|
|
48
50
|
}
|
|
@@ -21,6 +21,7 @@ function shaHash (checkpointString) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function computeHash (service, env, edgeTags, parentHash) {
|
|
24
|
+
edgeTags.sort()
|
|
24
25
|
const hashableEdgeTags = edgeTags.filter(item => item !== 'manual_checkpoint:true')
|
|
25
26
|
|
|
26
27
|
const key = `${service}${env}` + hashableEdgeTags.join('') + parentHash.toString()
|
|
@@ -5,7 +5,7 @@ const { breakpoints } = require('./state')
|
|
|
5
5
|
const session = require('./session')
|
|
6
6
|
const { getLocalStateForCallFrame } = require('./snapshot')
|
|
7
7
|
const send = require('./send')
|
|
8
|
-
const {
|
|
8
|
+
const { getStackFromCallFrames } = require('./state')
|
|
9
9
|
const { ackEmitting, ackError } = require('./status')
|
|
10
10
|
const { parentThreadId } = require('./config')
|
|
11
11
|
const log = require('../../log')
|
|
@@ -23,12 +23,14 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
23
23
|
const timestamp = Date.now()
|
|
24
24
|
|
|
25
25
|
let captureSnapshotForProbe = null
|
|
26
|
-
let maxReferenceDepth, maxLength
|
|
26
|
+
let maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength
|
|
27
27
|
const probes = params.hitBreakpoints.map((id) => {
|
|
28
28
|
const probe = breakpoints.get(id)
|
|
29
29
|
if (probe.captureSnapshot) {
|
|
30
30
|
captureSnapshotForProbe = probe
|
|
31
31
|
maxReferenceDepth = highestOrUndefined(probe.capture.maxReferenceDepth, maxReferenceDepth)
|
|
32
|
+
maxCollectionSize = highestOrUndefined(probe.capture.maxCollectionSize, maxCollectionSize)
|
|
33
|
+
maxFieldCount = highestOrUndefined(probe.capture.maxFieldCount, maxFieldCount)
|
|
32
34
|
maxLength = highestOrUndefined(probe.capture.maxLength, maxLength)
|
|
33
35
|
}
|
|
34
36
|
return probe
|
|
@@ -38,7 +40,10 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
38
40
|
if (captureSnapshotForProbe !== null) {
|
|
39
41
|
try {
|
|
40
42
|
// TODO: Create unique states for each affected probe based on that probes unique `capture` settings (DEBUG-2863)
|
|
41
|
-
processLocalState = await getLocalStateForCallFrame(
|
|
43
|
+
processLocalState = await getLocalStateForCallFrame(
|
|
44
|
+
params.callFrames[0],
|
|
45
|
+
{ maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength }
|
|
46
|
+
)
|
|
42
47
|
} catch (err) {
|
|
43
48
|
// TODO: This error is not tied to a specific probe, but to all probes with `captureSnapshot: true`.
|
|
44
49
|
// However, in 99,99% of cases, there will be just a single probe, so I guess this simplification is ok?
|
|
@@ -61,16 +66,7 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
61
66
|
thread_name: threadName
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
const stack = params.callFrames
|
|
65
|
-
let fileName = getScriptUrlFromId(frame.location.scriptId)
|
|
66
|
-
if (fileName.startsWith('file://')) fileName = fileName.substr(7) // TODO: This might not be required
|
|
67
|
-
return {
|
|
68
|
-
fileName,
|
|
69
|
-
function: frame.functionName,
|
|
70
|
-
lineNumber: frame.location.lineNumber + 1, // Beware! lineNumber is zero-indexed
|
|
71
|
-
columnNumber: frame.location.columnNumber + 1 // Beware! columnNumber is zero-indexed
|
|
72
|
-
}
|
|
73
|
-
})
|
|
69
|
+
const stack = getStackFromCallFrames(params.callFrames)
|
|
74
70
|
|
|
75
71
|
// TODO: Send multiple probes in one HTTP request as an array (DEBUG-2848)
|
|
76
72
|
for (const probe of probes) {
|
|
@@ -9,6 +9,8 @@ const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags'
|
|
|
9
9
|
|
|
10
10
|
module.exports = send
|
|
11
11
|
|
|
12
|
+
const MAX_PAYLOAD_SIZE = 1024 * 1024 // 1MB
|
|
13
|
+
|
|
12
14
|
const ddsource = 'dd_debugger'
|
|
13
15
|
const hostname = getHostname()
|
|
14
16
|
const service = config.service
|
|
@@ -37,5 +39,17 @@ function send (message, logger, snapshot, cb) {
|
|
|
37
39
|
'debugger.snapshot': snapshot
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
let json = JSON.stringify(payload)
|
|
43
|
+
|
|
44
|
+
if (Buffer.byteLength(json) > MAX_PAYLOAD_SIZE) {
|
|
45
|
+
// TODO: This is a very crude way to handle large payloads. Proper pruning will be implemented later (DEBUG-2624)
|
|
46
|
+
const line = Object.values(payload['debugger.snapshot'].captures.lines)[0]
|
|
47
|
+
line.locals = {
|
|
48
|
+
notCapturedReason: 'Snapshot was too large',
|
|
49
|
+
size: Object.keys(line.locals).length
|
|
50
|
+
}
|
|
51
|
+
json = JSON.stringify(payload)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
request(json, opts, cb)
|
|
41
55
|
}
|