dd-trace 5.54.0 → 5.56.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/ci/cypress/plugin.js +8 -0
- package/ci/cypress/polyfills.js +23 -0
- package/ci/init.js +8 -7
- package/initialize.mjs +2 -2
- package/package.json +10 -9
- package/packages/datadog-code-origin/index.js +22 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
- package/packages/datadog-core/src/utils/src/set.js +8 -10
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -6
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +2 -3
- package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
- package/packages/datadog-instrumentations/src/couchbase.js +3 -6
- package/packages/datadog-instrumentations/src/cucumber.js +21 -28
- package/packages/datadog-instrumentations/src/dns.js +4 -4
- package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
- package/packages/datadog-instrumentations/src/fastify.js +7 -9
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +14 -16
- package/packages/datadog-instrumentations/src/hapi.js +10 -11
- package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -5
- package/packages/datadog-instrumentations/src/jest.js +421 -376
- package/packages/datadog-instrumentations/src/koa.js +2 -3
- package/packages/datadog-instrumentations/src/mariadb.js +11 -4
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -75
- package/packages/datadog-instrumentations/src/mocha.js +3 -1
- package/packages/datadog-instrumentations/src/mysql.js +11 -2
- package/packages/datadog-instrumentations/src/nyc.js +2 -1
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
- package/packages/datadog-instrumentations/src/pg.js +2 -3
- package/packages/datadog-instrumentations/src/playwright.js +19 -22
- package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
- package/packages/datadog-instrumentations/src/redis.js +1 -1
- package/packages/datadog-instrumentations/src/restify.js +9 -13
- package/packages/datadog-instrumentations/src/router.js +12 -11
- package/packages/datadog-instrumentations/src/tedious.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +15 -29
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -8
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +12 -20
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -5
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -10
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -4
- package/packages/datadog-plugin-cucumber/src/index.js +3 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -1
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +1 -1
- package/packages/datadog-plugin-graphql/src/index.js +3 -2
- package/packages/datadog-plugin-graphql/src/resolve.js +17 -10
- package/packages/datadog-plugin-http/src/client.js +5 -6
- package/packages/datadog-plugin-http2/src/client.js +7 -8
- package/packages/datadog-plugin-jest/src/index.js +3 -2
- package/packages/datadog-plugin-mocha/src/index.js +6 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
- package/packages/datadog-plugin-mysql/src/index.js +11 -0
- package/packages/datadog-plugin-next/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +2 -4
- package/packages/datadog-plugin-oracledb/src/index.js +2 -1
- package/packages/datadog-plugin-playwright/src/index.js +3 -2
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
- package/packages/datadog-plugin-redis/src/index.js +1 -3
- package/packages/datadog-plugin-vitest/src/index.js +5 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +1 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +12 -13
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +44 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +8 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +0 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
- package/packages/dd-trace/src/appsec/index.js +16 -5
- package/packages/dd-trace/src/appsec/reporter.js +11 -11
- package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
- package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -2
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +2 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +8 -7
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +4 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -3
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -1
- package/packages/dd-trace/src/config-helper.js +89 -0
- package/packages/dd-trace/src/config.js +120 -115
- package/packages/dd-trace/src/config_stable.js +7 -4
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +6 -6
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +5 -1
- package/packages/dd-trace/src/debugger/index.js +1 -0
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +5 -2
- package/packages/dd-trace/src/encode/0.5.js +3 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -5
- package/packages/dd-trace/src/exporter.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -1
- package/packages/dd-trace/src/exporters/common/docker.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +4 -1
- package/packages/dd-trace/src/exporters/common/util.js +3 -1
- package/packages/dd-trace/src/id.js +3 -3
- package/packages/dd-trace/src/index.js +4 -3
- package/packages/dd-trace/src/lambda/handler.js +2 -1
- package/packages/dd-trace/src/lambda/index.js +2 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +3 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/index.js +21 -5
- package/packages/dd-trace/src/llmobs/noop.js +18 -20
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -2
- package/packages/dd-trace/src/llmobs/sdk.js +2 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +19 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/log/index.js +5 -4
- package/packages/dd-trace/src/log/writer.js +1 -2
- package/packages/dd-trace/src/msgpack/encoder.js +3 -3
- package/packages/dd-trace/src/noop/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +4 -5
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +35 -42
- package/packages/dd-trace/src/opentracing/span.js +7 -6
- package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +25 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +7 -7
- package/packages/dd-trace/src/plugins/util/git.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/stacktrace.js +8 -1
- package/packages/dd-trace/src/plugins/util/test.js +4 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +3 -4
- package/packages/dd-trace/src/priority_sampler.js +46 -35
- package/packages/dd-trace/src/profiling/config.js +12 -32
- package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -1
- package/packages/dd-trace/src/profiling/index.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +7 -4
- package/packages/dd-trace/src/profiling/profilers/events.js +10 -2
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
- package/packages/dd-trace/src/profiling/tagger.js +22 -12
- package/packages/dd-trace/src/proxy.js +2 -1
- package/packages/dd-trace/src/ritm.js +4 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -2
- package/packages/dd-trace/src/sampler.js +10 -2
- package/packages/dd-trace/src/serverless.js +11 -4
- package/packages/dd-trace/src/span_processor.js +2 -1
- package/packages/dd-trace/src/standalone/tracesource.js +1 -2
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
- package/packages/dd-trace/src/startup-log.js +5 -17
- package/packages/dd-trace/src/supported-configurations.json +440 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +62 -57
- package/packages/dd-trace/src/telemetry/send-data.js +7 -6
- package/packages/dd-trace/src/telemetry/telemetry.js +16 -26
- package/packages/dd-trace/src/tracer.js +3 -7
- package/packages/dd-trace/src/util.js +0 -5
- package/packages/datadog-core/src/utils/src/get.js +0 -11
- package/packages/datadog-core/src/utils/src/has.js +0 -14
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -120
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
|
@@ -421,7 +421,7 @@ function addAllowHeaders (req, res, headers) {
|
|
|
421
421
|
]
|
|
422
422
|
|
|
423
423
|
for (const header of contextHeaders) {
|
|
424
|
-
if (
|
|
424
|
+
if (requestHeaders.includes(header)) {
|
|
425
425
|
allowHeaders.push(header)
|
|
426
426
|
}
|
|
427
427
|
}
|
|
@@ -530,10 +530,9 @@ function extractURL (req) {
|
|
|
530
530
|
|
|
531
531
|
if (req.stream) {
|
|
532
532
|
return `${headers[HTTP2_HEADER_SCHEME]}://${headers[HTTP2_HEADER_AUTHORITY]}${headers[HTTP2_HEADER_PATH]}`
|
|
533
|
-
} else {
|
|
534
|
-
const protocol = getProtocol(req)
|
|
535
|
-
return `${protocol}://${req.headers.host}${req.originalUrl || req.url}`
|
|
536
533
|
}
|
|
534
|
+
const protocol = getProtocol(req)
|
|
535
|
+
return `${protocol}://${req.headers.host}${req.originalUrl || req.url}`
|
|
537
536
|
}
|
|
538
537
|
|
|
539
538
|
function getProtocol (req) {
|
|
@@ -5,7 +5,6 @@ const RateLimiter = require('./rate_limiter')
|
|
|
5
5
|
const Sampler = require('./sampler')
|
|
6
6
|
const { setSamplingRules } = require('./startup-log')
|
|
7
7
|
const SamplingRule = require('./sampling_rule')
|
|
8
|
-
const { hasOwn } = require('./util')
|
|
9
8
|
|
|
10
9
|
const {
|
|
11
10
|
SAMPLING_MECHANISM_DEFAULT,
|
|
@@ -40,16 +39,28 @@ const DEFAULT_KEY = 'service:,env:'
|
|
|
40
39
|
const defaultSampler = new Sampler(AUTO_KEEP)
|
|
41
40
|
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* PrioritySampler is responsible for determining whether a span should be sampled
|
|
43
|
+
* based on various rules, rate limits, and priorities. It supports manual and
|
|
44
|
+
* automatic sampling mechanisms and integrates with Datadog's tracing system.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
* @typedef {
|
|
46
|
+
* @class PrioritySampler
|
|
47
|
+
* @typedef {import('./opentracing/span')} DatadogSpan
|
|
48
|
+
* @typedef {import('./opentracing/span_context')} DatadogSpanContext
|
|
49
|
+
* @typedef {import('./standalone/product')} PRODUCTS
|
|
50
|
+
* @typedef {2|-1|1|0} SamplingPriority Empirically defined sampling priorities.
|
|
48
51
|
*/
|
|
49
52
|
class PrioritySampler {
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
54
|
+
* Creates an instance of PrioritySampler.
|
|
55
|
+
*
|
|
56
|
+
* @typedef {Object} SamplingConfig
|
|
57
|
+
* @property {number} [sampleRate] - The default sample rate for traces.
|
|
58
|
+
* @property {string} [provenance] - The provenance of the sampling rule (e.g., "customer", "dynamic").
|
|
59
|
+
* @property {number} [rateLimit=100] - The maximum number of traces to sample per second.
|
|
60
|
+
* @property {Array<SamplingRule>} [rules=[]] - An array of sampling rules to apply.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} env - The environment name (e.g., "production", "staging").
|
|
63
|
+
* @param {SamplingConfig} config - The configuration object for sampling.
|
|
53
64
|
*/
|
|
54
65
|
constructor (env, config) {
|
|
55
66
|
this.configure(env, config)
|
|
@@ -62,9 +73,9 @@ class PrioritySampler {
|
|
|
62
73
|
* @param opts {SamplingConfig}
|
|
63
74
|
*/
|
|
64
75
|
configure (env, opts = {}) {
|
|
65
|
-
const { sampleRate, provenance, rateLimit = 100, rules
|
|
76
|
+
const { sampleRate, provenance, rateLimit = 100, rules } = opts
|
|
66
77
|
this._env = env
|
|
67
|
-
this._rules = this.#normalizeRules(rules, sampleRate, rateLimit, provenance)
|
|
78
|
+
this._rules = this.#normalizeRules(rules || [], sampleRate, rateLimit, provenance)
|
|
68
79
|
this._limiter = new RateLimiter(rateLimit)
|
|
69
80
|
|
|
70
81
|
log.trace(env, opts)
|
|
@@ -154,7 +165,7 @@ class PrioritySampler {
|
|
|
154
165
|
*
|
|
155
166
|
* @param span {DatadogSpan}
|
|
156
167
|
* @param samplingPriority {SamplingPriority}
|
|
157
|
-
* @param product {import('./standalone/product')
|
|
168
|
+
* @param product {import('./standalone/product')}
|
|
158
169
|
*/
|
|
159
170
|
setPriority (span, samplingPriority, product) {
|
|
160
171
|
if (!span || !this.validate(samplingPriority)) return
|
|
@@ -208,18 +219,17 @@ class PrioritySampler {
|
|
|
208
219
|
* @returns {SamplingPriority}
|
|
209
220
|
*/
|
|
210
221
|
_getPriorityFromTags (tags, _context) {
|
|
211
|
-
if (hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
|
|
222
|
+
if (Object.hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
|
|
212
223
|
return USER_KEEP
|
|
213
|
-
} else if (hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
|
|
224
|
+
} else if (Object.hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
|
|
214
225
|
return USER_REJECT
|
|
215
|
-
}
|
|
216
|
-
|
|
226
|
+
}
|
|
227
|
+
const priority = Number.parseInt(tags[SAMPLING_PRIORITY], 10)
|
|
217
228
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
229
|
+
if (priority === 1 || priority === 2) {
|
|
230
|
+
return USER_KEEP
|
|
231
|
+
} else if (priority === 0 || priority === -1) {
|
|
232
|
+
return USER_REJECT
|
|
223
233
|
}
|
|
224
234
|
}
|
|
225
235
|
|
|
@@ -258,7 +268,6 @@ class PrioritySampler {
|
|
|
258
268
|
*
|
|
259
269
|
* @param context {DatadogSpanContext}
|
|
260
270
|
* @returns {SamplingPriority}
|
|
261
|
-
* @private
|
|
262
271
|
*/
|
|
263
272
|
#getPriorityByAgent (context) {
|
|
264
273
|
const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}`
|
|
@@ -274,7 +283,6 @@ class PrioritySampler {
|
|
|
274
283
|
/**
|
|
275
284
|
*
|
|
276
285
|
* @param span {DatadogSpan}
|
|
277
|
-
* @private
|
|
278
286
|
* @returns {void}
|
|
279
287
|
*/
|
|
280
288
|
#addDecisionMaker (span) {
|
|
@@ -293,30 +301,33 @@ class PrioritySampler {
|
|
|
293
301
|
}
|
|
294
302
|
|
|
295
303
|
/**
|
|
296
|
-
*
|
|
297
|
-
* @param
|
|
298
|
-
* @param
|
|
299
|
-
* @param
|
|
300
|
-
* @param provenance {string}
|
|
304
|
+
* @param {Record<string, unknown>[] | Record<string, unknown>} rules - The sampling rules to normalize.
|
|
305
|
+
* @param {number} sampleRate
|
|
306
|
+
* @param {number} rateLimit
|
|
307
|
+
* @param {string} provenance
|
|
301
308
|
* @returns {SamplingRule[]}
|
|
302
|
-
* @private
|
|
303
309
|
*/
|
|
304
310
|
#normalizeRules (rules, sampleRate, rateLimit, provenance) {
|
|
305
|
-
rules =
|
|
311
|
+
rules = Array.isArray(rules) ? rules.flat() : [rules]
|
|
306
312
|
|
|
307
313
|
rules.push({ sampleRate, maxPerSecond: rateLimit, provenance })
|
|
308
314
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
315
|
+
const result = []
|
|
316
|
+
for (const rule of rules) {
|
|
317
|
+
const sampleRate = Number.parseFloat(rule.sampleRate)
|
|
318
|
+
// TODO(BridgeAR): Debug logging invalid rules fails our tests.
|
|
319
|
+
// Should we definitely not know about these?
|
|
320
|
+
if (!Number.isNaN(sampleRate)) {
|
|
321
|
+
result.push(SamplingRule.from({ ...rule, sampleRate }))
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return result
|
|
313
325
|
}
|
|
314
326
|
|
|
315
327
|
/**
|
|
316
328
|
*
|
|
317
329
|
* @param span {DatadogSpan}
|
|
318
|
-
* @returns {SamplingRule}
|
|
319
|
-
* @private
|
|
330
|
+
* @returns {SamplingRule|undefined}
|
|
320
331
|
*/
|
|
321
332
|
#findRule (span) {
|
|
322
333
|
for (const rule of this._rules) {
|
|
@@ -330,7 +341,7 @@ class PrioritySampler {
|
|
|
330
341
|
/**
|
|
331
342
|
*
|
|
332
343
|
* @param span {DatadogSpan}
|
|
333
|
-
* @param product {import('./standalone/product')
|
|
344
|
+
* @param product {import('./standalone/product')}
|
|
334
345
|
*/
|
|
335
346
|
static keepTrace (span, product) {
|
|
336
347
|
span?._prioritySampler?.setPriority(span, USER_KEEP, product)
|
|
@@ -15,10 +15,12 @@ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
|
15
15
|
const { tagger } = require('./tagger')
|
|
16
16
|
const { isFalse, isTrue } = require('../util')
|
|
17
17
|
const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
|
|
18
|
+
const { getEnvironmentVariables } = require('../config-helper')
|
|
18
19
|
|
|
19
20
|
class Config {
|
|
20
21
|
constructor (options = {}) {
|
|
21
22
|
const {
|
|
23
|
+
AWS_LAMBDA_FUNCTION_NAME: functionname,
|
|
22
24
|
DD_AGENT_HOST,
|
|
23
25
|
DD_ENV,
|
|
24
26
|
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing
|
|
@@ -27,14 +29,10 @@ class Config {
|
|
|
27
29
|
DD_PROFILING_DEBUG_SOURCE_MAPS,
|
|
28
30
|
DD_PROFILING_DEBUG_UPLOAD_COMPRESSION,
|
|
29
31
|
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
30
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
31
|
-
DD_PROFILING_EXPERIMENTAL_CPU_ENABLED,
|
|
32
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
|
|
33
32
|
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
34
33
|
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
35
34
|
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
36
35
|
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
|
|
37
|
-
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED,
|
|
38
36
|
DD_PROFILING_HEAP_ENABLED,
|
|
39
37
|
DD_PROFILING_HEAP_SAMPLING_INTERVAL,
|
|
40
38
|
DD_PROFILING_PPROF_PREFIX,
|
|
@@ -50,13 +48,12 @@ class Config {
|
|
|
50
48
|
DD_TRACE_AGENT_PORT,
|
|
51
49
|
DD_TRACE_AGENT_URL,
|
|
52
50
|
DD_VERSION
|
|
53
|
-
} =
|
|
51
|
+
} = getEnvironmentVariables()
|
|
54
52
|
|
|
55
53
|
const env = coalesce(options.env, DD_ENV)
|
|
56
54
|
const service = options.service || DD_SERVICE || 'node'
|
|
57
55
|
const host = os.hostname()
|
|
58
56
|
const version = coalesce(options.version, DD_VERSION)
|
|
59
|
-
const functionname = process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
60
57
|
// Must be longer than one minute so pad with five seconds
|
|
61
58
|
const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
|
|
62
59
|
const uploadTimeout = coalesce(options.uploadTimeout,
|
|
@@ -86,16 +83,6 @@ class Config {
|
|
|
86
83
|
}
|
|
87
84
|
|
|
88
85
|
this.logger = ensureLogger(options.logger)
|
|
89
|
-
const logger = this.logger
|
|
90
|
-
function logExperimentalVarDeprecation (shortVarName) {
|
|
91
|
-
const deprecatedEnvVarName = `DD_PROFILING_EXPERIMENTAL_${shortVarName}`
|
|
92
|
-
const v = process.env[deprecatedEnvVarName]
|
|
93
|
-
// not null, undefined, or NaN -- same logic as koalas.hasValue
|
|
94
|
-
// eslint-disable-next-line no-self-compare
|
|
95
|
-
if (v != null && v === v) {
|
|
96
|
-
logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
86
|
// Profiler sampling contexts are not available on Windows, so features
|
|
100
87
|
// depending on those (code hotspots and endpoint collection) need to default
|
|
101
88
|
// to false on Windows.
|
|
@@ -119,9 +106,7 @@ class Config {
|
|
|
119
106
|
this.sourceMap = sourceMap
|
|
120
107
|
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
121
108
|
this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
|
|
122
|
-
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
123
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
|
|
124
|
-
logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
|
|
109
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
|
|
125
110
|
checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
|
|
126
111
|
|
|
127
112
|
this.pprofPrefix = pprofPrefix
|
|
@@ -172,23 +157,18 @@ class Config {
|
|
|
172
157
|
})
|
|
173
158
|
|
|
174
159
|
this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
|
|
175
|
-
DD_PROFILING_TIMELINE_ENABLED,
|
|
176
|
-
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED, samplingContextsAvailable))
|
|
177
|
-
logExperimentalVarDeprecation('TIMELINE_ENABLED')
|
|
160
|
+
DD_PROFILING_TIMELINE_ENABLED, samplingContextsAvailable))
|
|
178
161
|
checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
|
|
179
162
|
this.timelineSamplingEnabled = isTrue(coalesce(options.timelineSamplingEnabled,
|
|
180
163
|
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, true))
|
|
181
164
|
|
|
182
165
|
this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
|
|
183
|
-
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
184
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
|
|
185
|
-
logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
|
|
166
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
|
|
186
167
|
checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
|
|
187
168
|
|
|
188
169
|
this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
|
|
189
170
|
DD_PROFILING_CPU_ENABLED,
|
|
190
|
-
|
|
191
|
-
logExperimentalVarDeprecation('CPU_ENABLED')
|
|
171
|
+
samplingContextsAvailable))
|
|
192
172
|
checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
|
|
193
173
|
|
|
194
174
|
this.heapSamplingInterval = coalesce(options.heapSamplingInterval,
|
|
@@ -196,25 +176,25 @@ class Config {
|
|
|
196
176
|
const uploadCompression0 = coalesce(options.uploadCompression, DD_PROFILING_DEBUG_UPLOAD_COMPRESSION, 'on')
|
|
197
177
|
let [uploadCompression, level0] = uploadCompression0.split('-')
|
|
198
178
|
if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
|
|
199
|
-
logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
|
|
179
|
+
this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
|
|
200
180
|
uploadCompression = 'on'
|
|
201
181
|
}
|
|
202
182
|
let level = level0 ? Number.parseInt(level0, 10) : undefined
|
|
203
183
|
if (level !== undefined) {
|
|
204
184
|
if (['on', 'off'].includes(uploadCompression)) {
|
|
205
|
-
logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
|
|
185
|
+
this.logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
|
|
206
186
|
level = undefined
|
|
207
187
|
} else if (Number.isNaN(level)) {
|
|
208
|
-
logger.warn(
|
|
188
|
+
this.logger.warn(
|
|
209
189
|
`Invalid compression level "${level0}". Will use default level.`)
|
|
210
190
|
level = undefined
|
|
211
191
|
} else if (level < 1) {
|
|
212
|
-
logger.warn(`Invalid compression level ${level}. Will use 1.`)
|
|
192
|
+
this.logger.warn(`Invalid compression level ${level}. Will use 1.`)
|
|
213
193
|
level = 1
|
|
214
194
|
} else {
|
|
215
195
|
const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
|
|
216
196
|
if (level > maxLevel) {
|
|
217
|
-
logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
|
|
197
|
+
this.logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
|
|
218
198
|
level = maxLevel
|
|
219
199
|
}
|
|
220
200
|
}
|
|
@@ -8,6 +8,7 @@ const { ConsoleLogger } = require('./loggers/console')
|
|
|
8
8
|
const { tagger } = require('./tagger')
|
|
9
9
|
const fs = require('fs')
|
|
10
10
|
const { fileURLToPath } = require('url')
|
|
11
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
11
12
|
|
|
12
13
|
const logger = new ConsoleLogger()
|
|
13
14
|
const timeoutMs = 15 * 1000
|
|
@@ -15,25 +16,24 @@ const timeoutMs = 15 * 1000
|
|
|
15
16
|
function exporterFromURL (url) {
|
|
16
17
|
if (url.protocol === 'file:') {
|
|
17
18
|
return new FileExporter({ pprofPrefix: fileURLToPath(url) })
|
|
18
|
-
} else {
|
|
19
|
-
const injectionEnabled = (process.env.DD_INJECTION_ENABLED || '').split(',')
|
|
20
|
-
const libraryInjected = injectionEnabled.length > 0
|
|
21
|
-
const profilingEnabled = (process.env.DD_PROFILING_ENABLED || '').toLowerCase()
|
|
22
|
-
const activation = ['true', '1'].includes(profilingEnabled)
|
|
23
|
-
? 'manual'
|
|
24
|
-
: profilingEnabled === 'auto'
|
|
25
|
-
? 'auto'
|
|
26
|
-
: injectionEnabled.includes('profiling')
|
|
27
|
-
? 'injection'
|
|
28
|
-
: 'unknown'
|
|
29
|
-
return new AgentExporter({
|
|
30
|
-
url,
|
|
31
|
-
logger,
|
|
32
|
-
uploadTimeout: timeoutMs,
|
|
33
|
-
libraryInjected,
|
|
34
|
-
activation
|
|
35
|
-
})
|
|
36
19
|
}
|
|
20
|
+
const injectionEnabled = (getEnvironmentVariable('DD_INJECTION_ENABLED') ?? '').split(',')
|
|
21
|
+
const libraryInjected = injectionEnabled.length > 0
|
|
22
|
+
const profilingEnabled = (getEnvironmentVariable('DD_PROFILING_ENABLED') ?? '').toLowerCase()
|
|
23
|
+
const activation = ['true', '1'].includes(profilingEnabled)
|
|
24
|
+
? 'manual'
|
|
25
|
+
: profilingEnabled === 'auto'
|
|
26
|
+
? 'auto'
|
|
27
|
+
: injectionEnabled.includes('profiling')
|
|
28
|
+
? 'injection'
|
|
29
|
+
: 'unknown'
|
|
30
|
+
return new AgentExporter({
|
|
31
|
+
url,
|
|
32
|
+
logger,
|
|
33
|
+
uploadTimeout: timeoutMs,
|
|
34
|
+
libraryInjected,
|
|
35
|
+
activation
|
|
36
|
+
})
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
async function exportProfile (urls, tags, profileType, profile) {
|
|
@@ -46,7 +46,7 @@ async function exportProfile (urls, tags, profileType, profile) {
|
|
|
46
46
|
|
|
47
47
|
const encodedProfile = await encode(heap.convertProfile(profile, undefined, mapper))
|
|
48
48
|
const start = new Date()
|
|
49
|
-
|
|
49
|
+
await Promise.all(urls.map(async (url) => {
|
|
50
50
|
const exporter = exporterFromURL(url)
|
|
51
51
|
|
|
52
52
|
await exporter.export({
|
|
@@ -57,7 +57,7 @@ async function exportProfile (urls, tags, profileType, profile) {
|
|
|
57
57
|
end: start,
|
|
58
58
|
tags
|
|
59
59
|
})
|
|
60
|
-
}
|
|
60
|
+
}))
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/** Expected command line arguments are:
|
|
@@ -150,7 +150,7 @@ class AgentExporter extends EventSerializer {
|
|
|
150
150
|
'DD-EVP-ORIGIN-VERSION': version,
|
|
151
151
|
...form.getHeaders()
|
|
152
152
|
},
|
|
153
|
-
timeout: this._backoffTime *
|
|
153
|
+
timeout: this._backoffTime * 2 ** attempt
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
docker.inject(options.headers)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const os = require('os')
|
|
2
2
|
const perf = require('perf_hooks').performance
|
|
3
3
|
const version = require('../../../../../package.json').version
|
|
4
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
4
5
|
|
|
5
6
|
const libuvThreadPoolSize = (() => {
|
|
6
|
-
const ss =
|
|
7
|
+
const ss = getEnvironmentVariable('UV_THREADPOOL_SIZE')
|
|
7
8
|
if (ss === undefined) {
|
|
8
9
|
// Backend will apply the default size based on Node version.
|
|
9
10
|
return
|
|
@@ -6,8 +6,9 @@ const SpaceProfiler = require('./profilers/space')
|
|
|
6
6
|
const { AgentExporter } = require('./exporters/agent')
|
|
7
7
|
const { FileExporter } = require('./exporters/file')
|
|
8
8
|
const { ConsoleLogger } = require('./loggers/console')
|
|
9
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
9
10
|
|
|
10
|
-
const profiler =
|
|
11
|
+
const profiler = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') ? new ServerlessProfiler() : new Profiler()
|
|
11
12
|
|
|
12
13
|
module.exports = {
|
|
13
14
|
profiler,
|
|
@@ -226,7 +226,7 @@ class Profiler extends EventEmitter {
|
|
|
226
226
|
const encodedProfiles = {}
|
|
227
227
|
|
|
228
228
|
try {
|
|
229
|
-
if (
|
|
229
|
+
if (this._config.profilers.length === 0) {
|
|
230
230
|
throw new Error('No profile types configured.')
|
|
231
231
|
}
|
|
232
232
|
|
|
@@ -246,8 +246,10 @@ class Profiler extends EventEmitter {
|
|
|
246
246
|
this._capture(this._timeoutInterval, endDate)
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
let hasEncoded = false
|
|
250
|
+
|
|
249
251
|
// encode and export asynchronously
|
|
250
|
-
|
|
252
|
+
await Promise.all(profiles.map(async ({ profiler, profile }) => {
|
|
251
253
|
try {
|
|
252
254
|
const encoded = await profiler.encode(profile)
|
|
253
255
|
const compressed = encoded instanceof Buffer && this._compressionFn !== undefined
|
|
@@ -260,14 +262,15 @@ class Profiler extends EventEmitter {
|
|
|
260
262
|
})
|
|
261
263
|
return `Collected ${profiler.type} profile: ` + profileJson
|
|
262
264
|
})
|
|
265
|
+
hasEncoded = true
|
|
263
266
|
} catch (err) {
|
|
264
267
|
// If encoding one of the profile types fails, we should still try to
|
|
265
268
|
// encode and submit the other profile types.
|
|
266
269
|
this._logError(err)
|
|
267
270
|
}
|
|
268
|
-
}
|
|
271
|
+
}))
|
|
269
272
|
|
|
270
|
-
if (
|
|
273
|
+
if (hasEncoded) {
|
|
271
274
|
await this._submit(encodedProfiles, startDate, endDate, snapshotKind)
|
|
272
275
|
profileSubmittedChannel.publish()
|
|
273
276
|
this._logger.debug('Submitted profiles')
|
|
@@ -291,8 +291,16 @@ class NodeApiEventSource {
|
|
|
291
291
|
|
|
292
292
|
class DatadogInstrumentationEventSource {
|
|
293
293
|
constructor (eventHandler, eventFilter) {
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
// List all entries explicitly for bundlers to pick up the require calls correctly.
|
|
295
|
+
const plugins = [
|
|
296
|
+
require('./event_plugins/dns_lookup'),
|
|
297
|
+
require('./event_plugins/dns_lookupservice'),
|
|
298
|
+
require('./event_plugins/dns_resolve'),
|
|
299
|
+
require('./event_plugins/dns_reverse'),
|
|
300
|
+
require('./event_plugins/fs'),
|
|
301
|
+
require('./event_plugins/net')
|
|
302
|
+
]
|
|
303
|
+
this.plugins = plugins.map((Plugin) => {
|
|
296
304
|
return new Plugin(eventHandler, eventFilter)
|
|
297
305
|
})
|
|
298
306
|
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
const dc = require('dc-polyfill')
|
|
4
4
|
const coalesce = require('koalas')
|
|
5
5
|
const profileSubmittedChannel = dc.channel('datadog:profiling:mock-profile-submitted')
|
|
6
|
-
const {
|
|
6
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
7
|
+
|
|
8
|
+
const DD_PROFILING_UPLOAD_PERIOD = getEnvironmentVariable('DD_PROFILING_UPLOAD_PERIOD')
|
|
7
9
|
|
|
8
10
|
let timerId
|
|
9
11
|
|
|
@@ -5,20 +5,30 @@ const tagger = {
|
|
|
5
5
|
if (!tags) return {}
|
|
6
6
|
|
|
7
7
|
switch (typeof tags) {
|
|
8
|
-
case 'object':
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
8
|
+
case 'object': {
|
|
9
|
+
if (Array.isArray(tags)) {
|
|
10
|
+
const tagObject = {}
|
|
11
|
+
for (const tag of tags) {
|
|
12
|
+
const colon = tag.indexOf(':')
|
|
13
|
+
if (colon === -1) continue
|
|
14
|
+
const key = tag.slice(0, colon).trim()
|
|
15
|
+
const value = tag.slice(colon + 1).trim()
|
|
16
|
+
if (key.length !== 0 && value.length !== 0) {
|
|
17
|
+
tagObject[key] = value
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return tagObject
|
|
21
|
+
}
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
const tagsArray = []
|
|
24
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
25
|
+
if (value != null) {
|
|
26
|
+
tagsArray.push(`${key}:${value}`)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
: tagger.parse(Object.keys(tags)
|
|
20
|
-
.filter(key => tags[key] !== undefined && tags[key] !== null)
|
|
21
|
-
.map(key => `${key}:${tags[key]}`))
|
|
30
|
+
return tagger.parse(tagsArray)
|
|
31
|
+
}
|
|
22
32
|
case 'string':
|
|
23
33
|
return tagger.parse(tags.split(','))
|
|
24
34
|
default:
|
|
@@ -10,6 +10,7 @@ const telemetry = require('./telemetry')
|
|
|
10
10
|
const nomenclature = require('./service-naming')
|
|
11
11
|
const PluginManager = require('./plugin_manager')
|
|
12
12
|
const NoopDogStatsDClient = require('./noop/dogstatsd')
|
|
13
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
13
14
|
const {
|
|
14
15
|
setBaggageItem,
|
|
15
16
|
getBaggageItem,
|
|
@@ -198,7 +199,7 @@ class Tracer extends NoopProxy {
|
|
|
198
199
|
this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
|
|
199
200
|
}
|
|
200
201
|
if (config.ciVisAgentlessLogSubmissionEnabled) {
|
|
201
|
-
if (
|
|
202
|
+
if (getEnvironmentVariable('DD_API_KEY')) {
|
|
202
203
|
const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
|
|
203
204
|
const automaticLogPlugin = new LogSubmissionPlugin(this)
|
|
204
205
|
automaticLogPlugin.configure({ ...config, enabled: true })
|
|
@@ -4,6 +4,7 @@ const path = require('path')
|
|
|
4
4
|
const Module = require('module')
|
|
5
5
|
const parse = require('module-details-from-path')
|
|
6
6
|
const dc = require('dc-polyfill')
|
|
7
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
7
8
|
|
|
8
9
|
const origRequire = Module.prototype.require
|
|
9
10
|
|
|
@@ -82,9 +83,8 @@ function Hook (modules, options, onrequire) {
|
|
|
82
83
|
if (patched) {
|
|
83
84
|
// If it's already patched, just return it as-is.
|
|
84
85
|
return origRequire.apply(this, arguments)
|
|
85
|
-
} else {
|
|
86
|
-
patching[filename] = true
|
|
87
86
|
}
|
|
87
|
+
patching[filename] = true
|
|
88
88
|
|
|
89
89
|
const payload = {
|
|
90
90
|
filename,
|
|
@@ -110,8 +110,8 @@ function Hook (modules, options, onrequire) {
|
|
|
110
110
|
if (!hooks) return exports // abort if module name isn't on whitelist
|
|
111
111
|
name = filename
|
|
112
112
|
} else {
|
|
113
|
-
const inAWSLambda =
|
|
114
|
-
const hasLambdaHandler =
|
|
113
|
+
const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
|
|
114
|
+
const hasLambdaHandler = getEnvironmentVariable('DD_LAMBDA_HANDLER') !== undefined
|
|
115
115
|
const segments = filename.split(path.sep)
|
|
116
116
|
const filenameFromNodeModule = segments.includes('node_modules')
|
|
117
117
|
// decide how to assign the stat
|
|
@@ -8,9 +8,10 @@ const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd')
|
|
|
8
8
|
const log = require('../log')
|
|
9
9
|
const Histogram = require('../histogram')
|
|
10
10
|
const { performance, PerformanceObserver } = require('perf_hooks')
|
|
11
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
11
12
|
|
|
12
13
|
const { NODE_MAJOR, NODE_MINOR } = require('../../../../version')
|
|
13
|
-
const
|
|
14
|
+
const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getEnvironmentVariable('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000'
|
|
14
15
|
const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
|
|
15
16
|
|
|
16
17
|
// Node >=16 has PerformanceObserver with `gc` type, but <16.7 had a critical bug.
|
|
@@ -202,7 +203,7 @@ function captureGCMetrics () {
|
|
|
202
203
|
const pause = {}
|
|
203
204
|
|
|
204
205
|
for (const stat of profile.statistics) {
|
|
205
|
-
const type = stat.gcType.
|
|
206
|
+
const type = stat.gcType.replaceAll(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
|
|
206
207
|
|
|
207
208
|
pause[type] = pause[type] || new Histogram()
|
|
208
209
|
pause[type].record(stat.cost)
|
|
@@ -16,12 +16,16 @@ const SAMPLING_KNUTH_FACTOR = 1_111_111_111_111_111_111n
|
|
|
16
16
|
* This class uses a deterministic sampling algorithm that is consistent across all languages.
|
|
17
17
|
*/
|
|
18
18
|
class Sampler {
|
|
19
|
+
#threshold = 0n
|
|
20
|
+
|
|
19
21
|
/**
|
|
20
22
|
* @param {number} rate
|
|
21
23
|
*/
|
|
22
24
|
constructor (rate) {
|
|
25
|
+
// TODO: Should this be moved up to the calling parts?
|
|
26
|
+
rate = Math.min(Math.max(rate, 0), 1)
|
|
23
27
|
this._rate = rate
|
|
24
|
-
this
|
|
28
|
+
this.#threshold = BigInt(Math.floor(rate * MAX_TRACE_ID))
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
/**
|
|
@@ -31,6 +35,10 @@ class Sampler {
|
|
|
31
35
|
return this._rate
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
get threshold () {
|
|
39
|
+
return this.#threshold
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
/**
|
|
35
43
|
* Determines whether a trace/span should be sampled based on the configured sampling rate.
|
|
36
44
|
*
|
|
@@ -48,7 +56,7 @@ class Sampler {
|
|
|
48
56
|
|
|
49
57
|
span = typeof span.context === 'function' ? span.context() : span
|
|
50
58
|
|
|
51
|
-
return (span._traceId.toBigInt() * SAMPLING_KNUTH_FACTOR) % UINT64_MODULO <= this
|
|
59
|
+
return (span._traceId.toBigInt() * SAMPLING_KNUTH_FACTOR) % UINT64_MODULO <= this.#threshold
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
|