dd-trace 6.4.0 → 6.6.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.electron.md +7 -0
- package/README.md +17 -0
- package/ci/diagnose.js +2100 -0
- package/ci/init.js +23 -2
- package/ci/runbook.md +198 -0
- package/ci/test-optimization-validation/approval-artifacts.js +143 -0
- package/ci/test-optimization-validation/approval.js +299 -0
- package/ci/test-optimization-validation/artifact-id.js +20 -0
- package/ci/test-optimization-validation/bounded-json.js +121 -0
- package/ci/test-optimization-validation/ci-command-candidate.js +83 -0
- package/ci/test-optimization-validation/ci-discovery.js +181 -0
- package/ci/test-optimization-validation/ci-remediation.js +210 -0
- package/ci/test-optimization-validation/cli.js +903 -0
- package/ci/test-optimization-validation/command-blocker.js +81 -0
- package/ci/test-optimization-validation/command-output-policy.js +206 -0
- package/ci/test-optimization-validation/command-runner.js +707 -0
- package/ci/test-optimization-validation/command-suitability.js +471 -0
- package/ci/test-optimization-validation/executable-approval.js +48 -0
- package/ci/test-optimization-validation/executable.js +480 -0
- package/ci/test-optimization-validation/generated-file-policy.js +63 -0
- package/ci/test-optimization-validation/generated-files.js +351 -0
- package/ci/test-optimization-validation/generated-verifier.js +196 -0
- package/ci/test-optimization-validation/init-probe-preload.js +163 -0
- package/ci/test-optimization-validation/init-probe.js +246 -0
- package/ci/test-optimization-validation/late-initialization.js +63 -0
- package/ci/test-optimization-validation/local-command.js +163 -0
- package/ci/test-optimization-validation/manifest-loader.js +133 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +738 -0
- package/ci/test-optimization-validation/manifest-schema.js +862 -0
- package/ci/test-optimization-validation/offline-fixtures.js +327 -0
- package/ci/test-optimization-validation/offline-output.js +406 -0
- package/ci/test-optimization-validation/payload-normalizer.js +72 -0
- package/ci/test-optimization-validation/plan-writer.js +1120 -0
- package/ci/test-optimization-validation/preflight-runner.js +114 -0
- package/ci/test-optimization-validation/redaction.js +331 -0
- package/ci/test-optimization-validation/report-writer.js +1508 -0
- package/ci/test-optimization-validation/safe-files.js +203 -0
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +159 -0
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +657 -0
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +780 -0
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +141 -0
- package/ci/test-optimization-validation/scenarios/helpers.js +539 -0
- package/ci/test-optimization-validation/scenarios/test-management.js +218 -0
- package/ci/test-optimization-validation/setup-runner.js +97 -0
- package/ci/test-optimization-validation/static-diagnosis.js +159 -0
- package/ci/test-optimization-validation/test-output.js +129 -0
- package/ci/test-optimization-validation-manifest.schema.json +1 -0
- package/ci/validate-test-optimization.js +3 -0
- package/ext/exporters.js +1 -0
- package/index.d.ts +121 -8
- package/init.js +18 -0
- package/initialize.mjs +1 -1
- package/loader-hook.mjs +28 -18
- package/openfeature.d.ts +1 -0
- package/openfeature.js +4 -0
- package/package.json +11 -8
- package/packages/datadog-instrumentations/src/ai.js +8 -2
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +9 -3
- package/packages/datadog-instrumentations/src/cucumber.js +31 -19
- package/packages/datadog-instrumentations/src/cypress-config.js +398 -52
- package/packages/datadog-instrumentations/src/fastify.js +7 -11
- package/packages/datadog-instrumentations/src/helpers/channel.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +8 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +28 -2
- package/packages/datadog-instrumentations/src/jest.js +44 -17
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -32
- package/packages/datadog-instrumentations/src/mocha/utils.js +0 -4
- package/packages/datadog-instrumentations/src/mongodb.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/mquery.js +2 -2
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +24 -0
- package/packages/datadog-instrumentations/src/nyc.js +0 -2
- package/packages/datadog-instrumentations/src/oracledb.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/playwright.js +162 -46
- package/packages/datadog-instrumentations/src/process.js +3 -0
- package/packages/datadog-instrumentations/src/router.js +18 -8
- package/packages/datadog-instrumentations/src/selenium.js +52 -26
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +3 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +14 -28
- package/packages/datadog-instrumentations/src/vitest-util.js +0 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +5 -8
- package/packages/datadog-instrumentations/src/ws.js +2 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +3 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -57
- package/packages/datadog-plugin-cypress/src/index.js +6 -1
- package/packages/datadog-plugin-cypress/src/support.js +92 -26
- package/packages/datadog-plugin-electron/src/ipc.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +87 -45
- package/packages/datadog-plugin-graphql/src/validate.js +2 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -1
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -1
- package/packages/datadog-plugin-playwright/src/index.js +181 -65
- package/packages/datadog-plugin-router/src/index.js +11 -2
- package/packages/datadog-plugin-selenium/src/index.js +5 -36
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/datadog-plugin-ws/src/close.js +2 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -1
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/datadog-plugin-ws/src/server.js +2 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +3 -1
- package/packages/dd-trace/src/azure_metadata.js +2 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +93 -28
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +160 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +288 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/payload-projection.js +84 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +369 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +60 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +41 -3
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +6 -2
- package/packages/dd-trace/src/ci-visibility/rum.js +7 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +137 -9
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +168 -8
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +90 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +16 -0
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +10 -0
- package/packages/dd-trace/src/config/supported-configurations.json +66 -0
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/common/client-library-headers.js +21 -0
- package/packages/dd-trace/src/exporters/common/request.js +59 -30
- package/packages/dd-trace/src/exporters/common/url.js +15 -1
- package/packages/dd-trace/src/feature-registry.js +10 -3
- package/packages/dd-trace/src/llmobs/experiments/client.js +113 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +154 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +283 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +152 -0
- package/packages/dd-trace/src/llmobs/experiments/noop.js +30 -0
- package/packages/dd-trace/src/llmobs/experiments/result.js +34 -0
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +20 -3
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +8 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +48 -14
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +43 -0
- package/packages/dd-trace/src/llmobs/sdk.js +17 -0
- package/packages/dd-trace/src/llmobs/tagger.js +68 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
- package/packages/dd-trace/src/llmobs/util.js +32 -0
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +322 -0
- package/packages/dd-trace/src/openfeature/configuration_source.js +90 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +14 -23
- package/packages/dd-trace/src/openfeature/index.js +0 -2
- package/packages/dd-trace/src/openfeature/noop.js +1 -28
- package/packages/dd-trace/src/openfeature/register.js +16 -27
- package/packages/dd-trace/src/openfeature/remote_config.js +15 -18
- package/packages/dd-trace/src/openfeature/require-provider.js +18 -0
- package/packages/dd-trace/src/opentelemetry/span-ending-hook.js +10 -0
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -6
- package/packages/dd-trace/src/plugins/util/git.js +3 -2
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +29 -5
- package/packages/dd-trace/src/plugins/util/test.js +56 -4
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +84 -7
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/standalone/index.js +0 -14
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- package/packages/dd-trace/src/util.js +26 -0
- 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/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-instrumentations/src/helpers/require-optional-peer.js +0 -17
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { isLoopbackHost } = require('../exporters/common/url')
|
|
4
|
+
const log = require('../log')
|
|
5
|
+
|
|
6
|
+
const DEFAULT_AGENTLESS_PATH = '/api/v2/feature-flagging/config/rules-based/server'
|
|
7
|
+
const MAX_POLL_INTERVAL_SECONDS = 60 * 60
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('@datadog/openfeature-node-server').UniversalFlagConfigurationV1} UniversalFlagConfiguration
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {import('../config/config-base')} config
|
|
15
|
+
* @param {(configuration: UniversalFlagConfiguration) => void} applyConfiguration
|
|
16
|
+
*/
|
|
17
|
+
function create (config, applyConfiguration) {
|
|
18
|
+
const {
|
|
19
|
+
DD_FEATURE_FLAGS_CONFIGURATION_SOURCE: source,
|
|
20
|
+
DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL: baseUrl,
|
|
21
|
+
DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS: pollIntervalSeconds,
|
|
22
|
+
DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS: requestTimeoutSeconds,
|
|
23
|
+
DD_FEATURE_FLAGS_ENABLED: enabled,
|
|
24
|
+
} = config.featureFlags
|
|
25
|
+
|
|
26
|
+
if (!enabled || source !== 'agentless') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
if (!config.DD_API_KEY) {
|
|
32
|
+
throw new Error('DD_API_KEY is required for Feature Flagging agentless delivery')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const AgentlessConfigurationSource = require('./agentless_configuration_source')
|
|
36
|
+
return new AgentlessConfigurationSource({
|
|
37
|
+
endpoint: endpoint(config, baseUrl),
|
|
38
|
+
pollIntervalMs: Math.min(pollIntervalSeconds, MAX_POLL_INTERVAL_SECONDS) * 1000,
|
|
39
|
+
requestTimeoutMs: requestTimeoutSeconds * 1000,
|
|
40
|
+
apiKey: config.DD_API_KEY,
|
|
41
|
+
}, applyConfiguration)
|
|
42
|
+
} catch (error) {
|
|
43
|
+
log.error('Unable to configure Feature Flagging configuration source', error)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Builds the agentless rules-based server endpoint.
|
|
49
|
+
*
|
|
50
|
+
* A configured URL with a non-root path is treated as the exact endpoint. A
|
|
51
|
+
* configured origin (or root URL) receives the standard rules-based server
|
|
52
|
+
* path.
|
|
53
|
+
*
|
|
54
|
+
* @param {import('../config/config-base')} config - Tracer configuration.
|
|
55
|
+
* @param {string | undefined} configuredBaseUrl - Optional endpoint or origin override.
|
|
56
|
+
* @returns {URL} Agentless endpoint.
|
|
57
|
+
*/
|
|
58
|
+
function endpoint (config, configuredBaseUrl) {
|
|
59
|
+
const configured = configuredBaseUrl?.trim()
|
|
60
|
+
|
|
61
|
+
if (!configured) {
|
|
62
|
+
const url = new URL(`https://ufc-server.ff-cdn.${config.site.toLowerCase()}${DEFAULT_AGENTLESS_PATH}`)
|
|
63
|
+
if (config.env) url.searchParams.set('dd_env', config.env)
|
|
64
|
+
return url
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let url
|
|
68
|
+
try {
|
|
69
|
+
url = new URL(configured)
|
|
70
|
+
} catch {
|
|
71
|
+
throw new Error('Invalid Feature Flagging agentless URL')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
|
|
75
|
+
throw new Error('Feature Flagging agentless URL must use HTTP or HTTPS')
|
|
76
|
+
}
|
|
77
|
+
if (url.protocol === 'http:' && !isLoopbackHost(url.hostname)) {
|
|
78
|
+
throw new Error('Feature Flagging agentless URL must use HTTPS unless it targets loopback')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (url.pathname === '' || url.pathname === '/') {
|
|
82
|
+
url.pathname = DEFAULT_AGENTLESS_PATH
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return url
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
create,
|
|
90
|
+
}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { channel } = require('dc-polyfill')
|
|
4
|
-
const requireOptionalPeer = require('../../../datadog-instrumentations/src/helpers/require-optional-peer')
|
|
5
4
|
const log = require('../log')
|
|
5
|
+
const configurationSource = require('./configuration_source')
|
|
6
6
|
const { EXPOSURE_CHANNEL } = require('./constants/constants')
|
|
7
7
|
const EvalMetricsHook = require('./eval-metrics-hook')
|
|
8
8
|
const SpanEnrichmentHook = require('./span-enrichment-hook')
|
|
9
9
|
|
|
10
|
-
const { DatadogNodeServerProvider } =
|
|
10
|
+
const { DatadogNodeServerProvider } = require('./require-provider')
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* OpenFeature provider that integrates with Datadog's feature flagging system.
|
|
14
14
|
* Extends DatadogNodeServerProvider to add tracer integration and configuration management.
|
|
15
15
|
*/
|
|
16
16
|
class FlaggingProvider extends DatadogNodeServerProvider {
|
|
17
|
-
/** @type {SpanEnrichmentHook
|
|
17
|
+
/** @type {SpanEnrichmentHook | undefined} */
|
|
18
18
|
#spanEnrichmentHook
|
|
19
19
|
|
|
20
|
+
/** @type {{ start: Function, stop: Function } | undefined} */
|
|
21
|
+
#configurationSource
|
|
22
|
+
|
|
20
23
|
/**
|
|
21
24
|
* @param {import('../tracer')} tracer - Datadog tracer instance
|
|
22
|
-
* @param {import('../config')} config - Tracer configuration object
|
|
25
|
+
* @param {import('../config/config-base')} config - Tracer configuration object
|
|
23
26
|
*/
|
|
24
27
|
constructor (tracer, config) {
|
|
25
|
-
// Call parent constructor with required options and timeout
|
|
26
28
|
super({
|
|
27
29
|
exposureChannel: channel(EXPOSURE_CHANNEL),
|
|
28
30
|
initializationTimeoutMs: config.experimental.flaggingProvider.initializationTimeoutMs,
|
|
29
31
|
})
|
|
30
32
|
|
|
31
|
-
this._tracer = tracer
|
|
32
|
-
this._config = config
|
|
33
|
-
|
|
34
33
|
this.hooks.push(new EvalMetricsHook(config))
|
|
35
34
|
|
|
36
35
|
if (config.experimental.flaggingProvider.spanEnrichment?.enabled) {
|
|
37
36
|
this.#spanEnrichmentHook = new SpanEnrichmentHook(tracer)
|
|
37
|
+
// @ts-expect-error The upstream constructor always initializes its optional hooks property.
|
|
38
38
|
this.hooks.push(this.#spanEnrichmentHook)
|
|
39
39
|
log.info('%s span enrichment enabled', this.constructor.name)
|
|
40
40
|
} else {
|
|
@@ -43,6 +43,9 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
43
43
|
|
|
44
44
|
log.debug('%s created with timeout: %dms', this.constructor.name,
|
|
45
45
|
config.experimental.flaggingProvider.initializationTimeoutMs)
|
|
46
|
+
|
|
47
|
+
this.#configurationSource = configurationSource.create(config, this.setConfiguration.bind(this))
|
|
48
|
+
this.#configurationSource?.start()
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
/**
|
|
@@ -50,22 +53,10 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
50
53
|
* Cleans up resources including channel subscriptions.
|
|
51
54
|
*/
|
|
52
55
|
onClose () {
|
|
56
|
+
this.#configurationSource?.stop()
|
|
57
|
+
this.#configurationSource = undefined
|
|
53
58
|
this.#spanEnrichmentHook?.destroy()
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Internal method to update flag configuration from Remote Config.
|
|
58
|
-
* This method is called automatically when Remote Config delivers UFC updates.
|
|
59
|
-
*
|
|
60
|
-
* @internal
|
|
61
|
-
* @param {import('@datadog/openfeature-node-server').UniversalFlagConfigurationV1} ufc
|
|
62
|
-
* - Universal Flag Configuration object
|
|
63
|
-
*/
|
|
64
|
-
_setConfiguration (ufc) {
|
|
65
|
-
if (typeof this.setConfiguration === 'function') {
|
|
66
|
-
this.setConfiguration(ufc)
|
|
67
|
-
}
|
|
68
|
-
log.debug('%s provider configuration updated', this.constructor.name)
|
|
59
|
+
this.#spanEnrichmentHook = undefined
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
62
|
|
|
@@ -20,12 +20,7 @@ function resolveDefault (defaultValue) {
|
|
|
20
20
|
* https://openfeature.dev/docs/reference/concepts/provider/
|
|
21
21
|
*/
|
|
22
22
|
class NoopFlaggingProvider {
|
|
23
|
-
|
|
24
|
-
* @param {object} [noopTracer] - Optional noop tracer instance
|
|
25
|
-
*/
|
|
26
|
-
constructor (noopTracer) {
|
|
27
|
-
this._tracer = noopTracer
|
|
28
|
-
this._config = {}
|
|
23
|
+
constructor () {
|
|
29
24
|
this.metadata = { name: 'NoopFlaggingProvider' }
|
|
30
25
|
this.status = 'NOT_READY'
|
|
31
26
|
this.runsOn = 'server'
|
|
@@ -78,28 +73,6 @@ class NoopFlaggingProvider {
|
|
|
78
73
|
resolveObjectEvaluation (flagKey, defaultValue, context, logger) {
|
|
79
74
|
return resolveDefault(defaultValue)
|
|
80
75
|
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @returns {object} Current configuration
|
|
84
|
-
*/
|
|
85
|
-
getConfiguration () {
|
|
86
|
-
return this._config
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @param {object} config - Configuration to set
|
|
91
|
-
*/
|
|
92
|
-
setConfiguration (config) {
|
|
93
|
-
this._config = config
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @internal
|
|
98
|
-
* @param {object} ufc - Universal Flag Configuration object
|
|
99
|
-
*/
|
|
100
|
-
_setConfiguration (ufc) {
|
|
101
|
-
this.setConfiguration(ufc)
|
|
102
|
-
}
|
|
103
76
|
}
|
|
104
77
|
|
|
105
78
|
module.exports = NoopFlaggingProvider
|
|
@@ -4,43 +4,32 @@ const { registerFeature } = require('../feature-registry')
|
|
|
4
4
|
|
|
5
5
|
const noop = new (require('./noop'))()
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* @param {import('../proxy')} proxy
|
|
9
|
-
* @returns {boolean}
|
|
10
|
-
*/
|
|
11
|
-
function hasFlaggingProvider (proxy) {
|
|
12
|
-
const descriptor = Reflect.getOwnPropertyDescriptor(proxy, 'openfeature')
|
|
13
|
-
|
|
14
|
-
return descriptor?.value !== undefined && descriptor.value !== noop
|
|
15
|
-
}
|
|
7
|
+
/** @typedef {import('../proxy') & { openfeature: object }} OpenFeatureProxy */
|
|
16
8
|
|
|
17
9
|
registerFeature({
|
|
18
10
|
name: 'openfeature',
|
|
19
11
|
noop,
|
|
20
12
|
factory: () => require('./index'),
|
|
13
|
+
provider: () => require('./flagging_provider'),
|
|
21
14
|
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* @param {import('../proxy')} proxy
|
|
26
|
-
*/
|
|
27
|
-
remoteConfig (rc, config, proxy) {
|
|
28
|
-
const openfeatureRemoteConfig = require('./remote_config')
|
|
29
|
-
openfeatureRemoteConfig.enable(rc, config, () => proxy.openfeature)
|
|
15
|
+
/** @param {import('../config/config-base')} config */
|
|
16
|
+
isEnabled (config) {
|
|
17
|
+
return config.featureFlags.DD_FEATURE_FLAGS_ENABLED
|
|
30
18
|
},
|
|
31
19
|
|
|
32
20
|
/**
|
|
21
|
+
* @param {import('../remote_config')} rc - RemoteConfig instance
|
|
33
22
|
* @param {import('../config/config-base')} config
|
|
34
|
-
* @param {
|
|
35
|
-
* @param {import('../proxy')} proxy
|
|
36
|
-
* @param {Function} lazyProxy
|
|
23
|
+
* @param {OpenFeatureProxy} proxy
|
|
37
24
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
25
|
+
remoteConfig (rc, config, proxy) {
|
|
26
|
+
const openfeatureRemoteConfig = require('./remote_config')
|
|
27
|
+
const subscribe = config.featureFlags.DD_FEATURE_FLAGS_ENABLED &&
|
|
28
|
+
config.featureFlags.DD_FEATURE_FLAGS_CONFIGURATION_SOURCE === 'remote_config'
|
|
29
|
+
openfeatureRemoteConfig.enable(
|
|
30
|
+
rc,
|
|
31
|
+
() => proxy.openfeature,
|
|
32
|
+
subscribe
|
|
33
|
+
)
|
|
45
34
|
},
|
|
46
35
|
})
|
|
@@ -5,30 +5,27 @@ const RemoteConfigCapabilities = require('../remote_config/capabilities')
|
|
|
5
5
|
/**
|
|
6
6
|
* Configures remote config handlers for openfeature feature flagging
|
|
7
7
|
*
|
|
8
|
-
* @param {
|
|
9
|
-
* @param {
|
|
10
|
-
* @param {
|
|
8
|
+
* @param {import('../remote_config')} rc - RemoteConfig instance
|
|
9
|
+
* @param {() => import('./flagging_provider')} getOpenfeatureProxy
|
|
10
|
+
* @param {boolean} subscribe - Whether Agent Remote Config owns UFC delivery
|
|
11
11
|
*/
|
|
12
|
-
function enable (rc,
|
|
13
|
-
|
|
14
|
-
// This indicates the library supports this capability via remote config
|
|
15
|
-
rc.updateCapabilities(RemoteConfigCapabilities.FFE_FLAG_CONFIGURATION_RULES, true)
|
|
12
|
+
function enable (rc, getOpenfeatureProxy, subscribe) {
|
|
13
|
+
if (!subscribe) return
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
if (!config.experimental.flaggingProvider.enabled) return
|
|
15
|
+
rc.updateCapabilities(RemoteConfigCapabilities.FFE_FLAG_CONFIGURATION_RULES, true)
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} action
|
|
19
|
+
* @param {import('@datadog/openfeature-node-server').UniversalFlagConfigurationV1} conf
|
|
20
|
+
*/
|
|
21
|
+
const updateConfiguration = (action, conf) => {
|
|
22
22
|
if (action === 'apply' || action === 'modify') {
|
|
23
|
-
|
|
24
|
-
getOpenfeatureProxy()._setConfiguration(conf)
|
|
23
|
+
getOpenfeatureProxy().setConfiguration(conf)
|
|
25
24
|
} else if (action === 'unapply') {
|
|
26
|
-
|
|
27
|
-
// consistent with Go and Python which also set config to null on RC deletion.
|
|
28
|
-
// The evaluator returns PROVIDER_NOT_READY when config is null/undefined.
|
|
29
|
-
getOpenfeatureProxy()._setConfiguration(null)
|
|
25
|
+
getOpenfeatureProxy().setConfiguration(undefined)
|
|
30
26
|
}
|
|
31
|
-
}
|
|
27
|
+
}
|
|
28
|
+
rc.setProductHandler('FFE_FLAGS', updateConfiguration)
|
|
32
29
|
}
|
|
33
30
|
|
|
34
31
|
module.exports = {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/** @type {(request: string) => typeof import('@datadog/openfeature-node-server')} */
|
|
4
|
+
let requireOptionalPeer
|
|
5
|
+
|
|
6
|
+
// @ts-expect-error webpack exposes this escape hatch as a free variable.
|
|
7
|
+
// eslint-disable-next-line camelcase
|
|
8
|
+
if (typeof __non_webpack_require__ === 'function') {
|
|
9
|
+
// eslint-disable-next-line camelcase, no-undef
|
|
10
|
+
requireOptionalPeer = __non_webpack_require__
|
|
11
|
+
} else {
|
|
12
|
+
// nft recognizes createRequire through a binding named `module`.
|
|
13
|
+
const module = require('node:module')
|
|
14
|
+
const runtimeRequire = module.createRequire(__filename)
|
|
15
|
+
requireOptionalPeer = runtimeRequire
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = requireOptionalPeer('@datadog/openfeature-node-server')
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Pre-finish hook for OTel-bridge spans. `Span.end()` runs it before `finish()` formats and
|
|
4
|
+
// (synchronously, for the last span in a trace) exports the trace, so a framework instrumentation
|
|
5
|
+
// can rewrite the operation name / resource while the DD span is still unfinished; `onEnd` only sees
|
|
6
|
+
// the already-built payload. Its own dependency-free module so an instrumentation can register
|
|
7
|
+
// without loading the OTel bridge, and a plain holder so the caller gates on `hook` existing.
|
|
8
|
+
|
|
9
|
+
/** @type {{ hook: ((ddSpan: import('../opentracing/span')) => void) | undefined }} */
|
|
10
|
+
module.exports = { hook: undefined }
|
|
@@ -15,6 +15,7 @@ const kinds = require('../../../../ext/kinds')
|
|
|
15
15
|
const id = require('../id')
|
|
16
16
|
const BridgeSpanBase = require('./bridge-span-base')
|
|
17
17
|
const SpanContext = require('./span_context')
|
|
18
|
+
const spanEndingHook = require('./span-ending-hook')
|
|
18
19
|
const { setOtelOperationName, setOtelResource } = require('./span-helpers')
|
|
19
20
|
|
|
20
21
|
const spanKindNames = {
|
|
@@ -255,6 +256,10 @@ class Span extends BridgeSpanBase {
|
|
|
255
256
|
const hrEndTime = timeInputToHrTime(timeInput || (performance.now() + timeOrigin))
|
|
256
257
|
const endTime = hrTimeToMilliseconds(hrEndTime)
|
|
257
258
|
|
|
259
|
+
// Must run before `finish()`, while the DD span is still unfinished. See span-ending-hook.js.
|
|
260
|
+
if (spanEndingHook.hook !== undefined) {
|
|
261
|
+
spanEndingHook.hook(this._ddSpan)
|
|
262
|
+
}
|
|
258
263
|
this._ddSpan.finish(endTime)
|
|
259
264
|
this._spanProcessor.onEnd(this)
|
|
260
265
|
}
|
|
@@ -181,6 +181,9 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
181
181
|
}
|
|
182
182
|
this.tracer._exporter.getLibraryConfiguration(this.testConfiguration, (err, libraryConfig) => {
|
|
183
183
|
if (err) {
|
|
184
|
+
this.libraryConfig = undefined
|
|
185
|
+
this.itrCorrelationId = undefined
|
|
186
|
+
this.skippableSuitesCoverage = undefined
|
|
184
187
|
log.error('Library configuration could not be fetched. %s', err.message)
|
|
185
188
|
this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_SETTINGS, err)
|
|
186
189
|
} else {
|
|
@@ -955,17 +958,28 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
955
958
|
}
|
|
956
959
|
log.debug('Removing all Dynamic Instrumentation probes')
|
|
957
960
|
const promises = []
|
|
958
|
-
for (const
|
|
959
|
-
|
|
960
|
-
promises.push(this.removeDiProbe({ file, line }))
|
|
961
|
+
for (const [activeProbeKey, probeId] of this.fileLineToProbeId) {
|
|
962
|
+
promises.push(this.#removeDiProbe(activeProbeKey, probeId))
|
|
961
963
|
}
|
|
962
964
|
return Promise.all(promises)
|
|
963
965
|
}
|
|
964
966
|
|
|
967
|
+
/**
|
|
968
|
+
* @param {{ file: string, line: number }} location
|
|
969
|
+
*/
|
|
965
970
|
removeDiProbe ({ file, line }) {
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
this
|
|
971
|
+
const activeProbeKey = `${file}:${line}`
|
|
972
|
+
const probeId = this.fileLineToProbeId.get(activeProbeKey)
|
|
973
|
+
return this.#removeDiProbe(activeProbeKey, probeId)
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* @param {string} activeProbeKey
|
|
978
|
+
* @param {string|undefined} probeId
|
|
979
|
+
*/
|
|
980
|
+
#removeDiProbe (activeProbeKey, probeId) {
|
|
981
|
+
log.warn('Removing probe from %s, with id: %s', activeProbeKey, probeId)
|
|
982
|
+
this.fileLineToProbeId.delete(activeProbeKey)
|
|
969
983
|
return this.di.removeProbe(probeId)
|
|
970
984
|
}
|
|
971
985
|
|
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
TELEMETRY_GIT_COMMAND_ERRORS,
|
|
14
14
|
} = require('../../ci-visibility/telemetry')
|
|
15
15
|
const { storage } = require('../../../../datadog-core')
|
|
16
|
+
const { getSegment } = require('../../util')
|
|
16
17
|
const {
|
|
17
18
|
GIT_COMMIT_SHA,
|
|
18
19
|
GIT_BRANCH,
|
|
@@ -251,7 +252,7 @@ function getGitRemoteName () {
|
|
|
251
252
|
)
|
|
252
253
|
|
|
253
254
|
if (upstreamRemote) {
|
|
254
|
-
return upstreamRemote
|
|
255
|
+
return getSegment(upstreamRemote, '/', 0)
|
|
255
256
|
}
|
|
256
257
|
|
|
257
258
|
const remotes = sanitizedExec(
|
|
@@ -263,7 +264,7 @@ function getGitRemoteName () {
|
|
|
263
264
|
false
|
|
264
265
|
)
|
|
265
266
|
|
|
266
|
-
return remotes
|
|
267
|
+
return getSegment(remotes, '\n', 0) || 'origin'
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
function getSourceBranch () {
|
|
@@ -26,14 +26,27 @@ const supportedProxies = {
|
|
|
26
26
|
'aws-apigateway': {
|
|
27
27
|
spanName: 'aws.apigateway',
|
|
28
28
|
component: 'aws-apigateway',
|
|
29
|
+
providesTimestamp: true,
|
|
29
30
|
},
|
|
30
31
|
'aws-httpapi': {
|
|
31
32
|
spanName: 'aws.httpapi',
|
|
32
33
|
component: 'aws-httpapi',
|
|
34
|
+
providesTimestamp: true,
|
|
33
35
|
},
|
|
34
36
|
'azure-apim': {
|
|
35
37
|
spanName: 'azure.apim',
|
|
36
38
|
component: 'azure-apim',
|
|
39
|
+
providesTimestamp: true,
|
|
40
|
+
},
|
|
41
|
+
'azure-gw': {
|
|
42
|
+
spanName: 'azure.app-gateway',
|
|
43
|
+
component: 'azure-gw',
|
|
44
|
+
providesTimestamp: false,
|
|
45
|
+
},
|
|
46
|
+
'azure-fd': {
|
|
47
|
+
spanName: 'azure.frontdoor',
|
|
48
|
+
component: 'azure-fd',
|
|
49
|
+
providesTimestamp: false,
|
|
37
50
|
},
|
|
38
51
|
}
|
|
39
52
|
|
|
@@ -109,21 +122,32 @@ function setInferredProxySpanTags (span, proxyContext) {
|
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
function extractInferredProxyContext (headers) {
|
|
112
|
-
if (!(
|
|
125
|
+
if (!(PROXY_HEADER_SYSTEM in headers)) {
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
if (!Object.hasOwn(supportedProxies, headers[PROXY_HEADER_SYSTEM])) {
|
|
129
|
+
log.debug('Received headers to create inferred proxy span but headers include an unsupported proxy type: %s',
|
|
130
|
+
headers[PROXY_HEADER_SYSTEM])
|
|
131
|
+
|
|
113
132
|
return null
|
|
114
133
|
}
|
|
115
134
|
|
|
116
|
-
|
|
117
|
-
|
|
135
|
+
const detectedProxy = supportedProxies[headers[PROXY_HEADER_SYSTEM]]
|
|
136
|
+
|
|
137
|
+
if (detectedProxy.providesTimestamp && !headers[PROXY_HEADER_START_TIME_MS]) {
|
|
118
138
|
return null
|
|
119
139
|
}
|
|
120
140
|
|
|
121
141
|
return {
|
|
122
142
|
requestTime: headers[PROXY_HEADER_START_TIME_MS]
|
|
123
143
|
? Number.parseInt(headers[PROXY_HEADER_START_TIME_MS], 10)
|
|
124
|
-
:
|
|
144
|
+
: Date.now(),
|
|
125
145
|
method: headers[PROXY_HEADER_HTTPMETHOD],
|
|
126
|
-
path: headers[PROXY_HEADER_PATH]
|
|
146
|
+
path: headers[PROXY_HEADER_PATH]
|
|
147
|
+
? (headers[PROXY_HEADER_PATH].startsWith('/')
|
|
148
|
+
? headers[PROXY_HEADER_PATH]
|
|
149
|
+
: '/' + headers[PROXY_HEADER_PATH])
|
|
150
|
+
: headers[PROXY_HEADER_PATH],
|
|
127
151
|
stage: headers[PROXY_HEADER_STAGE],
|
|
128
152
|
domainName: headers[PROXY_HEADER_DOMAIN],
|
|
129
153
|
proxySystemName: headers[PROXY_HEADER_SYSTEM],
|
|
@@ -6,6 +6,7 @@ const { URL } = require('url')
|
|
|
6
6
|
const { getLageTestSessionName } = require('../../ci-visibility/lage')
|
|
7
7
|
const log = require('../../log')
|
|
8
8
|
const { getEnvironmentVariable } = require('../../config/helper')
|
|
9
|
+
const { getSegment } = require('../../util')
|
|
9
10
|
const satisfies = require('../../../../../vendor/dist/semifies')
|
|
10
11
|
|
|
11
12
|
const istanbul = require('../../../../../vendor/dist/istanbul-lib-coverage')
|
|
@@ -77,6 +78,11 @@ const {
|
|
|
77
78
|
*
|
|
78
79
|
* @typedef {{ service?: string, isServiceUserProvided?: boolean }} TestEnvironmentConfig
|
|
79
80
|
* @typedef {Record<string, string|number|undefined>} TestEnvironmentMetadata
|
|
81
|
+
* @typedef {{
|
|
82
|
+
* isRumActive?: boolean,
|
|
83
|
+
* browserVersion?: string,
|
|
84
|
+
* testExecutionId?: string
|
|
85
|
+
* }} RumTestCorrelationContext
|
|
80
86
|
*/
|
|
81
87
|
|
|
82
88
|
// session tags
|
|
@@ -130,7 +136,7 @@ const CI_APP_ORIGIN = 'ciapp-test'
|
|
|
130
136
|
// - Math.random() float values (10+ decimal digits after 0.)
|
|
131
137
|
const DYNAMIC_NAME_RE = new RegExp(
|
|
132
138
|
String.raw`\b1[6-9]\d{8,11}\b|` +
|
|
133
|
-
|
|
139
|
+
'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|' +
|
|
134
140
|
String.raw`\b\d{4}-\d{2}-\d{2}|` +
|
|
135
141
|
String.raw`(?:localhost|127\.0\.0\.1|0\.0\.0\.0):\d{4,5}\b|` +
|
|
136
142
|
String.raw`\b0\.\d{10,}`,
|
|
@@ -434,6 +440,8 @@ module.exports = {
|
|
|
434
440
|
TEST_PARAMETERS,
|
|
435
441
|
TEST_SKIP_REASON,
|
|
436
442
|
TEST_IS_RUM_ACTIVE,
|
|
443
|
+
setRumTestCorrelation,
|
|
444
|
+
setRumTestTags,
|
|
437
445
|
TEST_SOURCE_FILE,
|
|
438
446
|
TEST_FAILURE_SCREENSHOT_UPLOADED,
|
|
439
447
|
TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
|
|
@@ -567,7 +575,7 @@ module.exports = {
|
|
|
567
575
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
568
576
|
function getPkgManager () {
|
|
569
577
|
try {
|
|
570
|
-
return getEnvironmentVariable('npm_config_user_agent')
|
|
578
|
+
return getSegment(getEnvironmentVariable('npm_config_user_agent'), ' ', 0).replace('/', '-')
|
|
571
579
|
} catch {
|
|
572
580
|
return ''
|
|
573
581
|
}
|
|
@@ -798,6 +806,9 @@ function getTestTypeFromFramework (testFramework) {
|
|
|
798
806
|
return 'test'
|
|
799
807
|
}
|
|
800
808
|
|
|
809
|
+
/**
|
|
810
|
+
* @param {import('../../opentracing/span')} span
|
|
811
|
+
*/
|
|
801
812
|
function finishAllTraceSpans (span) {
|
|
802
813
|
for (const traceSpan of span.context()._trace.started) {
|
|
803
814
|
if (traceSpan !== span) {
|
|
@@ -806,6 +817,49 @@ function finishAllTraceSpans (span) {
|
|
|
806
817
|
}
|
|
807
818
|
}
|
|
808
819
|
|
|
820
|
+
/**
|
|
821
|
+
* @param {import('../../opentracing/span')} testSpan
|
|
822
|
+
* @param {boolean|undefined} isRumActive
|
|
823
|
+
* @param {string} [browserVersion]
|
|
824
|
+
* @returns {void}
|
|
825
|
+
*/
|
|
826
|
+
function setRumTestTags (testSpan, isRumActive, browserVersion) {
|
|
827
|
+
if (isRumActive) {
|
|
828
|
+
testSpan.setTag(TEST_IS_RUM_ACTIVE, 'true')
|
|
829
|
+
}
|
|
830
|
+
if (browserVersion) {
|
|
831
|
+
testSpan.setTag(TEST_BROWSER_VERSION, browserVersion)
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* @param {RumTestCorrelationContext} context
|
|
837
|
+
* @param {import('../../opentracing/span')|undefined} activeSpan
|
|
838
|
+
* @returns {import('../../opentracing/span')|undefined}
|
|
839
|
+
*/
|
|
840
|
+
function setRumTestCorrelation (context, activeSpan) {
|
|
841
|
+
if (!activeSpan) return
|
|
842
|
+
|
|
843
|
+
const activeContext = activeSpan.context()
|
|
844
|
+
let testSpan
|
|
845
|
+
if (activeContext.getTag(SPAN_TYPE) === 'test') {
|
|
846
|
+
testSpan = activeSpan
|
|
847
|
+
} else {
|
|
848
|
+
for (const traceSpan of activeContext._trace.started) {
|
|
849
|
+
if (traceSpan.context().getTag(SPAN_TYPE) === 'test') {
|
|
850
|
+
testSpan = traceSpan
|
|
851
|
+
break
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (!testSpan) return
|
|
857
|
+
|
|
858
|
+
context.testExecutionId = testSpan.context().toTraceId()
|
|
859
|
+
setRumTestTags(testSpan, context.isRumActive, context.browserVersion)
|
|
860
|
+
return testSpan
|
|
861
|
+
}
|
|
862
|
+
|
|
809
863
|
function getTestParentSpan (tracer) {
|
|
810
864
|
return tracer.extract('text_map', {
|
|
811
865
|
'x-datadog-trace-id': id().toString(10),
|
|
@@ -1360,7 +1414,6 @@ function resetCoverage (coverage) {
|
|
|
1360
1414
|
|
|
1361
1415
|
return coverageMap
|
|
1362
1416
|
.files()
|
|
1363
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1364
1417
|
.forEach(filename => {
|
|
1365
1418
|
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
1366
1419
|
fileCoverage.resetHits()
|
|
@@ -1371,7 +1424,6 @@ function mergeCoverage (coverage, targetCoverage) {
|
|
|
1371
1424
|
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
1372
1425
|
return coverageMap
|
|
1373
1426
|
.files()
|
|
1374
|
-
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1375
1427
|
.forEach(filename => {
|
|
1376
1428
|
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
1377
1429
|
|
|
@@ -59,7 +59,7 @@ class NativeSpaceProfiler {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
profile (restart) {
|
|
62
|
-
const profile = this.#pprof.heap.profile(undefined, this.#mapper, getThreadLabels)
|
|
62
|
+
const profile = this.#pprof.heap.profile(undefined, this.#mapper, getThreadLabels, 'pack')
|
|
63
63
|
if (!restart) {
|
|
64
64
|
this.stop()
|
|
65
65
|
}
|
|
@@ -187,6 +187,7 @@ class NativeWallProfiler {
|
|
|
187
187
|
|
|
188
188
|
this.#pprof.time.start({
|
|
189
189
|
collectCpuTime: this.#cpuProfilingEnabled,
|
|
190
|
+
columnNumbers: 'pack',
|
|
190
191
|
durationMillis: this.#flushIntervalMillis,
|
|
191
192
|
intervalMicros: this.#samplingIntervalMicros,
|
|
192
193
|
lineNumbers: false,
|