dd-trace 5.109.0 → 5.111.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/README.md +13 -8
- package/ci/init.js +25 -5
- package/ci/vitest-no-worker-init-setup.mjs +430 -0
- package/ext/tags.js +2 -0
- package/index.d.ts +79 -24
- package/initialize.mjs +5 -6
- package/loader-hook.mjs +154 -47
- package/package.json +20 -16
- package/packages/datadog-esbuild/index.js +26 -0
- package/packages/datadog-esbuild/src/utils.js +46 -3
- package/packages/datadog-instrumentations/src/connect.js +4 -3
- package/packages/datadog-instrumentations/src/fastify.js +4 -12
- package/packages/datadog-instrumentations/src/fs.js +8 -6
- package/packages/datadog-instrumentations/src/graphql.js +26 -484
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +81 -8
- package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -2
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +65 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -4
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +201 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +18 -2
- package/packages/datadog-instrumentations/src/koa.js +3 -2
- package/packages/datadog-instrumentations/src/mariadb.js +4 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +14 -2
- package/packages/datadog-instrumentations/src/next.js +10 -10
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +7 -6
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/restify.js +4 -3
- package/packages/datadog-instrumentations/src/router.js +18 -5
- package/packages/datadog-instrumentations/src/selenium.js +1 -2
- package/packages/datadog-instrumentations/src/tedious.js +28 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +1293 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +1567 -0
- package/packages/datadog-instrumentations/src/vitest-util.js +249 -0
- package/packages/datadog-instrumentations/src/vitest-worker.js +753 -0
- package/packages/datadog-instrumentations/src/vitest.js +11 -1598
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +18 -10
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +47 -11
- package/packages/datadog-plugin-aws-sdk/src/base.js +13 -9
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +43 -6
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +83 -91
- package/packages/datadog-plugin-cucumber/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -5
- package/packages/datadog-plugin-cypress/src/support.js +45 -1
- package/packages/datadog-plugin-express/src/code_origin.js +1 -1
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +627 -11
- package/packages/datadog-plugin-graphql/src/index.js +20 -8
- package/packages/datadog-plugin-graphql/src/parse.js +24 -4
- package/packages/datadog-plugin-graphql/src/validate.js +16 -5
- package/packages/datadog-plugin-http/src/client.js +8 -3
- package/packages/datadog-plugin-http/src/index.js +6 -8
- package/packages/datadog-plugin-http2/src/client.js +5 -2
- package/packages/datadog-plugin-jest/src/index.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +7 -2
- package/packages/datadog-plugin-openai/src/services.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-undici/src/index.js +5 -2
- package/packages/datadog-plugin-vitest/src/index.js +76 -64
- package/packages/datadog-shimmer/src/shimmer.js +37 -16
- package/packages/datadog-webpack/index.js +17 -1
- package/packages/datadog-webpack/src/optional-peer-loader.js +17 -0
- package/packages/dd-trace/src/aiguard/sdk.js +15 -3
- package/packages/dd-trace/src/appsec/api_security/index.js +55 -0
- package/packages/dd-trace/src/appsec/api_security/sampler.js +147 -0
- package/packages/dd-trace/src/appsec/channels.js +3 -1
- package/packages/dd-trace/src/appsec/downstream_requests.js +4 -4
- package/packages/dd-trace/src/appsec/graphql.js +5 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +26 -19
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +2 -1
- package/packages/dd-trace/src/appsec/index.js +20 -7
- package/packages/dd-trace/src/appsec/lambda.js +135 -0
- package/packages/dd-trace/src/appsec/reporter.js +50 -10
- package/packages/dd-trace/src/appsec/telemetry/api_security.js +34 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +27 -1
- package/packages/dd-trace/src/appsec/waf/index.js +16 -4
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -4
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +21 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +55 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +17 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +47 -26
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +64 -53
- package/packages/dd-trace/src/ci-visibility/requests/request.js +1 -17
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +3 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +23 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +128 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +287 -0
- package/packages/dd-trace/src/config/defaults.js +25 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +596 -58
- package/packages/dd-trace/src/config/helper.js +134 -33
- package/packages/dd-trace/src/config/index.js +39 -23
- package/packages/dd-trace/src/config/major-overrides.js +4 -2
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +109 -57
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/datastreams/processor.js +11 -3
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +47 -35
- package/packages/dd-trace/src/debugger/devtools_client/index.js +31 -66
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +83 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -0
- package/packages/dd-trace/src/debugger/index.js +5 -0
- package/packages/dd-trace/src/debugger/probe_sampler.js +112 -0
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +19 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +77 -26
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +4 -4
- package/packages/dd-trace/src/exporters/common/request.js +1 -20
- package/packages/dd-trace/src/exporters/common/url.js +34 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -3
- package/packages/dd-trace/src/guardrails/index.js +8 -5
- package/packages/dd-trace/src/index.js +6 -4
- package/packages/dd-trace/src/llmobs/constants/tags.js +6 -0
- package/packages/dd-trace/src/llmobs/index.js +17 -6
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -4
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +5 -1
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +8 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +5 -1
- package/packages/dd-trace/src/llmobs/tagger.js +58 -3
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/log/index.js +18 -20
- package/packages/dd-trace/src/openfeature/flagging_provider.js +2 -7
- package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +5 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +54 -5
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +2 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +40 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +169 -0
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +4 -3
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +19 -0
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +2 -2
- package/packages/dd-trace/src/opentelemetry/otlp/logs.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/logs_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +44 -38
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +29 -13
- package/packages/dd-trace/src/opentelemetry/span.js +14 -3
- package/packages/dd-trace/src/opentelemetry/span_context.js +1 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +26 -13
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +3 -3
- package/packages/dd-trace/src/opentracing/span_context.js +17 -0
- package/packages/dd-trace/src/opentracing/tracer.js +6 -1
- package/packages/dd-trace/src/plugin_manager.js +14 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +276 -0
- package/packages/dd-trace/src/plugins/util/llm.js +6 -1
- package/packages/dd-trace/src/plugins/util/test.js +91 -9
- package/packages/dd-trace/src/plugins/util/url.js +68 -1
- package/packages/dd-trace/src/plugins/util/web.js +19 -36
- package/packages/dd-trace/src/priority_sampler.js +1 -13
- package/packages/dd-trace/src/profiling/config.js +129 -198
- package/packages/dd-trace/src/profiling/constants.js +4 -7
- package/packages/dd-trace/src/profiling/exporter_cli.js +10 -10
- package/packages/dd-trace/src/profiling/exporters/agent.js +23 -16
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +45 -14
- package/packages/dd-trace/src/profiling/exporters/file.js +16 -5
- package/packages/dd-trace/src/profiling/oom.js +71 -0
- package/packages/dd-trace/src/profiling/profiler.js +35 -23
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -7
- package/packages/dd-trace/src/profiling/profilers/space.js +27 -18
- package/packages/dd-trace/src/profiling/profilers/wall.js +35 -25
- package/packages/dd-trace/src/proxy.js +8 -8
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +1 -2
- package/packages/dd-trace/src/service-naming/schemas/util.js +36 -5
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +5 -3
- package/packages/dd-trace/src/span_format.js +2 -1
- package/packages/dd-trace/src/span_processor.js +11 -6
- package/packages/dd-trace/src/span_stats.js +96 -78
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +6 -4
- package/packages/dd-trace/src/telemetry/index.js +2 -2
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/send-data.js +20 -18
- package/packages/dd-trace/src/telemetry/session-propagation.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +9 -9
- package/packages/dd-trace/src/tracer.js +15 -1
- package/packages/dd-trace/src/util.js +14 -0
- package/register.js +58 -1
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +0 -170
- package/packages/dd-trace/src/appsec/api_security_sampler.js +0 -117
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const path = require('path')
|
|
4
|
-
const { pathToFileURL } = require('url')
|
|
5
|
-
|
|
6
3
|
const satisfies = require('../../../../vendor/dist/semifies')
|
|
7
4
|
const getGitMetadata = require('../git_metadata')
|
|
8
5
|
const log = require('../log')
|
|
9
6
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
10
7
|
const { getIsAzureFunction } = require('../serverless')
|
|
11
8
|
const { getAzureTagsFromMetadata, getAzureAppMetadata, getAzureFunctionMetadata } = require('../azure_metadata')
|
|
12
|
-
const { getEnvironmentVariable } = require('../config/helper')
|
|
9
|
+
const { getEnvironmentVariable, getValueFromEnvSources } = require('../config/helper')
|
|
13
10
|
const { isACFActive } = require('../../../datadog-core/src/storage')
|
|
14
11
|
|
|
15
12
|
const { AgentExporter } = require('./exporters/agent')
|
|
@@ -17,152 +14,93 @@ const { FileExporter } = require('./exporters/file')
|
|
|
17
14
|
const WallProfiler = require('./profilers/wall')
|
|
18
15
|
const SpaceProfiler = require('./profilers/space')
|
|
19
16
|
const EventsProfiler = require('./profilers/events')
|
|
20
|
-
const {
|
|
17
|
+
const { ensureOOMExportStrategies } = require('./oom')
|
|
21
18
|
const { tagger } = require('./tagger')
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const { commitSHA, repositoryUrl } = getGitMetadata(options)
|
|
42
|
-
if (repositoryUrl && commitSHA) {
|
|
43
|
-
this.tags[GIT_REPOSITORY_URL] = repositoryUrl
|
|
44
|
-
this.tags[GIT_COMMIT_SHA] = commitSHA
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Normalize from seconds to milliseconds. Default must be longer than a minute.
|
|
48
|
-
this.flushInterval = options.DD_PROFILING_UPLOAD_PERIOD * 1000
|
|
49
|
-
this.uploadTimeout = options.DD_PROFILING_UPLOAD_TIMEOUT
|
|
50
|
-
this.sourceMap = options.DD_PROFILING_SOURCE_MAP
|
|
51
|
-
this.debugSourceMaps = options.DD_PROFILING_DEBUG_SOURCE_MAPS
|
|
52
|
-
this.endpointCollectionEnabled = options.DD_PROFILING_ENDPOINT_COLLECTION_ENABLED
|
|
53
|
-
this.pprofPrefix = options.DD_PROFILING_PPROF_PREFIX
|
|
54
|
-
this.v8ProfilerBugWorkaroundEnabled = options.DD_PROFILING_V8_PROFILER_BUG_WORKAROUND
|
|
55
|
-
|
|
56
|
-
this.url = options.url
|
|
57
|
-
|
|
58
|
-
this.libraryInjected = !!options.DD_INJECTION_ENABLED
|
|
59
|
-
|
|
60
|
-
let activation
|
|
61
|
-
if (options.profiling.enabled === 'auto') {
|
|
62
|
-
activation = 'auto'
|
|
63
|
-
} else if (options.profiling.enabled === 'true') {
|
|
64
|
-
activation = 'manual'
|
|
65
|
-
} // else activation = undefined
|
|
66
|
-
|
|
67
|
-
this.activation = activation
|
|
68
|
-
this.exporters = ensureExporters(options.DD_PROFILING_EXPORTERS, this)
|
|
69
|
-
|
|
70
|
-
const oomMonitoringEnabled = options.DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED
|
|
71
|
-
const heapLimitExtensionSize = options.DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE
|
|
72
|
-
const maxHeapExtensionCount = options.DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT
|
|
73
|
-
const exportStrategies = oomMonitoringEnabled
|
|
74
|
-
? ensureOOMExportStrategies(options.DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES)
|
|
75
|
-
: []
|
|
76
|
-
const exportCommand = oomMonitoringEnabled ? buildExportCommand(this) : undefined
|
|
77
|
-
this.oomMonitoring = {
|
|
78
|
-
enabled: oomMonitoringEnabled,
|
|
79
|
-
heapLimitExtensionSize,
|
|
80
|
-
maxHeapExtensionCount,
|
|
81
|
-
exportStrategies,
|
|
82
|
-
exportCommand,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const profilers = getProfilers(options)
|
|
86
|
-
|
|
87
|
-
this.timelineEnabled = options.DD_PROFILING_TIMELINE_ENABLED
|
|
88
|
-
this.timelineSamplingEnabled = options.DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED
|
|
89
|
-
this.allocationProfilingEnabled = options.DD_PROFILING_ALLOCATION_ENABLED
|
|
90
|
-
this.codeHotspotsEnabled = options.DD_PROFILING_CODEHOTSPOTS_ENABLED
|
|
91
|
-
this.cpuProfilingEnabled = options.DD_PROFILING_CPU_ENABLED
|
|
92
|
-
this.heapSamplingInterval = options.DD_PROFILING_HEAP_SAMPLING_INTERVAL
|
|
93
|
-
|
|
94
|
-
this.samplingInterval = 1e3 / 99 // 99hz in milliseconds
|
|
95
|
-
|
|
96
|
-
const isAtLeast24 = satisfies(process.versions.node, '>=24.0.0')
|
|
97
|
-
|
|
98
|
-
const uploadCompression0 = options.DD_PROFILING_DEBUG_UPLOAD_COMPRESSION
|
|
99
|
-
let [uploadCompression, level0] = uploadCompression0.split('-')
|
|
100
|
-
let level = level0 ? Number.parseInt(level0, 10) : undefined
|
|
101
|
-
if (level !== undefined) {
|
|
102
|
-
const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
|
|
103
|
-
if (level > maxLevel) {
|
|
104
|
-
log.warn('Invalid compression level %d. Will use %d.', level, maxLevel)
|
|
105
|
-
level = maxLevel
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Default to either zstd (on Node.js 24+) or gzip (earlier Node.js). We could default to ztsd
|
|
110
|
-
// everywhere as we ship a Rust zstd compressor for older Node.js versions, but on 24+ we use
|
|
111
|
-
// the built-in one that runs asynchronously on libuv worker threads, just as gzip does. This is
|
|
112
|
-
// the least disruptive choice.
|
|
113
|
-
if (uploadCompression === 'on') {
|
|
114
|
-
uploadCompression = isAtLeast24 ? 'zstd' : 'gzip'
|
|
115
|
-
}
|
|
20
|
+
/** @typedef {import('../config/config-base')} TracerConfig */
|
|
21
|
+
/** @typedef {AgentExporter | FileExporter} ProfilingExporter */
|
|
22
|
+
/** @typedef {WallProfiler | SpaceProfiler | EventsProfiler} ProfilingProfiler */
|
|
23
|
+
|
|
24
|
+
/** @param {TracerConfig} config */
|
|
25
|
+
function getProfilingTags (config) {
|
|
26
|
+
const functionName = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME')
|
|
27
|
+
|
|
28
|
+
const tags = {
|
|
29
|
+
...config.tags,
|
|
30
|
+
...tagger.parse({
|
|
31
|
+
host: config.reportHostname ? require('os').hostname() : undefined,
|
|
32
|
+
functionname: functionName,
|
|
33
|
+
}),
|
|
34
|
+
...getAzureTagsFromMetadata(getIsAzureFunction() ? getAzureFunctionMetadata() : getAzureAppMetadata()),
|
|
35
|
+
}
|
|
116
36
|
|
|
117
|
-
|
|
37
|
+
const { commitSHA, repositoryUrl } = getGitMetadata(config)
|
|
38
|
+
if (repositoryUrl && commitSHA) {
|
|
39
|
+
tags[GIT_REPOSITORY_URL] = repositoryUrl
|
|
40
|
+
tags[GIT_COMMIT_SHA] = commitSHA
|
|
41
|
+
}
|
|
118
42
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
log.warn('DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set %s, it will have no effect.', msg)
|
|
122
|
-
that.asyncContextFrameEnabled = false
|
|
123
|
-
}
|
|
43
|
+
return tags
|
|
44
|
+
}
|
|
124
45
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
46
|
+
/** @param {TracerConfig} config */
|
|
47
|
+
function getAsyncContextFrameEnabled (config) {
|
|
48
|
+
const enabled = config.DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED
|
|
49
|
+
if (enabled && !isACFActive) {
|
|
50
|
+
// The default value already tracks runtime support, so an unset config landing
|
|
51
|
+
// here is expected; only an explicit opt-in the runtime can't honor is worth a warning.
|
|
52
|
+
if (getValueFromEnvSources('DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED', true)) {
|
|
53
|
+
let reason
|
|
54
|
+
if (satisfies(process.versions.node, '>=24.0.0')) {
|
|
55
|
+
reason = 'with --no-async-context-frame'
|
|
129
56
|
} else if (satisfies(process.versions.node, '>=22.9.0')) {
|
|
130
|
-
|
|
57
|
+
reason = 'without --experimental-async-context-frame'
|
|
131
58
|
} else {
|
|
132
|
-
|
|
59
|
+
reason = 'but it requires at least Node.js 22.9.0'
|
|
133
60
|
}
|
|
61
|
+
log.warn('DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set %s, it will have no effect.', reason)
|
|
134
62
|
}
|
|
135
|
-
|
|
136
|
-
this.heartbeatInterval = options.telemetry.heartbeatInterval
|
|
137
|
-
|
|
138
|
-
this.profilers = ensureProfilers(profilers, this)
|
|
63
|
+
return false
|
|
139
64
|
}
|
|
65
|
+
return enabled
|
|
66
|
+
}
|
|
140
67
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
68
|
+
/**
|
|
69
|
+
* @param {TracerConfig} config
|
|
70
|
+
* @param {{
|
|
71
|
+
* asyncContextFrameEnabled: boolean,
|
|
72
|
+
* flushInterval: number,
|
|
73
|
+
* tags: Record<string, string>,
|
|
74
|
+
* exporters: ProfilingExporter[],
|
|
75
|
+
* }} runtime
|
|
76
|
+
*/
|
|
77
|
+
function createProfilers (config, { asyncContextFrameEnabled, flushInterval, tags, exporters }) {
|
|
78
|
+
const profilers = []
|
|
79
|
+
for (const name of selectProfilerTypes(config)) {
|
|
80
|
+
switch (name) {
|
|
81
|
+
case 'cpu':
|
|
82
|
+
case 'wall':
|
|
83
|
+
profilers.push(new WallProfiler(config, { asyncContextFrameEnabled, flushInterval }))
|
|
84
|
+
break
|
|
85
|
+
case 'space':
|
|
86
|
+
profilers.push(new SpaceProfiler(config, { tags, exporters }))
|
|
87
|
+
break
|
|
88
|
+
default:
|
|
89
|
+
log.error('Unknown profiler "%s"', name)
|
|
157
90
|
}
|
|
158
|
-
delete report.oomMonitoring.exportCommand
|
|
159
|
-
return report
|
|
160
91
|
}
|
|
161
|
-
}
|
|
162
92
|
|
|
163
|
-
|
|
93
|
+
// The events profiler produces timeline events. It is only added if timeline
|
|
94
|
+
// is enabled and there's a wall profiler.
|
|
95
|
+
if (config.DD_PROFILING_TIMELINE_ENABLED && profilers.some(profiler => profiler instanceof WallProfiler)) {
|
|
96
|
+
profilers.push(new EventsProfiler(config, { flushInterval }))
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return profilers
|
|
100
|
+
}
|
|
164
101
|
|
|
165
|
-
|
|
102
|
+
/** @param {TracerConfig} config */
|
|
103
|
+
function selectProfilerTypes ({
|
|
166
104
|
DD_PROFILING_HEAP_ENABLED,
|
|
167
105
|
DD_PROFILING_WALLTIME_ENABLED,
|
|
168
106
|
DD_PROFILING_PROFILERS,
|
|
@@ -214,81 +152,74 @@ function getProfilers ({
|
|
|
214
152
|
return profilersArray
|
|
215
153
|
}
|
|
216
154
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return strategy
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function ensureOOMExportStrategies (strategies) {
|
|
226
|
-
const set = new Set()
|
|
227
|
-
for (const strategy of strategies) {
|
|
228
|
-
set.add(getExportStrategy(strategy))
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return [...set]
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function getExporter (name, options) {
|
|
155
|
+
/**
|
|
156
|
+
* @param {string} name
|
|
157
|
+
* @param {TracerConfig} config
|
|
158
|
+
*/
|
|
159
|
+
function getExporter (name, config) {
|
|
235
160
|
switch (name) {
|
|
236
161
|
case 'agent':
|
|
237
|
-
return new AgentExporter(
|
|
162
|
+
return new AgentExporter(config)
|
|
238
163
|
case 'file':
|
|
239
|
-
return new FileExporter(
|
|
164
|
+
return new FileExporter(config)
|
|
240
165
|
default:
|
|
241
166
|
log.error('Unknown exporter "%s"', name)
|
|
242
167
|
}
|
|
243
168
|
}
|
|
244
169
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
for (let i = 0; i < profilers.length; i++) {
|
|
265
|
-
const profiler = getProfiler(profilers[i], options)
|
|
266
|
-
if (profiler !== undefined) {
|
|
267
|
-
filteredProfilers.push(profiler)
|
|
170
|
+
/**
|
|
171
|
+
* Assembles everything the profiler needs from the tracer config: the runtime objects (tags,
|
|
172
|
+
* exporters, profilers) the {@link import('./profiler').Profiler#start} consumes and the system
|
|
173
|
+
* info report sent with each profile. The leaves read the canonical DD_PROFILING_* fields straight
|
|
174
|
+
* off the config; only the genuinely runtime values (tags, exporters, the resolved async context
|
|
175
|
+
* frame flag, the flush interval) are derived here.
|
|
176
|
+
*
|
|
177
|
+
* @param {TracerConfig} config
|
|
178
|
+
*/
|
|
179
|
+
function buildProfilingRuntime (config) {
|
|
180
|
+
const tags = getProfilingTags(config)
|
|
181
|
+
const exporters = []
|
|
182
|
+
for (const name of config.DD_PROFILING_EXPORTERS) {
|
|
183
|
+
const exporter = getExporter(name, config)
|
|
184
|
+
// getExporter logs and returns undefined for an unknown exporter name; drop it so a misconfigured
|
|
185
|
+
// DD_PROFILING_EXPORTERS entry can't crash the export path later.
|
|
186
|
+
if (exporter !== undefined) {
|
|
187
|
+
exporters.push(exporter)
|
|
268
188
|
}
|
|
269
189
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
190
|
+
const asyncContextFrameEnabled = getAsyncContextFrameEnabled(config)
|
|
191
|
+
const flushInterval = config.DD_PROFILING_UPLOAD_PERIOD * 1000
|
|
192
|
+
const profilers = createProfilers(config, { asyncContextFrameEnabled, flushInterval, tags, exporters })
|
|
193
|
+
const uploadCompression = config.DD_PROFILING_DEBUG_UPLOAD_COMPRESSION
|
|
194
|
+
|
|
195
|
+
const oomMonitoringEnabled = config.DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED
|
|
196
|
+
const systemInfoReport = {
|
|
197
|
+
allocationProfilingEnabled: config.DD_PROFILING_ALLOCATION_ENABLED,
|
|
198
|
+
asyncContextFrameEnabled,
|
|
199
|
+
codeHotspotsEnabled: config.DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
200
|
+
cpuProfilingEnabled: config.DD_PROFILING_CPU_ENABLED,
|
|
201
|
+
debugSourceMaps: config.DD_PROFILING_DEBUG_SOURCE_MAPS,
|
|
202
|
+
endpointCollectionEnabled: config.DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
203
|
+
heapSamplingInterval: config.DD_PROFILING_HEAP_SAMPLING_INTERVAL,
|
|
204
|
+
oomMonitoring: {
|
|
205
|
+
enabled: oomMonitoringEnabled,
|
|
206
|
+
heapLimitExtensionSize: config.DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
207
|
+
maxHeapExtensionCount: config.DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
208
|
+
exportStrategies: oomMonitoringEnabled
|
|
209
|
+
? ensureOOMExportStrategies(config.DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES)
|
|
210
|
+
: [],
|
|
211
|
+
},
|
|
212
|
+
profilerTypes: profilers.map(profiler => profiler.type),
|
|
213
|
+
sourceMap: config.DD_PROFILING_SOURCE_MAP,
|
|
214
|
+
timelineEnabled: config.DD_PROFILING_TIMELINE_ENABLED,
|
|
215
|
+
timelineSamplingEnabled: config.DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED,
|
|
216
|
+
uploadCompression: { ...uploadCompression },
|
|
217
|
+
v8ProfilerBugWorkaroundEnabled: config.DD_PROFILING_V8_PROFILER_BUG_WORKAROUND,
|
|
275
218
|
}
|
|
276
219
|
|
|
277
|
-
return
|
|
220
|
+
return { tags, exporters, flushInterval, profilers, uploadCompression, systemInfoReport }
|
|
278
221
|
}
|
|
279
222
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
['snapshot', snapshotKinds.ON_OUT_OF_MEMORY]].map(([key, value]) => `${key}:${value}`).join(',')
|
|
283
|
-
const urls = []
|
|
284
|
-
for (const exporter of options.exporters) {
|
|
285
|
-
if (exporter instanceof AgentExporter) {
|
|
286
|
-
urls.push(options.url.toString())
|
|
287
|
-
} else if (exporter instanceof FileExporter) {
|
|
288
|
-
urls.push(pathToFileURL(options.pprofPrefix).toString())
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return [process.execPath,
|
|
292
|
-
path.join(__dirname, 'exporter_cli.js'),
|
|
293
|
-
urls.join(','), tags, 'space']
|
|
223
|
+
module.exports = {
|
|
224
|
+
buildProfilingRuntime,
|
|
294
225
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// 99hz in milliseconds.
|
|
4
|
+
const SAMPLING_INTERVAL = 1e3 / 99
|
|
5
|
+
|
|
3
6
|
const snapshotKinds = Object.freeze({
|
|
4
7
|
PERIODIC: 'periodic',
|
|
5
8
|
ON_SHUTDOWN: 'on_shutdown',
|
|
6
9
|
ON_OUT_OF_MEMORY: 'on_oom',
|
|
7
10
|
})
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
PROCESS: 'process',
|
|
11
|
-
ASYNC_CALLBACK: 'async',
|
|
12
|
-
LOGS: 'logs',
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
module.exports = { snapshotKinds, oomExportStrategies }
|
|
12
|
+
module.exports = { SAMPLING_INTERVAL, snapshotKinds }
|
|
@@ -15,20 +15,20 @@ const timeoutMs = 15 * 1000
|
|
|
15
15
|
|
|
16
16
|
function exporterFromURL (url) {
|
|
17
17
|
if (url.protocol === 'file:') {
|
|
18
|
-
return new FileExporter({
|
|
18
|
+
return new FileExporter({}, fileURLToPath(url))
|
|
19
19
|
}
|
|
20
|
+
// The subprocess has no tracer config, so mirror the canonical config property
|
|
21
|
+
// names the exporters read. Normalize the raw env to the parsed profiling.DD_PROFILING_ENABLED
|
|
22
|
+
// values ('true' | 'false' | 'auto') the main process would have produced.
|
|
20
23
|
const profilingEnabled = (getValueFromEnvSources('DD_PROFILING_ENABLED') ?? '').toLowerCase()
|
|
21
|
-
const
|
|
22
|
-
? '
|
|
23
|
-
: profilingEnabled
|
|
24
|
-
? 'auto'
|
|
25
|
-
: 'unknown'
|
|
24
|
+
const enabled = profilingEnabled === 'auto'
|
|
25
|
+
? 'auto'
|
|
26
|
+
: ['true', '1'].includes(profilingEnabled) ? 'true' : 'false'
|
|
26
27
|
return new AgentExporter({
|
|
27
28
|
url,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
activation,
|
|
29
|
+
DD_PROFILING_UPLOAD_TIMEOUT: timeoutMs,
|
|
30
|
+
DD_INJECTION_ENABLED: getValueFromEnvSources('DD_INJECTION_ENABLED'),
|
|
31
|
+
profiling: { DD_PROFILING_ENABLED: enabled },
|
|
32
32
|
})
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
const { request: httpRequest } = require('http')
|
|
4
4
|
const { request: httpsRequest } = require('https')
|
|
5
5
|
const perf = require('perf_hooks').performance
|
|
6
|
-
const { urlToHttpOptions } = require('url')
|
|
7
6
|
|
|
8
7
|
const retry = require('../../../../../vendor/dist/retry')
|
|
9
8
|
// TODO: avoid using dd-trace internals. Make this a separate module?
|
|
10
9
|
const docker = require('../../exporters/common/docker')
|
|
11
10
|
const FormData = require('../../exporters/common/form-data')
|
|
11
|
+
const { parseUrl } = require('../../exporters/common/url')
|
|
12
12
|
const log = require('../../log')
|
|
13
13
|
const { storage } = require('../../../../datadog-core')
|
|
14
14
|
const version = require('../../../../../package.json').version
|
|
@@ -88,15 +88,22 @@ function computeRetries (uploadTimeout) {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
class AgentExporter extends EventSerializer {
|
|
91
|
-
|
|
91
|
+
#backoffTime
|
|
92
|
+
#backoffTries
|
|
93
|
+
|
|
94
|
+
/** @param {import('./event_serializer').TracerConfig} config */
|
|
95
|
+
constructor (config) {
|
|
92
96
|
super(config)
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
this._url = config.url
|
|
98
|
+
|
|
99
|
+
const [backoffTries, backoffTime] = computeRetries(config.DD_PROFILING_UPLOAD_TIMEOUT)
|
|
95
100
|
|
|
96
|
-
|
|
101
|
+
this.#backoffTime = backoffTime
|
|
102
|
+
this.#backoffTries = backoffTries
|
|
103
|
+
}
|
|
97
104
|
|
|
98
|
-
|
|
99
|
-
this.
|
|
105
|
+
getExportUrl () {
|
|
106
|
+
return this._url
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
export (exportSpec) {
|
|
@@ -128,8 +135,8 @@ class AgentExporter extends EventSerializer {
|
|
|
128
135
|
return new Promise((resolve, reject) => {
|
|
129
136
|
const operation = retry.operation({
|
|
130
137
|
randomize: true,
|
|
131
|
-
minTimeout: this
|
|
132
|
-
retries: this
|
|
138
|
+
minTimeout: this.#backoffTime,
|
|
139
|
+
retries: this.#backoffTries,
|
|
133
140
|
unref: true,
|
|
134
141
|
})
|
|
135
142
|
|
|
@@ -148,18 +155,18 @@ class AgentExporter extends EventSerializer {
|
|
|
148
155
|
'DD-EVP-ORIGIN-VERSION': version,
|
|
149
156
|
...form.getHeaders(),
|
|
150
157
|
},
|
|
151
|
-
timeout: this
|
|
158
|
+
timeout: this.#backoffTime * 2 ** attempt,
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
docker.inject(options.headers)
|
|
155
162
|
|
|
156
|
-
|
|
157
|
-
|
|
163
|
+
const url = parseUrl(this._url)
|
|
164
|
+
if (url.protocol === 'unix:') {
|
|
165
|
+
options.socketPath = url.pathname
|
|
158
166
|
} else {
|
|
159
|
-
|
|
160
|
-
options.
|
|
161
|
-
options.
|
|
162
|
-
options.port = httpOptions.port
|
|
167
|
+
options.protocol = url.protocol
|
|
168
|
+
options.hostname = url.hostname
|
|
169
|
+
options.port = url.port
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
@@ -8,16 +8,47 @@ const version = require('../../../../../package.json').version
|
|
|
8
8
|
const { availableParallelism, libuvThreadPoolSize } = require('../libuv-size')
|
|
9
9
|
const processTags = require('../../process-tags')
|
|
10
10
|
|
|
11
|
+
/** @typedef {import('../../config/config-base')} TracerConfig */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Maps the canonical profiling.DD_PROFILING_ENABLED value to the activation reported in the
|
|
15
|
+
* profile event.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} [enabled] - config.profiling.DD_PROFILING_ENABLED ('true' | 'false' | 'auto')
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
function getActivation (enabled) {
|
|
21
|
+
if (enabled === 'auto') return 'auto'
|
|
22
|
+
if (enabled === 'true') return 'manual'
|
|
23
|
+
return 'unknown'
|
|
24
|
+
}
|
|
25
|
+
|
|
11
26
|
class EventSerializer {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
27
|
+
#activation
|
|
28
|
+
#appVersion
|
|
29
|
+
#env
|
|
30
|
+
#host
|
|
31
|
+
#libraryInjected
|
|
32
|
+
#service
|
|
33
|
+
|
|
34
|
+
/** @param {TracerConfig} config */
|
|
35
|
+
constructor (config) {
|
|
36
|
+
this.#env = config.env
|
|
37
|
+
this.#host = config.reportHostname ? os.hostname() : undefined
|
|
38
|
+
this.#service = config.service
|
|
39
|
+
this.#appVersion = config.version
|
|
40
|
+
this.#libraryInjected = !!config.DD_INJECTION_ENABLED
|
|
41
|
+
this.#activation = getActivation(config.profiling?.DD_PROFILING_ENABLED)
|
|
19
42
|
}
|
|
20
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Returns the destination URL for the near-OOM export subprocess, or nothing when this exporter
|
|
46
|
+
* does not support OOM export. Overridden by {@link AgentExporter} and {@link FileExporter}.
|
|
47
|
+
*
|
|
48
|
+
* @returns {URL | undefined}
|
|
49
|
+
*/
|
|
50
|
+
getExportUrl () {}
|
|
51
|
+
|
|
21
52
|
typeToFile (type) {
|
|
22
53
|
return `${type}.pprof`
|
|
23
54
|
}
|
|
@@ -43,21 +74,21 @@ class EventSerializer {
|
|
|
43
74
|
endpoint_counts: endpointCounts,
|
|
44
75
|
info: {
|
|
45
76
|
application: {
|
|
46
|
-
env: this
|
|
47
|
-
service: this
|
|
77
|
+
env: this.#env,
|
|
78
|
+
service: this.#service,
|
|
48
79
|
start_time: new Date(perf.nodeTiming.nodeStart + perf.timeOrigin).toISOString(),
|
|
49
|
-
version: this
|
|
80
|
+
version: this.#appVersion,
|
|
50
81
|
},
|
|
51
82
|
platform: {
|
|
52
|
-
hostname: this
|
|
83
|
+
hostname: this.#host,
|
|
53
84
|
kernel_name: os.type(),
|
|
54
85
|
kernel_release: os.release(),
|
|
55
86
|
kernel_version: os.version(),
|
|
56
87
|
},
|
|
57
88
|
profiler: {
|
|
58
|
-
activation: this
|
|
89
|
+
activation: this.#activation,
|
|
59
90
|
ssi: {
|
|
60
|
-
mechanism: this
|
|
91
|
+
mechanism: this.#libraryInjected ? 'injected_agent' : 'none',
|
|
61
92
|
},
|
|
62
93
|
version,
|
|
63
94
|
...infos,
|
|
@@ -92,4 +123,4 @@ class EventSerializer {
|
|
|
92
123
|
}
|
|
93
124
|
}
|
|
94
125
|
|
|
95
|
-
module.exports = { EventSerializer }
|
|
126
|
+
module.exports = { EventSerializer, getActivation }
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const { promisify } = require('util')
|
|
5
|
+
const { pathToFileURL } = require('url')
|
|
5
6
|
const { threadId } = require('worker_threads')
|
|
6
7
|
const writeFile = promisify(fs.writeFile)
|
|
7
8
|
const { EventSerializer } = require('./event_serializer')
|
|
@@ -10,14 +11,24 @@ const pad = (n) => String(n).padStart(2, '0')
|
|
|
10
11
|
|
|
11
12
|
function formatDateTime (t) {
|
|
12
13
|
return `${t.getUTCFullYear()}${pad(t.getUTCMonth() + 1)}${pad(t.getUTCDate())}` +
|
|
13
|
-
|
|
14
|
+
`T${pad(t.getUTCHours())}${pad(t.getUTCMinutes())}${pad(t.getUTCSeconds())}Z`
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
class FileExporter extends EventSerializer {
|
|
17
|
-
|
|
18
|
+
#pprofPrefix
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('./event_serializer').TracerConfig} config
|
|
22
|
+
* @param {string} [pprofPrefix] - File path prefix. Defaults to the config value, but the OOM
|
|
23
|
+
* export subprocess passes a path derived from a `file:` URL, which is not a config value.
|
|
24
|
+
*/
|
|
25
|
+
constructor (config, pprofPrefix = config.DD_PROFILING_PPROF_PREFIX) {
|
|
18
26
|
super(config)
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
this.#pprofPrefix = pprofPrefix
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getExportUrl () {
|
|
31
|
+
return pathToFileURL(this.#pprofPrefix)
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
export (exportSpec) {
|
|
@@ -25,7 +36,7 @@ class FileExporter extends EventSerializer {
|
|
|
25
36
|
const types = Object.keys(profiles)
|
|
26
37
|
const dateStr = formatDateTime(end)
|
|
27
38
|
const tasks = types.map(type => {
|
|
28
|
-
return writeFile(`${this
|
|
39
|
+
return writeFile(`${this.#pprofPrefix}${type}_worker_${threadId}_${dateStr}.pprof`, profiles[type])
|
|
29
40
|
})
|
|
30
41
|
tasks.push(writeFile(`event_worker_${threadId}_${dateStr}.json`, this.getEventJSON(exportSpec)))
|
|
31
42
|
return Promise.all(tasks)
|