dd-trace 5.67.0 → 5.69.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 +6 -4
- package/README.md +0 -2
- package/ci/init.js +52 -54
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +240 -3
- package/initialize.mjs +1 -1
- package/package.json +17 -11
- package/packages/datadog-core/src/storage.js +14 -13
- package/packages/datadog-esbuild/index.js +118 -26
- package/packages/datadog-instrumentations/src/aws-sdk.js +42 -4
- package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
- package/packages/datadog-instrumentations/src/azure-service-bus.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
- package/packages/datadog-instrumentations/src/connect.js +6 -2
- package/packages/datadog-instrumentations/src/cucumber.js +31 -6
- package/packages/datadog-instrumentations/src/express.js +5 -6
- package/packages/datadog-instrumentations/src/fastify.js +3 -3
- package/packages/datadog-instrumentations/src/helpers/hook.js +28 -15
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +15 -5
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -3
- package/packages/datadog-instrumentations/src/http2/client.js +1 -0
- package/packages/datadog-instrumentations/src/http2/server.js +0 -1
- package/packages/datadog-instrumentations/src/ioredis.js +12 -1
- package/packages/datadog-instrumentations/src/jest.js +48 -36
- package/packages/datadog-instrumentations/src/limitd-client.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +15 -7
- package/packages/datadog-instrumentations/src/mocha/utils.js +3 -0
- package/packages/datadog-instrumentations/src/mongoose.js +2 -1
- package/packages/datadog-instrumentations/src/oracledb.js +19 -13
- package/packages/datadog-instrumentations/src/pg.js +9 -5
- package/packages/datadog-instrumentations/src/pino.js +18 -6
- package/packages/datadog-instrumentations/src/playwright.js +15 -1
- package/packages/datadog-instrumentations/src/sequelize.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +155 -62
- package/packages/datadog-plugin-ai/src/tracing.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +23 -8
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +101 -2
- package/packages/datadog-plugin-aws-sdk/src/util.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +6 -0
- package/packages/datadog-plugin-cucumber/src/index.js +4 -56
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +6 -3
- package/packages/datadog-plugin-cypress/src/support.js +4 -0
- package/packages/datadog-plugin-express/src/code_origin.js +2 -2
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -2
- package/packages/datadog-plugin-jest/src/index.js +0 -21
- package/packages/datadog-plugin-mocha/src/index.js +3 -57
- package/packages/datadog-plugin-mongodb-core/src/index.js +38 -12
- package/packages/datadog-plugin-playwright/src/index.js +11 -5
- package/packages/datadog-plugin-vitest/src/index.js +5 -1
- package/packages/datadog-plugin-ws/src/close.js +1 -1
- package/packages/datadog-plugin-ws/src/producer.js +6 -1
- package/packages/datadog-plugin-ws/src/receiver.js +6 -1
- package/packages/dd-trace/src/aiguard/client.js +25 -0
- package/packages/dd-trace/src/aiguard/noop.js +9 -0
- package/packages/dd-trace/src/aiguard/sdk.js +173 -0
- package/packages/dd-trace/src/aiguard/tags.js +11 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +21 -4
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +6 -3
- package/packages/dd-trace/src/appsec/stack_trace.js +20 -1
- package/packages/dd-trace/src/appsec/telemetry/waf.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +11 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +10 -1
- package/packages/dd-trace/src/config-helper.js +8 -1
- package/packages/dd-trace/src/config.js +92 -304
- package/packages/dd-trace/src/config_defaults.js +191 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -1
- package/packages/dd-trace/src/datastreams/fnv.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +23 -1
- package/packages/dd-trace/src/datastreams/writer.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -1
- package/packages/dd-trace/src/dogstatsd.js +4 -3
- package/packages/dd-trace/src/encode/0.4.js +1 -5
- package/packages/dd-trace/src/exporter.js +1 -0
- package/packages/dd-trace/src/exporters/agent/index.js +3 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +2 -1
- package/packages/dd-trace/src/exporters/span-stats/index.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +15 -4
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +20 -7
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +40 -13
- package/packages/dd-trace/src/llmobs/plugins/openai.js +7 -1
- package/packages/dd-trace/src/llmobs/tagger.js +8 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
- package/packages/dd-trace/src/log/index.js +27 -16
- package/packages/dd-trace/src/log/log.js +29 -5
- package/packages/dd-trace/src/log/writer.js +5 -5
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/noop/span.js +1 -0
- package/packages/dd-trace/src/opentelemetry/span.js +14 -3
- package/packages/dd-trace/src/opentracing/span.js +19 -5
- package/packages/dd-trace/src/payload-tagging/config/index.js +16 -0
- package/packages/dd-trace/src/payload-tagging/index.js +26 -15
- package/packages/dd-trace/src/payload-tagging/tagging.js +17 -8
- package/packages/dd-trace/src/pkg.js +3 -1
- package/packages/dd-trace/src/plugin_manager.js +20 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +97 -3
- package/packages/dd-trace/src/plugins/composite.js +3 -0
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/plugin.js +67 -0
- package/packages/dd-trace/src/plugins/util/git-cache.js +129 -0
- package/packages/dd-trace/src/plugins/util/git.js +41 -27
- package/packages/dd-trace/src/plugins/util/test.js +56 -27
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/priority_sampler.js +70 -46
- package/packages/dd-trace/src/profiler.js +4 -1
- package/packages/dd-trace/src/profiling/config.js +73 -42
- package/packages/dd-trace/src/profiling/profiler.js +3 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -8
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +196 -117
- package/packages/dd-trace/src/proxy.js +15 -0
- package/packages/dd-trace/src/rate_limiter.js +26 -1
- package/packages/dd-trace/src/remote_config/capabilities.js +5 -0
- package/packages/dd-trace/src/remote_config/manager.js +3 -2
- package/packages/dd-trace/src/sampling_rule.js +124 -2
- package/packages/dd-trace/src/span_sampler.js +19 -0
- package/packages/dd-trace/src/standalone/product.js +9 -0
- package/packages/dd-trace/src/standalone/tracesource.js +16 -1
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +13 -0
- package/packages/dd-trace/src/startup-log.js +21 -2
- package/packages/dd-trace/src/supported-configurations.json +9 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/util.js +1 -1
- package/register.js +1 -1
- package/version.js +4 -2
|
@@ -49,6 +49,13 @@ const { SAMPLING_RULE_DECISION } = require('../../constants')
|
|
|
49
49
|
const { AUTO_KEEP } = require('../../../../../ext/priority')
|
|
50
50
|
const { version: ddTraceVersion } = require('../../../../../package.json')
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* JSDoc types for test environment metadata helpers.
|
|
54
|
+
*
|
|
55
|
+
* @typedef {{ service?: string, isServiceUserProvided?: boolean }} TestEnvironmentConfig
|
|
56
|
+
* @typedef {Record<string, string|number|undefined>} TestEnvironmentMetadata
|
|
57
|
+
*/
|
|
58
|
+
|
|
52
59
|
// session tags
|
|
53
60
|
const TEST_SESSION_NAME = 'test_session.name'
|
|
54
61
|
|
|
@@ -119,6 +126,10 @@ const MOCHA_WORKER_TRACE_PAYLOAD_CODE = 80
|
|
|
119
126
|
// playwright worker variables
|
|
120
127
|
const PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE = 90
|
|
121
128
|
|
|
129
|
+
// vitest worker variables
|
|
130
|
+
const VITEST_WORKER_TRACE_PAYLOAD_CODE = 100
|
|
131
|
+
const VITEST_WORKER_LOGS_PAYLOAD_CODE = 102
|
|
132
|
+
|
|
122
133
|
// Early flake detection util strings
|
|
123
134
|
const EFD_STRING = "Retried by Datadog's Early Flake Detection"
|
|
124
135
|
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + String.raw` \(#\d+\): `, 'g')
|
|
@@ -218,6 +229,8 @@ module.exports = {
|
|
|
218
229
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
219
230
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
220
231
|
PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE,
|
|
232
|
+
VITEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
233
|
+
VITEST_WORKER_LOGS_PAYLOAD_CODE,
|
|
221
234
|
TEST_SOURCE_START,
|
|
222
235
|
TEST_SKIPPED_BY_ITR,
|
|
223
236
|
TEST_IS_NEW,
|
|
@@ -325,6 +338,10 @@ function validateUrl (url) {
|
|
|
325
338
|
}
|
|
326
339
|
}
|
|
327
340
|
|
|
341
|
+
/**
|
|
342
|
+
* @param {TestEnvironmentMetadata} metadata
|
|
343
|
+
* @returns {TestEnvironmentMetadata}
|
|
344
|
+
*/
|
|
328
345
|
function removeInvalidMetadata (metadata) {
|
|
329
346
|
return Object.keys(metadata).reduce((filteredTags, tag) => {
|
|
330
347
|
if (tag === GIT_REPOSITORY_URL && !validateGitRepositoryUrl(metadata[GIT_REPOSITORY_URL])) {
|
|
@@ -438,37 +455,49 @@ function checkShaDiscrepancies (ciMetadata, userProvidedGitMetadata) {
|
|
|
438
455
|
)
|
|
439
456
|
}
|
|
440
457
|
|
|
441
|
-
|
|
442
|
-
|
|
458
|
+
/**
|
|
459
|
+
* Build environment metadata for tests by merging CI, Git, runtime/OS and user-provided metadata.
|
|
460
|
+
*
|
|
461
|
+
* @param {string=} testFramework
|
|
462
|
+
* @param {TestEnvironmentConfig=} config
|
|
463
|
+
* @returns {TestEnvironmentMetadata}
|
|
464
|
+
*/
|
|
465
|
+
function getTestEnvironmentMetadata (testFramework, config, shouldSkipGitMetadataExtraction = false) {
|
|
443
466
|
const ciMetadata = getCIMetadata()
|
|
444
|
-
const {
|
|
445
|
-
[GIT_COMMIT_SHA]: commitSHA,
|
|
446
|
-
[GIT_BRANCH]: branch,
|
|
447
|
-
[GIT_REPOSITORY_URL]: repositoryUrl,
|
|
448
|
-
[GIT_TAG]: tag,
|
|
449
|
-
[GIT_COMMIT_AUTHOR_NAME]: authorName,
|
|
450
|
-
[GIT_COMMIT_AUTHOR_EMAIL]: authorEmail,
|
|
451
|
-
[GIT_COMMIT_MESSAGE]: commitMessage,
|
|
452
|
-
[CI_WORKSPACE_PATH]: ciWorkspacePath,
|
|
453
|
-
[GIT_COMMIT_HEAD_SHA]: headCommitSha
|
|
454
|
-
} = ciMetadata
|
|
455
|
-
|
|
456
|
-
const gitMetadata = getGitMetadata({
|
|
457
|
-
commitSHA,
|
|
458
|
-
branch,
|
|
459
|
-
repositoryUrl,
|
|
460
|
-
tag,
|
|
461
|
-
authorName,
|
|
462
|
-
authorEmail,
|
|
463
|
-
commitMessage,
|
|
464
|
-
ciWorkspacePath,
|
|
465
|
-
headCommitSha
|
|
466
|
-
})
|
|
467
|
-
|
|
468
467
|
const userProvidedGitMetadata = getUserProviderGitMetadata()
|
|
469
468
|
|
|
470
|
-
|
|
469
|
+
let gitMetadata = {}
|
|
470
|
+
|
|
471
|
+
// We don't execute git in test framework workers since the information is in the parent process
|
|
472
|
+
// and git metadata does not affect the execution of the tests
|
|
473
|
+
if (!shouldSkipGitMetadataExtraction) {
|
|
474
|
+
checkShaDiscrepancies(ciMetadata, userProvidedGitMetadata)
|
|
475
|
+
|
|
476
|
+
const {
|
|
477
|
+
[GIT_COMMIT_SHA]: commitSHA,
|
|
478
|
+
[GIT_BRANCH]: branch,
|
|
479
|
+
[GIT_REPOSITORY_URL]: repositoryUrl,
|
|
480
|
+
[GIT_TAG]: tag,
|
|
481
|
+
[GIT_COMMIT_AUTHOR_NAME]: authorName,
|
|
482
|
+
[GIT_COMMIT_AUTHOR_EMAIL]: authorEmail,
|
|
483
|
+
[GIT_COMMIT_MESSAGE]: commitMessage,
|
|
484
|
+
[CI_WORKSPACE_PATH]: ciWorkspacePath,
|
|
485
|
+
[GIT_COMMIT_HEAD_SHA]: headCommitSha
|
|
486
|
+
} = ciMetadata
|
|
487
|
+
gitMetadata = getGitMetadata({
|
|
488
|
+
commitSHA,
|
|
489
|
+
branch,
|
|
490
|
+
repositoryUrl,
|
|
491
|
+
tag,
|
|
492
|
+
authorName,
|
|
493
|
+
authorEmail,
|
|
494
|
+
commitMessage,
|
|
495
|
+
ciWorkspacePath,
|
|
496
|
+
headCommitSha
|
|
497
|
+
})
|
|
498
|
+
}
|
|
471
499
|
|
|
500
|
+
/** @type {TestEnvironmentMetadata} */
|
|
472
501
|
const runtimeAndOSMetadata = getRuntimeAndOSMetadata()
|
|
473
502
|
|
|
474
503
|
const metadata = {
|
|
@@ -387,7 +387,7 @@ const web = {
|
|
|
387
387
|
|
|
388
388
|
return function (statusCode, statusMessage, headers) {
|
|
389
389
|
headers = typeof statusMessage === 'string' ? headers : statusMessage
|
|
390
|
-
headers =
|
|
390
|
+
headers = { ...res.getHeaders(), ...headers }
|
|
391
391
|
|
|
392
392
|
if (req.method.toLowerCase() === 'options' && isOriginAllowed(req, headers)) {
|
|
393
393
|
addAllowHeaders(req, res, headers)
|
|
@@ -46,8 +46,9 @@ const defaultSampler = new Sampler(AUTO_KEEP)
|
|
|
46
46
|
* @class PrioritySampler
|
|
47
47
|
* @typedef {import('./opentracing/span')} DatadogSpan
|
|
48
48
|
* @typedef {import('./opentracing/span_context')} DatadogSpanContext
|
|
49
|
-
* @typedef {
|
|
49
|
+
* @typedef {{ id: number, mechanism?: number }} Product
|
|
50
50
|
* @typedef {2|-1|1|0} SamplingPriority Empirically defined sampling priorities.
|
|
51
|
+
* @typedef {import('./sampling_rule')|Record<string, unknown>} SamplingRuleLike
|
|
51
52
|
*/
|
|
52
53
|
class PrioritySampler {
|
|
53
54
|
/**
|
|
@@ -55,12 +56,12 @@ class PrioritySampler {
|
|
|
55
56
|
*
|
|
56
57
|
* @typedef {Object} SamplingConfig
|
|
57
58
|
* @property {number} [sampleRate] - The default sample rate for traces.
|
|
58
|
-
* @property {string} [provenance] -
|
|
59
|
+
* @property {string} [provenance] - Optional rule provenance ("customer" or "dynamic").
|
|
59
60
|
* @property {number} [rateLimit=100] - The maximum number of traces to sample per second.
|
|
60
|
-
* @property {Array<
|
|
61
|
+
* @property {Array<import('./sampling_rule')>|Array<Record<string, unknown>>} [rules=[]] - Sampling rules or configs.
|
|
61
62
|
*
|
|
62
63
|
* @param {string} env - The environment name (e.g., "production", "staging").
|
|
63
|
-
* @param {SamplingConfig} config - The configuration object for sampling.
|
|
64
|
+
* @param {SamplingConfig} [config] - The configuration object for sampling.
|
|
64
65
|
*/
|
|
65
66
|
constructor (env, config) {
|
|
66
67
|
this.configure(env, config)
|
|
@@ -69,22 +70,22 @@ class PrioritySampler {
|
|
|
69
70
|
|
|
70
71
|
/**
|
|
71
72
|
*
|
|
72
|
-
* @param
|
|
73
|
-
* @param
|
|
73
|
+
* @param {string} env
|
|
74
|
+
* @param {SamplingConfig} config
|
|
74
75
|
*/
|
|
75
|
-
configure (env,
|
|
76
|
-
const { sampleRate, provenance, rateLimit = 100, rules } =
|
|
76
|
+
configure (env, config = {}) {
|
|
77
|
+
const { sampleRate, provenance, rateLimit = 100, rules } = config
|
|
77
78
|
this._env = env
|
|
78
79
|
this._rules = this.#normalizeRules(rules || [], sampleRate, rateLimit, provenance)
|
|
79
80
|
this._limiter = new RateLimiter(rateLimit)
|
|
80
81
|
|
|
81
|
-
log.trace(env,
|
|
82
|
+
log.trace(env, config)
|
|
82
83
|
setSamplingRules(this._rules)
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
|
-
* @param
|
|
87
|
-
* @returns {boolean}
|
|
87
|
+
* @param {DatadogSpan} span
|
|
88
|
+
* @returns {boolean} True if the trace should be sampled based on priority.
|
|
88
89
|
*/
|
|
89
90
|
isSampled (span) {
|
|
90
91
|
const priority = this._getPriorityFromAuto(span)
|
|
@@ -93,9 +94,10 @@ class PrioritySampler {
|
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
/**
|
|
97
|
+
* Assigns a sampling priority to a span if not already set.
|
|
96
98
|
*
|
|
97
|
-
* @param
|
|
98
|
-
* @param
|
|
99
|
+
* @param {DatadogSpan} span
|
|
100
|
+
* @param {boolean} [auto=true] - Whether to use automatic sampling if no manual tags are present.
|
|
99
101
|
* @returns {void}
|
|
100
102
|
*/
|
|
101
103
|
sample (span, auto = true) {
|
|
@@ -125,8 +127,9 @@ class PrioritySampler {
|
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
/**
|
|
130
|
+
* Updates agent-provided sampling rates keyed by `service:,env:`.
|
|
128
131
|
*
|
|
129
|
-
* @param
|
|
132
|
+
* @param {Record<string, number>} rates
|
|
130
133
|
* @returns {void}
|
|
131
134
|
*/
|
|
132
135
|
update (rates) {
|
|
@@ -145,8 +148,9 @@ class PrioritySampler {
|
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
/**
|
|
151
|
+
* Validates that a sampling priority value is one of the allowed constants.
|
|
148
152
|
*
|
|
149
|
-
* @param
|
|
153
|
+
* @param {SamplingPriority|undefined} samplingPriority
|
|
150
154
|
* @returns {boolean}
|
|
151
155
|
*/
|
|
152
156
|
validate (samplingPriority) {
|
|
@@ -162,10 +166,11 @@ class PrioritySampler {
|
|
|
162
166
|
}
|
|
163
167
|
|
|
164
168
|
/**
|
|
169
|
+
* Explicitly sets the priority and mechanism for the span's trace.
|
|
165
170
|
*
|
|
166
|
-
* @param
|
|
167
|
-
* @param
|
|
168
|
-
* @param
|
|
171
|
+
* @param {DatadogSpan} span
|
|
172
|
+
* @param {SamplingPriority} samplingPriority
|
|
173
|
+
* @param {Product} [product]
|
|
169
174
|
*/
|
|
170
175
|
setPriority (span, samplingPriority, product) {
|
|
171
176
|
if (!span || !this.validate(samplingPriority)) return
|
|
@@ -189,17 +194,21 @@ class PrioritySampler {
|
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
/**
|
|
197
|
+
* Returns the span context, accepting either a span or a span context.
|
|
192
198
|
*
|
|
193
|
-
* @param
|
|
199
|
+
* @param {DatadogSpan|DatadogSpanContext} span
|
|
194
200
|
* @returns {DatadogSpanContext}
|
|
195
201
|
*/
|
|
196
202
|
_getContext (span) {
|
|
197
|
-
return typeof span.context === 'function'
|
|
203
|
+
return typeof /** @type {DatadogSpan} */ (span).context === 'function'
|
|
204
|
+
? /** @type {DatadogSpan} */ (span).context()
|
|
205
|
+
: /** @type {DatadogSpanContext} */ (span)
|
|
198
206
|
}
|
|
199
207
|
|
|
200
208
|
/**
|
|
209
|
+
* Computes priority using rules and agent rates when no manual tag is present.
|
|
201
210
|
*
|
|
202
|
-
* @param
|
|
211
|
+
* @param {DatadogSpan} span
|
|
203
212
|
* @returns {SamplingPriority}
|
|
204
213
|
*/
|
|
205
214
|
_getPriorityFromAuto (span) {
|
|
@@ -212,11 +221,12 @@ class PrioritySampler {
|
|
|
212
221
|
}
|
|
213
222
|
|
|
214
223
|
/**
|
|
215
|
-
*
|
|
216
|
-
* @param tags {Record<string, symbol | unknown>}
|
|
224
|
+
* Computes priority from manual sampling tags if present.
|
|
217
225
|
* Included for compatibility with {@link import('./standalone/tracesource_priority_sampler')._getPriorityFromTags}
|
|
218
|
-
*
|
|
219
|
-
* @
|
|
226
|
+
*
|
|
227
|
+
* @param {Record<string, unknown>} tags
|
|
228
|
+
* @param {DatadogSpanContext} _context
|
|
229
|
+
* @returns {SamplingPriority|undefined}
|
|
220
230
|
*/
|
|
221
231
|
_getPriorityFromTags (tags, _context) {
|
|
222
232
|
if (Object.hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
|
|
@@ -224,19 +234,23 @@ class PrioritySampler {
|
|
|
224
234
|
} else if (Object.hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
|
|
225
235
|
return USER_REJECT
|
|
226
236
|
}
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
237
|
+
const rawPriority = tags[SAMPLING_PRIORITY]
|
|
238
|
+
if (rawPriority !== undefined) {
|
|
239
|
+
const priority = Number.parseInt(String(rawPriority), 10)
|
|
240
|
+
|
|
241
|
+
if (priority === 1 || priority === 2) {
|
|
242
|
+
return USER_KEEP
|
|
243
|
+
} else if (priority === 0 || priority === -1) {
|
|
244
|
+
return USER_REJECT
|
|
245
|
+
}
|
|
233
246
|
}
|
|
234
247
|
}
|
|
235
248
|
|
|
236
249
|
/**
|
|
250
|
+
* Applies a matching rule and rate limit to compute the sampling priority.
|
|
237
251
|
*
|
|
238
|
-
* @param
|
|
239
|
-
* @param
|
|
252
|
+
* @param {DatadogSpanContext} context
|
|
253
|
+
* @param {import('./sampling_rule')} rule
|
|
240
254
|
* @returns {SamplingPriority}
|
|
241
255
|
*/
|
|
242
256
|
#getPriorityByRule (context, rule) {
|
|
@@ -251,12 +265,14 @@ class PrioritySampler {
|
|
|
251
265
|
}
|
|
252
266
|
|
|
253
267
|
/**
|
|
268
|
+
* Checks if the rate limiter allows sampling for the current window and
|
|
269
|
+
* records the effective rate on the trace.
|
|
254
270
|
*
|
|
255
|
-
* @param
|
|
271
|
+
* @param {DatadogSpanContext} context
|
|
256
272
|
* @returns {boolean}
|
|
257
|
-
* @private
|
|
258
273
|
*/
|
|
259
274
|
_isSampledByRateLimit (context) {
|
|
275
|
+
// TODO: Change underscored properties to private ones.
|
|
260
276
|
const allowed = this._limiter.isAllowed()
|
|
261
277
|
|
|
262
278
|
context._trace[SAMPLING_LIMIT_DECISION] = this._limiter.effectiveRate()
|
|
@@ -265,12 +281,14 @@ class PrioritySampler {
|
|
|
265
281
|
}
|
|
266
282
|
|
|
267
283
|
/**
|
|
284
|
+
* Computes priority using agent-provided sampling rates.
|
|
268
285
|
*
|
|
269
|
-
* @param
|
|
286
|
+
* @param {DatadogSpanContext} context
|
|
270
287
|
* @returns {SamplingPriority}
|
|
271
288
|
*/
|
|
272
289
|
#getPriorityByAgent (context) {
|
|
273
290
|
const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}`
|
|
291
|
+
// TODO: Change underscored properties to private ones.
|
|
274
292
|
const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY]
|
|
275
293
|
|
|
276
294
|
context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
|
|
@@ -281,8 +299,9 @@ class PrioritySampler {
|
|
|
281
299
|
}
|
|
282
300
|
|
|
283
301
|
/**
|
|
302
|
+
* Tags the trace with a decision maker when priority is keep, or removes it otherwise.
|
|
284
303
|
*
|
|
285
|
-
* @param
|
|
304
|
+
* @param {DatadogSpan} span
|
|
286
305
|
* @returns {void}
|
|
287
306
|
*/
|
|
288
307
|
#addDecisionMaker (span) {
|
|
@@ -301,11 +320,13 @@ class PrioritySampler {
|
|
|
301
320
|
}
|
|
302
321
|
|
|
303
322
|
/**
|
|
304
|
-
*
|
|
305
|
-
*
|
|
323
|
+
* Normalizes rule inputs to SamplingRule instances, applying defaults.
|
|
324
|
+
*
|
|
325
|
+
* @param {Array<SamplingRuleLike>|SamplingRuleLike} rules - Rules to normalize.
|
|
326
|
+
* @param {number|undefined} sampleRate
|
|
306
327
|
* @param {number} rateLimit
|
|
307
|
-
* @param {string} provenance
|
|
308
|
-
* @returns {
|
|
328
|
+
* @param {string|undefined} provenance
|
|
329
|
+
* @returns {Array<import('./sampling_rule')>}
|
|
309
330
|
*/
|
|
310
331
|
#normalizeRules (rules, sampleRate, rateLimit, provenance) {
|
|
311
332
|
rules = Array.isArray(rules) ? rules.flat() : [rules]
|
|
@@ -314,7 +335,7 @@ class PrioritySampler {
|
|
|
314
335
|
|
|
315
336
|
const result = []
|
|
316
337
|
for (const rule of rules) {
|
|
317
|
-
const sampleRate = Number.parseFloat(rule.sampleRate)
|
|
338
|
+
const sampleRate = Number.parseFloat(String(rule.sampleRate))
|
|
318
339
|
// TODO(BridgeAR): Debug logging invalid rules fails our tests.
|
|
319
340
|
// Should we definitely not know about these?
|
|
320
341
|
if (!Number.isNaN(sampleRate)) {
|
|
@@ -325,11 +346,13 @@ class PrioritySampler {
|
|
|
325
346
|
}
|
|
326
347
|
|
|
327
348
|
/**
|
|
349
|
+
* Finds the first matching rule for the given span.
|
|
328
350
|
*
|
|
329
|
-
* @param
|
|
330
|
-
* @returns {
|
|
351
|
+
* @param {DatadogSpan} span
|
|
352
|
+
* @returns {import('./sampling_rule')|undefined}
|
|
331
353
|
*/
|
|
332
354
|
#findRule (span) {
|
|
355
|
+
// TODO: Change underscored properties to private ones.
|
|
333
356
|
for (const rule of this._rules) {
|
|
334
357
|
// Rule is a special object with a .match() property.
|
|
335
358
|
// It has nothing to do with a regular expression.
|
|
@@ -339,9 +362,10 @@ class PrioritySampler {
|
|
|
339
362
|
}
|
|
340
363
|
|
|
341
364
|
/**
|
|
365
|
+
* Convenience helper to keep a trace with an optional product mechanism.
|
|
342
366
|
*
|
|
343
|
-
* @param
|
|
344
|
-
* @param
|
|
367
|
+
* @param {DatadogSpan} span
|
|
368
|
+
* @param {Product} [product]
|
|
345
369
|
*/
|
|
346
370
|
static keepTrace (span, product) {
|
|
347
371
|
span?._prioritySampler?.setPriority(span, USER_KEEP, product)
|
|
@@ -10,6 +10,8 @@ module.exports = {
|
|
|
10
10
|
start: config => {
|
|
11
11
|
const { service, version, env, url, hostname, port, tags, repositoryUrl, commitSHA, injectionEnabled } = config
|
|
12
12
|
const { enabled, sourceMap, exporters } = config.profiling
|
|
13
|
+
const { heartbeatInterval } = config.telemetry
|
|
14
|
+
|
|
13
15
|
const logger = {
|
|
14
16
|
debug: (message) => log.debug(message),
|
|
15
17
|
info: (message) => log.info(message),
|
|
@@ -39,7 +41,8 @@ module.exports = {
|
|
|
39
41
|
repositoryUrl,
|
|
40
42
|
commitSHA,
|
|
41
43
|
libraryInjected,
|
|
42
|
-
activation
|
|
44
|
+
activation,
|
|
45
|
+
heartbeatInterval
|
|
43
46
|
})
|
|
44
47
|
},
|
|
45
48
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const coalesce = require('koalas')
|
|
4
3
|
const os = require('os')
|
|
5
4
|
const path = require('path')
|
|
6
5
|
const { URL, format, pathToFileURL } = require('url')
|
|
6
|
+
const satisfies = require('semifies')
|
|
7
7
|
const { AgentExporter } = require('./exporters/agent')
|
|
8
8
|
const { FileExporter } = require('./exporters/file')
|
|
9
9
|
const { ConsoleLogger } = require('./loggers/console')
|
|
@@ -16,6 +16,7 @@ const { tagger } = require('./tagger')
|
|
|
16
16
|
const { isFalse, isTrue } = require('../util')
|
|
17
17
|
const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
|
|
18
18
|
const { getEnvironmentVariables } = require('../config-helper')
|
|
19
|
+
const defaults = require('../config_defaults')
|
|
19
20
|
|
|
20
21
|
class Config {
|
|
21
22
|
constructor (options = {}) {
|
|
@@ -41,27 +42,26 @@ class Config {
|
|
|
41
42
|
DD_PROFILING_TIMELINE_ENABLED,
|
|
42
43
|
DD_PROFILING_UPLOAD_PERIOD,
|
|
43
44
|
DD_PROFILING_UPLOAD_TIMEOUT,
|
|
45
|
+
DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED,
|
|
44
46
|
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND,
|
|
45
47
|
DD_PROFILING_WALLTIME_ENABLED,
|
|
46
48
|
DD_SERVICE,
|
|
47
49
|
DD_TAGS,
|
|
48
50
|
DD_TRACE_AGENT_PORT,
|
|
49
51
|
DD_TRACE_AGENT_URL,
|
|
50
|
-
DD_VERSION
|
|
52
|
+
DD_VERSION,
|
|
53
|
+
NODE_OPTIONS
|
|
51
54
|
} = getEnvironmentVariables()
|
|
52
55
|
|
|
53
|
-
const env =
|
|
56
|
+
const env = options.env ?? DD_ENV
|
|
54
57
|
const service = options.service || DD_SERVICE || 'node'
|
|
55
58
|
const host = os.hostname()
|
|
56
|
-
const version =
|
|
59
|
+
const version = options.version ?? DD_VERSION
|
|
57
60
|
// Must be longer than one minute so pad with five seconds
|
|
58
|
-
const flushInterval =
|
|
59
|
-
const uploadTimeout =
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
DD_PROFILING_SOURCE_MAP, true)
|
|
63
|
-
const pprofPrefix = coalesce(options.pprofPrefix,
|
|
64
|
-
DD_PROFILING_PPROF_PREFIX, '')
|
|
61
|
+
const flushInterval = options.interval ?? (Number(DD_PROFILING_UPLOAD_PERIOD) * 1000 || 65 * 1000)
|
|
62
|
+
const uploadTimeout = options.uploadTimeout ?? (Number(DD_PROFILING_UPLOAD_TIMEOUT) || 60 * 1000)
|
|
63
|
+
const sourceMap = options.sourceMap ?? DD_PROFILING_SOURCE_MAP ?? true
|
|
64
|
+
const pprofPrefix = options.pprofPrefix ?? DD_PROFILING_PPROF_PREFIX ?? ''
|
|
65
65
|
|
|
66
66
|
this.service = service
|
|
67
67
|
this.env = env
|
|
@@ -104,21 +104,21 @@ class Config {
|
|
|
104
104
|
this.flushInterval = flushInterval
|
|
105
105
|
this.uploadTimeout = uploadTimeout
|
|
106
106
|
this.sourceMap = sourceMap
|
|
107
|
-
this.debugSourceMaps = isTrue(
|
|
108
|
-
this.endpointCollectionEnabled = isTrue(
|
|
109
|
-
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED
|
|
107
|
+
this.debugSourceMaps = isTrue(options.debugSourceMaps ?? DD_PROFILING_DEBUG_SOURCE_MAPS)
|
|
108
|
+
this.endpointCollectionEnabled = isTrue(options.endpointCollection ??
|
|
109
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED ?? samplingContextsAvailable)
|
|
110
110
|
checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
|
|
111
111
|
|
|
112
112
|
this.pprofPrefix = pprofPrefix
|
|
113
|
-
this.v8ProfilerBugWorkaroundEnabled = isTrue(
|
|
114
|
-
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND
|
|
115
|
-
const hostname =
|
|
116
|
-
const port =
|
|
117
|
-
this.url = new URL(
|
|
113
|
+
this.v8ProfilerBugWorkaroundEnabled = isTrue(options.v8ProfilerBugWorkaround ??
|
|
114
|
+
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND ?? true)
|
|
115
|
+
const hostname = (options.hostname ?? DD_AGENT_HOST) || defaults.hostname
|
|
116
|
+
const port = (options.port ?? DD_TRACE_AGENT_PORT) || defaults.port
|
|
117
|
+
this.url = new URL(options.url ?? DD_TRACE_AGENT_URL ?? format({
|
|
118
118
|
protocol: 'http:',
|
|
119
119
|
hostname,
|
|
120
120
|
port
|
|
121
|
-
}))
|
|
121
|
+
}))
|
|
122
122
|
|
|
123
123
|
this.libraryInjected = options.libraryInjected
|
|
124
124
|
this.activation = options.activation
|
|
@@ -129,17 +129,17 @@ class Config {
|
|
|
129
129
|
// OOM monitoring does not work well on Windows, so it is disabled by default.
|
|
130
130
|
const oomMonitoringSupported = process.platform !== 'win32'
|
|
131
131
|
|
|
132
|
-
const oomMonitoringEnabled = isTrue(
|
|
133
|
-
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED
|
|
132
|
+
const oomMonitoringEnabled = isTrue(options.oomMonitoring ??
|
|
133
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED ?? oomMonitoringSupported)
|
|
134
134
|
checkOptionAllowed(oomMonitoringEnabled, 'OOM monitoring', oomMonitoringSupported)
|
|
135
135
|
|
|
136
|
-
const heapLimitExtensionSize =
|
|
137
|
-
Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE)
|
|
138
|
-
const maxHeapExtensionCount =
|
|
139
|
-
Number(DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT)
|
|
136
|
+
const heapLimitExtensionSize = options.oomHeapLimitExtensionSize ??
|
|
137
|
+
(Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE) || 0)
|
|
138
|
+
const maxHeapExtensionCount = options.oomMaxHeapExtensionCount ??
|
|
139
|
+
(Number(DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT) || 0)
|
|
140
140
|
const exportStrategies = oomMonitoringEnabled
|
|
141
|
-
? ensureOOMExportStrategies(
|
|
142
|
-
[oomExportStrategies.PROCESS]
|
|
141
|
+
? ensureOOMExportStrategies(options.oomExportStrategies ?? DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES ??
|
|
142
|
+
[oomExportStrategies.PROCESS], this)
|
|
143
143
|
: []
|
|
144
144
|
const exportCommand = oomMonitoringEnabled ? buildExportCommand(this) : undefined
|
|
145
145
|
this.oomMonitoring = {
|
|
@@ -156,26 +156,29 @@ class Config {
|
|
|
156
156
|
DD_PROFILING_PROFILERS
|
|
157
157
|
})
|
|
158
158
|
|
|
159
|
-
this.timelineEnabled = isTrue(
|
|
160
|
-
DD_PROFILING_TIMELINE_ENABLED
|
|
159
|
+
this.timelineEnabled = isTrue(
|
|
160
|
+
options.timelineEnabled ?? DD_PROFILING_TIMELINE_ENABLED ?? samplingContextsAvailable
|
|
161
|
+
)
|
|
161
162
|
checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
|
|
162
|
-
this.timelineSamplingEnabled = isTrue(
|
|
163
|
-
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED
|
|
163
|
+
this.timelineSamplingEnabled = isTrue(
|
|
164
|
+
options.timelineSamplingEnabled ?? DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED ?? true
|
|
165
|
+
)
|
|
164
166
|
|
|
165
|
-
this.codeHotspotsEnabled = isTrue(
|
|
166
|
-
DD_PROFILING_CODEHOTSPOTS_ENABLED
|
|
167
|
+
this.codeHotspotsEnabled = isTrue(
|
|
168
|
+
options.codeHotspotsEnabled ?? DD_PROFILING_CODEHOTSPOTS_ENABLED ?? samplingContextsAvailable
|
|
169
|
+
)
|
|
167
170
|
checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
|
|
168
171
|
|
|
169
|
-
this.cpuProfilingEnabled = isTrue(
|
|
170
|
-
DD_PROFILING_CPU_ENABLED
|
|
171
|
-
|
|
172
|
+
this.cpuProfilingEnabled = isTrue(
|
|
173
|
+
options.cpuProfilingEnabled ?? DD_PROFILING_CPU_ENABLED ?? samplingContextsAvailable
|
|
174
|
+
)
|
|
172
175
|
checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
|
|
173
176
|
|
|
174
|
-
this.samplingInterval =
|
|
177
|
+
this.samplingInterval = options.samplingInterval || 1e3 / 99 // 99hz in millis
|
|
175
178
|
|
|
176
|
-
this.heapSamplingInterval =
|
|
177
|
-
Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL))
|
|
178
|
-
const uploadCompression0 =
|
|
179
|
+
this.heapSamplingInterval = options.heapSamplingInterval ??
|
|
180
|
+
(Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL) || 512 * 1024)
|
|
181
|
+
const uploadCompression0 = options.uploadCompression ?? DD_PROFILING_DEBUG_UPLOAD_COMPRESSION ?? 'on'
|
|
179
182
|
let [uploadCompression, level0] = uploadCompression0.split('-')
|
|
180
183
|
if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
|
|
181
184
|
this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
|
|
@@ -209,6 +212,34 @@ class Config {
|
|
|
209
212
|
|
|
210
213
|
this.uploadCompression = { method: uploadCompression, level }
|
|
211
214
|
|
|
215
|
+
const that = this
|
|
216
|
+
function turnOffAsyncContextFrame (msg) {
|
|
217
|
+
that.logger.warn(
|
|
218
|
+
`DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set ${msg}, it will have no effect.`)
|
|
219
|
+
that.asyncContextFrameEnabled = false
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const hasExecArg = (arg) => process.execArgv.includes(arg) || String(NODE_OPTIONS).includes(arg)
|
|
223
|
+
|
|
224
|
+
this.asyncContextFrameEnabled = isTrue(options.useAsyncContextFrame ?? DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED)
|
|
225
|
+
if (this.asyncContextFrameEnabled) {
|
|
226
|
+
if (satisfies(process.versions.node, '>=24.0.0')) {
|
|
227
|
+
if (hasExecArg('--no-async-context-frame')) {
|
|
228
|
+
turnOffAsyncContextFrame('with --no-async-context-frame')
|
|
229
|
+
}
|
|
230
|
+
} else if (satisfies(process.versions.node, '>=23.0.0')) {
|
|
231
|
+
if (!hasExecArg('--experimental-async-context-frame')) {
|
|
232
|
+
turnOffAsyncContextFrame('without --experimental-async-context-frame')
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
// NOTE: technically, this should work starting with 22.7.0 which is when
|
|
236
|
+
// AsyncContextFrame debuted, but it would require a change in pprof-nodejs too.
|
|
237
|
+
turnOffAsyncContextFrame('but it requires at least Node.js 23')
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
this.heartbeatInterval = options.heartbeatInterval || 60 * 1000 // 1 minute
|
|
242
|
+
|
|
212
243
|
this.profilers = ensureProfilers(profilers, this)
|
|
213
244
|
}
|
|
214
245
|
}
|
|
@@ -220,7 +251,7 @@ function getProfilers ({
|
|
|
220
251
|
}) {
|
|
221
252
|
// First consider "legacy" DD_PROFILING_PROFILERS env variable, defaulting to wall + space
|
|
222
253
|
// Use a Set to avoid duplicates
|
|
223
|
-
const profilers = new Set(
|
|
254
|
+
const profilers = new Set((DD_PROFILING_PROFILERS ?? 'wall,space').split(','))
|
|
224
255
|
|
|
225
256
|
// Add/remove wall depending on the value of DD_PROFILING_WALLTIME_ENABLED
|
|
226
257
|
if (DD_PROFILING_WALLTIME_ENABLED != null) {
|
|
@@ -110,11 +110,13 @@ class Profiler extends EventEmitter {
|
|
|
110
110
|
}
|
|
111
111
|
break
|
|
112
112
|
case 'zstd':
|
|
113
|
-
if (typeof zlib.zstdCompress === 'function') {
|
|
113
|
+
if (typeof zlib.zstdCompress === 'function') { // eslint-disable-line n/no-unsupported-features/node-builtins
|
|
114
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
114
115
|
this.#compressionFn = promisify(zlib.zstdCompress)
|
|
115
116
|
if (clevel !== undefined) {
|
|
116
117
|
this.#compressionOptions = {
|
|
117
118
|
params: {
|
|
119
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
118
120
|
[zlib.constants.ZSTD_c_compressionLevel]: clevel
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -41,14 +41,9 @@ function labelFromStrStr (stringTable, keyStr, valStr) {
|
|
|
41
41
|
return labelFromStr(stringTable, stringTable.dedup(keyStr), valStr)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function getSamplingIntervalMillis (options) {
|
|
45
|
-
return (options.samplingInterval || 1e3 / 99) // 99Hz
|
|
46
|
-
}
|
|
47
|
-
|
|
48
44
|
function getMaxSamples (options) {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const maxCpuSamples = flushInterval / cpuSamplingInterval
|
|
45
|
+
const flushInterval = options.flushInterval || 65 * 1e3 // 65 seconds
|
|
46
|
+
const maxCpuSamples = flushInterval / options.samplingInterval
|
|
52
47
|
|
|
53
48
|
// The lesser of max parallelism and libuv thread pool size, plus one so we can detect
|
|
54
49
|
// oversubscription on libuv thread pool, plus another one for GC.
|
|
@@ -399,7 +394,7 @@ class EventsProfiler {
|
|
|
399
394
|
|
|
400
395
|
const eventHandler = event => this.#eventSerializer.addEvent(event)
|
|
401
396
|
const eventFilter = options.timelineSamplingEnabled
|
|
402
|
-
? createPoissonProcessSamplingFilter(
|
|
397
|
+
? createPoissonProcessSamplingFilter(options.samplingInterval)
|
|
403
398
|
: () => true
|
|
404
399
|
const filteringEventHandler = event => {
|
|
405
400
|
if (eventFilter(event)) {
|