dd-trace 5.82.0 → 5.83.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 +78 -79
- package/ci/init.js +6 -6
- package/index.d.ts +152 -3
- package/loader-hook.mjs +1 -1
- package/package.json +58 -55
- package/packages/datadog-core/src/storage.js +7 -7
- package/packages/datadog-esbuild/index.js +6 -0
- package/packages/datadog-instrumentations/src/ai.js +7 -3
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +3 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +1 -1
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/jest.js +35 -14
- package/packages/datadog-instrumentations/src/koa.js +2 -1
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +2 -2
- package/packages/datadog-instrumentations/src/net.js +13 -5
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -4
- package/packages/datadog-instrumentations/src/pg.js +4 -2
- package/packages/datadog-instrumentations/src/playwright.js +3 -3
- package/packages/datadog-instrumentations/src/selenium.js +2 -2
- package/packages/datadog-instrumentations/src/undici.js +12 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +4 -4
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +2 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -2
- package/packages/datadog-plugin-express/src/code_origin.js +21 -15
- package/packages/datadog-plugin-fastify/src/code_origin.js +17 -4
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +3 -3
- package/packages/datadog-plugin-undici/src/index.js +305 -2
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/dd-trace/index.js +19 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +2 -4
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +36 -11
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -1
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/{config_defaults.js → config/defaults.js} +3 -3
- package/packages/dd-trace/src/{config-helper.js → config/helper.js} +88 -15
- package/packages/dd-trace/src/{config.js → config/index.js} +92 -45
- package/packages/dd-trace/src/config/remote_config.js +187 -19
- package/packages/dd-trace/src/{config_stable.js → config/stable.js} +20 -32
- package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json} +2 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +83 -15
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +2 -2
- package/packages/dd-trace/src/exporter.js +1 -1
- package/packages/dd-trace/src/exporters/agent/index.js +2 -4
- package/packages/dd-trace/src/exporters/agent/writer.js +9 -14
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +1 -1
- package/packages/dd-trace/src/exporters/common/docker.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/exporters/span-stats/index.js +1 -1
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
- package/packages/dd-trace/src/index.js +4 -4
- package/packages/dd-trace/src/lambda/handler.js +2 -2
- package/packages/dd-trace/src/lambda/index.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/patch.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +8 -1
- package/packages/dd-trace/src/llmobs/index.js +2 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +3 -4
- package/packages/dd-trace/src/llmobs/sdk.js +33 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +17 -7
- package/packages/dd-trace/src/llmobs/tagger.js +175 -1
- package/packages/dd-trace/src/llmobs/writers/base.js +116 -37
- package/packages/dd-trace/src/llmobs/writers/spans.js +4 -3
- package/packages/dd-trace/src/log/index.js +5 -5
- package/packages/dd-trace/src/noop/proxy.js +3 -3
- package/packages/dd-trace/src/openfeature/writers/base.js +7 -8
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +48 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +45 -21
- package/packages/dd-trace/src/opentracing/span.js +4 -4
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/util/ci.js +5 -8
- package/packages/dd-trace/src/plugins/util/git-cache.js +3 -3
- package/packages/dd-trace/src/plugins/util/test.js +1 -1
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +41 -43
- package/packages/dd-trace/src/profiler.js +4 -39
- package/packages/dd-trace/src/profiling/config.js +74 -31
- package/packages/dd-trace/src/profiling/exporter_cli.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +9 -2
- package/packages/dd-trace/src/profiling/index.js +1 -1
- package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +57 -2
- package/packages/dd-trace/src/proxy.js +34 -5
- package/packages/dd-trace/src/remote_config/capabilities.js +3 -0
- package/packages/dd-trace/src/remote_config/index.js +1 -1
- package/packages/dd-trace/src/ritm.js +8 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/serverless.js +2 -2
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/startup-log.js +6 -15
- package/packages/dd-trace/src/telemetry/endpoints.js +67 -5
- package/packages/dd-trace/src/telemetry/send-data.js +103 -4
- package/packages/dd-trace/src/telemetry/telemetry.js +229 -110
- /package/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
|
@@ -7,11 +7,11 @@ const crypto = require('crypto')
|
|
|
7
7
|
const cp = require('child_process')
|
|
8
8
|
|
|
9
9
|
const log = require('../../log')
|
|
10
|
-
const {
|
|
10
|
+
const { getValueFromEnvSources } = require('../../config/helper')
|
|
11
11
|
const { isTrue } = require('../../util')
|
|
12
12
|
|
|
13
|
-
let isGitEnabled = isTrue(
|
|
14
|
-
const GIT_CACHE_DIR =
|
|
13
|
+
let isGitEnabled = isTrue(getValueFromEnvSources('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED'))
|
|
14
|
+
const GIT_CACHE_DIR = getValueFromEnvSources('DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR') ||
|
|
15
15
|
path.join(os.tmpdir(), 'dd-trace-git-cache')
|
|
16
16
|
|
|
17
17
|
function ensureCacheDir () {
|
|
@@ -4,7 +4,7 @@ const path = require('path')
|
|
|
4
4
|
const fs = require('fs')
|
|
5
5
|
const { URL } = require('url')
|
|
6
6
|
const log = require('../../log')
|
|
7
|
-
const { getEnvironmentVariable } = require('../../config
|
|
7
|
+
const { getEnvironmentVariable } = require('../../config/helper')
|
|
8
8
|
const satisfies = require('../../../../../vendor/dist/semifies')
|
|
9
9
|
|
|
10
10
|
const istanbul = require('../../../../../vendor/dist/istanbul-lib-coverage')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { getValueFromEnvSources } = require('../../config/helper')
|
|
4
4
|
const {
|
|
5
5
|
GIT_COMMIT_SHA,
|
|
6
6
|
GIT_BRANCH,
|
|
@@ -21,16 +21,15 @@ const {
|
|
|
21
21
|
const { normalizeRef } = require('./ci')
|
|
22
22
|
const { filterSensitiveInfoFromRepository } = require('./url')
|
|
23
23
|
|
|
24
|
-
function removeEmptyValues (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
function removeEmptyValues (tagsAndValues) {
|
|
25
|
+
const filteredTags = {}
|
|
26
|
+
for (let i = 0; i < tagsAndValues.length; i += 2) {
|
|
27
|
+
const value = tagsAndValues[i + 1]
|
|
28
|
+
if (value) {
|
|
29
|
+
filteredTags[tagsAndValues[i]] = value
|
|
28
30
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
[tag]: tags[tag]
|
|
32
|
-
}
|
|
33
|
-
}, {})
|
|
31
|
+
}
|
|
32
|
+
return filteredTags
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
// The regex is inspired by
|
|
@@ -47,47 +46,46 @@ function validateGitCommitSha (gitCommitSha) {
|
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
function getUserProviderGitMetadata () {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
DD_GIT_COMMIT_HEAD_SHA
|
|
65
|
-
} = getEnvironmentVariables()
|
|
49
|
+
const DD_GIT_COMMIT_SHA = getValueFromEnvSources('DD_GIT_COMMIT_SHA')
|
|
50
|
+
const DD_GIT_BRANCH = getValueFromEnvSources('DD_GIT_BRANCH')
|
|
51
|
+
const DD_GIT_REPOSITORY_URL = getValueFromEnvSources('DD_GIT_REPOSITORY_URL')
|
|
52
|
+
const DD_GIT_TAG = getValueFromEnvSources('DD_GIT_TAG')
|
|
53
|
+
const DD_GIT_COMMIT_MESSAGE = getValueFromEnvSources('DD_GIT_COMMIT_MESSAGE')
|
|
54
|
+
const DD_GIT_COMMIT_COMMITTER_NAME = getValueFromEnvSources('DD_GIT_COMMIT_COMMITTER_NAME')
|
|
55
|
+
const DD_GIT_COMMIT_COMMITTER_EMAIL = getValueFromEnvSources('DD_GIT_COMMIT_COMMITTER_EMAIL')
|
|
56
|
+
const DD_GIT_COMMIT_COMMITTER_DATE = getValueFromEnvSources('DD_GIT_COMMIT_COMMITTER_DATE')
|
|
57
|
+
const DD_GIT_COMMIT_AUTHOR_NAME = getValueFromEnvSources('DD_GIT_COMMIT_AUTHOR_NAME')
|
|
58
|
+
const DD_GIT_COMMIT_AUTHOR_EMAIL = getValueFromEnvSources('DD_GIT_COMMIT_AUTHOR_EMAIL')
|
|
59
|
+
const DD_GIT_COMMIT_AUTHOR_DATE = getValueFromEnvSources('DD_GIT_COMMIT_AUTHOR_DATE')
|
|
60
|
+
const DD_GIT_PULL_REQUEST_BASE_BRANCH = getValueFromEnvSources('DD_GIT_PULL_REQUEST_BASE_BRANCH')
|
|
61
|
+
const DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA = getValueFromEnvSources('DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA')
|
|
62
|
+
const DD_GIT_COMMIT_HEAD_SHA = getValueFromEnvSources('DD_GIT_COMMIT_HEAD_SHA')
|
|
66
63
|
|
|
67
64
|
const branch = normalizeRef(DD_GIT_BRANCH)
|
|
68
65
|
let tag = normalizeRef(DD_GIT_TAG)
|
|
69
66
|
|
|
70
67
|
// if DD_GIT_BRANCH is a tag, we associate its value to TAG too
|
|
71
|
-
if ((DD_GIT_BRANCH
|
|
68
|
+
if ((DD_GIT_BRANCH ?? '').includes('origin/tags') || (DD_GIT_BRANCH ?? '').includes('refs/heads/tags')) {
|
|
72
69
|
tag = normalizeRef(DD_GIT_BRANCH)
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
72
|
+
// Key value pairs are grouped in pairs of two
|
|
73
|
+
return removeEmptyValues([
|
|
74
|
+
GIT_COMMIT_SHA, DD_GIT_COMMIT_SHA,
|
|
75
|
+
GIT_BRANCH, branch,
|
|
76
|
+
GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository(DD_GIT_REPOSITORY_URL),
|
|
77
|
+
GIT_TAG, tag,
|
|
78
|
+
GIT_COMMIT_MESSAGE, DD_GIT_COMMIT_MESSAGE,
|
|
79
|
+
GIT_COMMIT_COMMITTER_NAME, DD_GIT_COMMIT_COMMITTER_NAME,
|
|
80
|
+
GIT_COMMIT_COMMITTER_DATE, DD_GIT_COMMIT_COMMITTER_DATE,
|
|
81
|
+
GIT_COMMIT_COMMITTER_EMAIL, DD_GIT_COMMIT_COMMITTER_EMAIL,
|
|
82
|
+
GIT_COMMIT_AUTHOR_NAME, DD_GIT_COMMIT_AUTHOR_NAME,
|
|
83
|
+
GIT_COMMIT_AUTHOR_EMAIL, DD_GIT_COMMIT_AUTHOR_EMAIL,
|
|
84
|
+
GIT_COMMIT_AUTHOR_DATE, DD_GIT_COMMIT_AUTHOR_DATE,
|
|
85
|
+
GIT_PULL_REQUEST_BASE_BRANCH, DD_GIT_PULL_REQUEST_BASE_BRANCH,
|
|
86
|
+
GIT_PULL_REQUEST_BASE_BRANCH_SHA, DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA,
|
|
87
|
+
GIT_COMMIT_HEAD_SHA, DD_GIT_COMMIT_HEAD_SHA
|
|
88
|
+
])
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
module.exports = { getUserProviderGitMetadata, validateGitRepositoryUrl, validateGitCommitSha }
|
|
@@ -1,49 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const log = require('./log')
|
|
4
3
|
const { profiler } = require('./profiling')
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
process.once('beforeExit', () => { profiler.stop() })
|
|
5
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(() => { profiler.stop() })
|
|
8
6
|
|
|
9
7
|
module.exports = {
|
|
10
8
|
start: config => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const logger = {
|
|
16
|
-
debug: (message) => log.debug(message),
|
|
17
|
-
info: (message) => log.info(message),
|
|
18
|
-
warn: (message) => log.warn(message),
|
|
19
|
-
error: (...args) => log.error(...args)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const libraryInjected = injectionEnabled.length > 0
|
|
23
|
-
let activation
|
|
24
|
-
if (enabled === 'auto') {
|
|
25
|
-
activation = 'auto'
|
|
26
|
-
} else if (enabled === 'true') {
|
|
27
|
-
activation = 'manual'
|
|
28
|
-
} // else activation = undefined
|
|
29
|
-
|
|
30
|
-
return profiler.start({
|
|
31
|
-
service,
|
|
32
|
-
version,
|
|
33
|
-
env,
|
|
34
|
-
logger,
|
|
35
|
-
sourceMap,
|
|
36
|
-
exporters,
|
|
37
|
-
url,
|
|
38
|
-
hostname,
|
|
39
|
-
port,
|
|
40
|
-
tags,
|
|
41
|
-
repositoryUrl,
|
|
42
|
-
commitSHA,
|
|
43
|
-
libraryInjected,
|
|
44
|
-
activation,
|
|
45
|
-
heartbeatInterval
|
|
46
|
-
})
|
|
9
|
+
// Forward the full tracer config to the profiling layer.
|
|
10
|
+
// Profiling code is responsible for deriving the specific options it needs.
|
|
11
|
+
return profiler.start(config)
|
|
47
12
|
},
|
|
48
13
|
|
|
49
14
|
stop: () => {
|
|
@@ -8,8 +8,7 @@ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
|
8
8
|
const { getIsAzureFunction } = require('../serverless')
|
|
9
9
|
const { isFalse, isTrue } = require('../util')
|
|
10
10
|
const { getAzureTagsFromMetadata, getAzureAppMetadata, getAzureFunctionMetadata } = require('../azure_metadata')
|
|
11
|
-
const {
|
|
12
|
-
const defaults = require('../config_defaults')
|
|
11
|
+
const { getEnvironmentVariable, getValueFromEnvSources } = require('../config/helper')
|
|
13
12
|
const { AgentExporter } = require('./exporters/agent')
|
|
14
13
|
const { FileExporter } = require('./exporters/file')
|
|
15
14
|
const { ConsoleLogger } = require('./loggers/console')
|
|
@@ -18,14 +17,16 @@ const SpaceProfiler = require('./profilers/space')
|
|
|
18
17
|
const EventsProfiler = require('./profilers/events')
|
|
19
18
|
const { oomExportStrategies, snapshotKinds } = require('./constants')
|
|
20
19
|
const { tagger } = require('./tagger')
|
|
21
|
-
|
|
22
20
|
class Config {
|
|
23
21
|
constructor (options = {}) {
|
|
22
|
+
// TODO: Remove entries that were already resolved in config.
|
|
23
|
+
// For the others, move them over to config.
|
|
24
|
+
const AWS_LAMBDA_FUNCTION_NAME = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME')
|
|
25
|
+
const NODE_OPTIONS = getEnvironmentVariable('NODE_OPTIONS')
|
|
26
|
+
|
|
27
|
+
// TODO: Move initialization of these values to packages/dd-trace/src/config/index.js, and just read from config
|
|
24
28
|
const {
|
|
25
|
-
|
|
26
|
-
DD_AGENT_HOST,
|
|
27
|
-
DD_ENV,
|
|
28
|
-
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing
|
|
29
|
+
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED,
|
|
29
30
|
DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED,
|
|
30
31
|
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
31
32
|
DD_PROFILING_CPU_ENABLED,
|
|
@@ -40,40 +41,37 @@ class Config {
|
|
|
40
41
|
DD_PROFILING_HEAP_SAMPLING_INTERVAL,
|
|
41
42
|
DD_PROFILING_PPROF_PREFIX,
|
|
42
43
|
DD_PROFILING_PROFILERS,
|
|
43
|
-
DD_PROFILING_SOURCE_MAP,
|
|
44
44
|
DD_PROFILING_TIMELINE_ENABLED,
|
|
45
45
|
DD_PROFILING_UPLOAD_PERIOD,
|
|
46
46
|
DD_PROFILING_UPLOAD_TIMEOUT,
|
|
47
47
|
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND,
|
|
48
48
|
DD_PROFILING_WALLTIME_ENABLED,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
DD_TRACE_AGENT_URL,
|
|
53
|
-
DD_VERSION,
|
|
54
|
-
NODE_OPTIONS
|
|
55
|
-
} = getEnvironmentVariables()
|
|
56
|
-
|
|
57
|
-
const env = options.env ?? DD_ENV
|
|
58
|
-
const service = options.service || DD_SERVICE || 'node'
|
|
49
|
+
DD_TAGS
|
|
50
|
+
} = getProfilingEnvValues()
|
|
51
|
+
|
|
59
52
|
const host = os.hostname()
|
|
60
|
-
const version = options.version ?? DD_VERSION
|
|
61
53
|
// Must be longer than one minute so pad with five seconds
|
|
62
54
|
const flushInterval = options.interval ?? (Number(DD_PROFILING_UPLOAD_PERIOD) * 1000 || 65 * 1000)
|
|
63
55
|
const uploadTimeout = options.uploadTimeout ?? (Number(DD_PROFILING_UPLOAD_TIMEOUT) || 60 * 1000)
|
|
64
|
-
const sourceMap = options.sourceMap ?? DD_PROFILING_SOURCE_MAP ?? true
|
|
65
56
|
const pprofPrefix = options.pprofPrefix ?? DD_PROFILING_PPROF_PREFIX ?? ''
|
|
66
57
|
|
|
67
|
-
|
|
68
|
-
this.
|
|
58
|
+
// TODO: Remove the fallback. Just use the value from the config.
|
|
59
|
+
this.service = options.service || 'node'
|
|
60
|
+
this.env = options.env
|
|
69
61
|
this.host = host
|
|
70
|
-
this.functionname =
|
|
62
|
+
this.functionname = AWS_LAMBDA_FUNCTION_NAME
|
|
71
63
|
|
|
72
|
-
this.version = version
|
|
64
|
+
this.version = options.version
|
|
73
65
|
this.tags = Object.assign(
|
|
74
66
|
tagger.parse(DD_TAGS),
|
|
75
67
|
tagger.parse(options.tags),
|
|
76
|
-
tagger.parse({
|
|
68
|
+
tagger.parse({
|
|
69
|
+
env: options.env,
|
|
70
|
+
host,
|
|
71
|
+
service: this.service,
|
|
72
|
+
version: this.version,
|
|
73
|
+
functionname: AWS_LAMBDA_FUNCTION_NAME
|
|
74
|
+
}),
|
|
77
75
|
getAzureTagsFromMetadata(getIsAzureFunction() ? getAzureFunctionMetadata() : getAzureAppMetadata())
|
|
78
76
|
)
|
|
79
77
|
|
|
@@ -104,7 +102,7 @@ class Config {
|
|
|
104
102
|
|
|
105
103
|
this.flushInterval = flushInterval
|
|
106
104
|
this.uploadTimeout = uploadTimeout
|
|
107
|
-
this.sourceMap = sourceMap
|
|
105
|
+
this.sourceMap = options.sourceMap
|
|
108
106
|
this.debugSourceMaps = isTrue(options.debugSourceMaps ?? DD_PROFILING_DEBUG_SOURCE_MAPS)
|
|
109
107
|
this.endpointCollectionEnabled = isTrue(options.endpointCollection ??
|
|
110
108
|
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED ?? samplingContextsAvailable)
|
|
@@ -113,12 +111,10 @@ class Config {
|
|
|
113
111
|
this.pprofPrefix = pprofPrefix
|
|
114
112
|
this.v8ProfilerBugWorkaroundEnabled = isTrue(options.v8ProfilerBugWorkaround ??
|
|
115
113
|
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND ?? true)
|
|
116
|
-
|
|
117
|
-
const port = (options.port ?? DD_TRACE_AGENT_PORT) || defaults.port
|
|
118
|
-
this.url = new URL(options.url ?? DD_TRACE_AGENT_URL ?? format({
|
|
114
|
+
this.url = new URL(options.url || format({
|
|
119
115
|
protocol: 'http:',
|
|
120
|
-
hostname,
|
|
121
|
-
port
|
|
116
|
+
hostname: options.hostname,
|
|
117
|
+
port: options.port
|
|
122
118
|
}))
|
|
123
119
|
|
|
124
120
|
this.libraryInjected = options.libraryInjected
|
|
@@ -439,3 +435,50 @@ function buildExportCommand (options) {
|
|
|
439
435
|
path.join(__dirname, 'exporter_cli.js'),
|
|
440
436
|
urls.join(','), tags, 'space']
|
|
441
437
|
}
|
|
438
|
+
|
|
439
|
+
function getProfilingEnvValues () {
|
|
440
|
+
return {
|
|
441
|
+
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED:
|
|
442
|
+
getValueFromEnvSources('DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED'),
|
|
443
|
+
DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED:
|
|
444
|
+
getValueFromEnvSources('DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED'),
|
|
445
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED:
|
|
446
|
+
getValueFromEnvSources('DD_PROFILING_CODEHOTSPOTS_ENABLED'),
|
|
447
|
+
DD_PROFILING_CPU_ENABLED:
|
|
448
|
+
getValueFromEnvSources('DD_PROFILING_CPU_ENABLED'),
|
|
449
|
+
DD_PROFILING_DEBUG_SOURCE_MAPS:
|
|
450
|
+
getValueFromEnvSources('DD_PROFILING_DEBUG_SOURCE_MAPS'),
|
|
451
|
+
DD_PROFILING_DEBUG_UPLOAD_COMPRESSION:
|
|
452
|
+
getValueFromEnvSources('DD_PROFILING_DEBUG_UPLOAD_COMPRESSION'),
|
|
453
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED:
|
|
454
|
+
getValueFromEnvSources('DD_PROFILING_ENDPOINT_COLLECTION_ENABLED'),
|
|
455
|
+
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES:
|
|
456
|
+
getValueFromEnvSources('DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES'),
|
|
457
|
+
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE:
|
|
458
|
+
getValueFromEnvSources('DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE'),
|
|
459
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT:
|
|
460
|
+
getValueFromEnvSources('DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT'),
|
|
461
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED:
|
|
462
|
+
getValueFromEnvSources('DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED'),
|
|
463
|
+
DD_PROFILING_HEAP_ENABLED:
|
|
464
|
+
getValueFromEnvSources('DD_PROFILING_HEAP_ENABLED'),
|
|
465
|
+
DD_PROFILING_HEAP_SAMPLING_INTERVAL:
|
|
466
|
+
getValueFromEnvSources('DD_PROFILING_HEAP_SAMPLING_INTERVAL'),
|
|
467
|
+
DD_PROFILING_PPROF_PREFIX:
|
|
468
|
+
getValueFromEnvSources('DD_PROFILING_PPROF_PREFIX'),
|
|
469
|
+
DD_PROFILING_PROFILERS:
|
|
470
|
+
getValueFromEnvSources('DD_PROFILING_PROFILERS'),
|
|
471
|
+
DD_PROFILING_TIMELINE_ENABLED:
|
|
472
|
+
getValueFromEnvSources('DD_PROFILING_TIMELINE_ENABLED'),
|
|
473
|
+
DD_PROFILING_UPLOAD_PERIOD:
|
|
474
|
+
getValueFromEnvSources('DD_PROFILING_UPLOAD_PERIOD'),
|
|
475
|
+
DD_PROFILING_UPLOAD_TIMEOUT:
|
|
476
|
+
getValueFromEnvSources('DD_PROFILING_UPLOAD_TIMEOUT'),
|
|
477
|
+
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND:
|
|
478
|
+
getValueFromEnvSources('DD_PROFILING_V8_PROFILER_BUG_WORKAROUND'),
|
|
479
|
+
DD_PROFILING_WALLTIME_ENABLED:
|
|
480
|
+
getValueFromEnvSources('DD_PROFILING_WALLTIME_ENABLED'),
|
|
481
|
+
DD_TAGS:
|
|
482
|
+
getValueFromEnvSources('DD_TAGS')
|
|
483
|
+
}
|
|
484
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const { fileURLToPath } = require('url')
|
|
5
5
|
const { SourceMapper, heap, encode } = require('@datadog/pprof')
|
|
6
|
-
const {
|
|
6
|
+
const { getValueFromEnvSources } = require('../config/helper')
|
|
7
7
|
const { AgentExporter } = require('./exporters/agent')
|
|
8
8
|
const { FileExporter } = require('./exporters/file')
|
|
9
9
|
|
|
@@ -17,9 +17,9 @@ function exporterFromURL (url) {
|
|
|
17
17
|
if (url.protocol === 'file:') {
|
|
18
18
|
return new FileExporter({ pprofPrefix: fileURLToPath(url) })
|
|
19
19
|
}
|
|
20
|
-
const injectionEnabled = (
|
|
20
|
+
const injectionEnabled = (getValueFromEnvSources('DD_INJECTION_ENABLED') ?? '').split(',')
|
|
21
21
|
const libraryInjected = injectionEnabled.length > 0
|
|
22
|
-
const profilingEnabled = (
|
|
22
|
+
const profilingEnabled = (getValueFromEnvSources('DD_PROFILING_ENABLED') ?? '').toLowerCase()
|
|
23
23
|
const activation = ['true', '1'].includes(profilingEnabled)
|
|
24
24
|
? 'manual'
|
|
25
25
|
: profilingEnabled === 'auto'
|
|
@@ -62,12 +62,12 @@ async function exportProfile (urls, tags, profileType, profile) {
|
|
|
62
62
|
* Expected command line arguments are:
|
|
63
63
|
* - Comma separated list of URLs (eg. "http://127.0.0.1:8126/,file:///tmp/foo.pprof")
|
|
64
64
|
* - Tags (eg. "service:nodejs_oom_test,version:1.0.0")
|
|
65
|
-
* -
|
|
65
|
+
* - Profile type (eg. space,wall,cpu)
|
|
66
66
|
* - JSON profile filepath
|
|
67
67
|
*/
|
|
68
68
|
const urls = process.argv[2].split(',').map(s => new URL(s))
|
|
69
69
|
const tags = tagger.parse(process.argv[3])
|
|
70
70
|
const profileType = process.argv[4]
|
|
71
|
-
const profile = JSON.parse(fs.readFileSync(process.argv[5]))
|
|
71
|
+
const profile = JSON.parse(fs.readFileSync(process.argv[5], 'utf8'))
|
|
72
72
|
|
|
73
73
|
exportProfile(urls, tags, profileType, profile)
|
|
@@ -6,6 +6,7 @@ const os = require('os')
|
|
|
6
6
|
const perf = require('perf_hooks').performance
|
|
7
7
|
const version = require('../../../../../package.json').version
|
|
8
8
|
const { availableParallelism, libuvThreadPoolSize } = require('../libuv-size')
|
|
9
|
+
const processTags = require('../../process-tags')
|
|
9
10
|
|
|
10
11
|
class EventSerializer {
|
|
11
12
|
constructor ({ env, host, service, version, libraryInjected, activation } = {}) {
|
|
@@ -22,7 +23,7 @@ class EventSerializer {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
getEventJSON ({ profiles, infos, start, end, tags = {}, endpointCounts }) {
|
|
25
|
-
|
|
26
|
+
const event = {
|
|
26
27
|
attachments: Object.keys(profiles).map(t => this.typeToFile(t)),
|
|
27
28
|
start: start.toISOString(),
|
|
28
29
|
end: end.toISOString(),
|
|
@@ -77,7 +78,13 @@ class EventSerializer {
|
|
|
77
78
|
version: process.version.slice(1)
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (processTags.serialized) {
|
|
84
|
+
event[processTags.PROFILING_FIELD_NAME] = processTags.serialized
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return JSON.stringify(event)
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getEnvironmentVariable } = require('../config
|
|
3
|
+
const { getEnvironmentVariable } = require('../config/helper')
|
|
4
4
|
const { Profiler, ServerlessProfiler } = require('./profiler')
|
|
5
5
|
const WallProfiler = require('./profilers/wall')
|
|
6
6
|
const SpaceProfiler = require('./profilers/space')
|
|
@@ -5,6 +5,7 @@ const { promisify } = require('util')
|
|
|
5
5
|
const zlib = require('zlib')
|
|
6
6
|
const dc = require('dc-polyfill')
|
|
7
7
|
const crashtracker = require('../crashtracking')
|
|
8
|
+
const log = require('../log')
|
|
8
9
|
const { Config } = require('./config')
|
|
9
10
|
const { snapshotKinds } = require('./constants')
|
|
10
11
|
const { threadNamePrefix } = require('./profilers/shared')
|
|
@@ -63,13 +64,64 @@ class Profiler extends EventEmitter {
|
|
|
63
64
|
this._timeoutInterval = undefined
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
get serverless () { return false }
|
|
68
|
+
|
|
66
69
|
get flushInterval () {
|
|
67
70
|
return this.#config?.flushInterval
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
start (
|
|
73
|
+
start (config) {
|
|
74
|
+
const {
|
|
75
|
+
service,
|
|
76
|
+
version,
|
|
77
|
+
env,
|
|
78
|
+
url,
|
|
79
|
+
hostname,
|
|
80
|
+
port,
|
|
81
|
+
tags,
|
|
82
|
+
repositoryUrl,
|
|
83
|
+
commitSHA,
|
|
84
|
+
injectionEnabled
|
|
85
|
+
} = config
|
|
86
|
+
const { enabled, sourceMap, exporters } = config.profiling
|
|
87
|
+
const { heartbeatInterval } = config.telemetry
|
|
88
|
+
|
|
89
|
+
// TODO: Unify with main logger and rewrite template strings to use printf formatting.
|
|
90
|
+
const logger = {
|
|
91
|
+
debug (message) { log.debug(message) },
|
|
92
|
+
info (message) { log.info(message) },
|
|
93
|
+
warn (message) { log.warn(message) },
|
|
94
|
+
error (...args) { log.error(...args) }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const libraryInjected = injectionEnabled.length > 0
|
|
98
|
+
let activation
|
|
99
|
+
if (enabled === 'auto') {
|
|
100
|
+
activation = 'auto'
|
|
101
|
+
} else if (enabled === 'true') {
|
|
102
|
+
activation = 'manual'
|
|
103
|
+
} // else activation = undefined
|
|
104
|
+
|
|
105
|
+
const options = {
|
|
106
|
+
service,
|
|
107
|
+
version,
|
|
108
|
+
env,
|
|
109
|
+
logger,
|
|
110
|
+
sourceMap,
|
|
111
|
+
exporters,
|
|
112
|
+
url,
|
|
113
|
+
hostname,
|
|
114
|
+
port,
|
|
115
|
+
tags,
|
|
116
|
+
repositoryUrl,
|
|
117
|
+
commitSHA,
|
|
118
|
+
libraryInjected,
|
|
119
|
+
activation,
|
|
120
|
+
heartbeatInterval
|
|
121
|
+
}
|
|
122
|
+
|
|
71
123
|
return this._start(options).catch((err) => {
|
|
72
|
-
logError(
|
|
124
|
+
logError(logger, 'Error starting profiler. For troubleshooting tips, see ' +
|
|
73
125
|
'<https://dtdg.co/nodejs-profiler-troubleshooting>', err)
|
|
74
126
|
return false
|
|
75
127
|
})
|
|
@@ -242,6 +294,7 @@ class Profiler extends EventEmitter {
|
|
|
242
294
|
|
|
243
295
|
#createInitialInfos () {
|
|
244
296
|
return {
|
|
297
|
+
serverless: this.serverless,
|
|
245
298
|
settings: this.#config.systemInfoReport
|
|
246
299
|
}
|
|
247
300
|
}
|
|
@@ -351,6 +404,8 @@ class ServerlessProfiler extends Profiler {
|
|
|
351
404
|
this.#flushAfterIntervals = undefined
|
|
352
405
|
}
|
|
353
406
|
|
|
407
|
+
get serverless () { return true }
|
|
408
|
+
|
|
354
409
|
get profiledIntervals () {
|
|
355
410
|
return this.#profiledIntervals
|
|
356
411
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const { getValueFromEnvSources } = require('./config/helper')
|
|
3
4
|
const NoopProxy = require('./noop/proxy')
|
|
4
5
|
const DatadogTracer = require('./tracer')
|
|
5
6
|
const getConfig = require('./config')
|
|
@@ -130,7 +131,10 @@ class Tracer extends NoopProxy {
|
|
|
130
131
|
const rc = new RemoteConfig(config)
|
|
131
132
|
|
|
132
133
|
const tracingRemoteConfig = require('./config/remote_config')
|
|
133
|
-
tracingRemoteConfig.enable(rc, config,
|
|
134
|
+
tracingRemoteConfig.enable(rc, config, () => {
|
|
135
|
+
this.#updateTracing(config)
|
|
136
|
+
this.#updateDebugger(config, rc)
|
|
137
|
+
})
|
|
134
138
|
|
|
135
139
|
rc.setProductHandler('AGENT_CONFIG', (action, conf) => {
|
|
136
140
|
if (!conf?.name?.startsWith('flare-log-level.')) return
|
|
@@ -183,7 +187,7 @@ class Tracer extends NoopProxy {
|
|
|
183
187
|
runtimeMetrics.start(config)
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
this
|
|
190
|
+
this.#updateTracing(config)
|
|
187
191
|
|
|
188
192
|
this._modules.rewriter.enable(config)
|
|
189
193
|
|
|
@@ -196,7 +200,7 @@ class Tracer extends NoopProxy {
|
|
|
196
200
|
this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
|
|
197
201
|
}
|
|
198
202
|
if (config.ciVisAgentlessLogSubmissionEnabled) {
|
|
199
|
-
if (
|
|
203
|
+
if (getValueFromEnvSources('DD_API_KEY')) {
|
|
200
204
|
const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
|
|
201
205
|
const automaticLogPlugin = new LogSubmissionPlugin(this)
|
|
202
206
|
automaticLogPlugin.configure({ ...config, enabled: true })
|
|
@@ -242,7 +246,7 @@ class Tracer extends NoopProxy {
|
|
|
242
246
|
}
|
|
243
247
|
}
|
|
244
248
|
|
|
245
|
-
|
|
249
|
+
#updateTracing (config) {
|
|
246
250
|
if (config.tracing !== false) {
|
|
247
251
|
if (config.appsec.enabled) {
|
|
248
252
|
this._modules.appsec.enable(config)
|
|
@@ -287,6 +291,31 @@ class Tracer extends NoopProxy {
|
|
|
287
291
|
}
|
|
288
292
|
}
|
|
289
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Updates the debugger (Dynamic Instrumentation) state based on remote config changes.
|
|
296
|
+
* Handles starting, stopping, and reconfiguring the debugger dynamically.
|
|
297
|
+
*
|
|
298
|
+
* @param {object} config - The tracer configuration object
|
|
299
|
+
* @param {object} rc - The RemoteConfig instance
|
|
300
|
+
*/
|
|
301
|
+
#updateDebugger (config, rc) {
|
|
302
|
+
const shouldBeEnabled = config.dynamicInstrumentation.enabled
|
|
303
|
+
const isCurrentlyStarted = DynamicInstrumentation.isStarted()
|
|
304
|
+
|
|
305
|
+
if (shouldBeEnabled) {
|
|
306
|
+
if (isCurrentlyStarted) {
|
|
307
|
+
log.debug('[proxy] Reconfiguring Dynamic Instrumentation via remote config')
|
|
308
|
+
DynamicInstrumentation.configure(config)
|
|
309
|
+
} else {
|
|
310
|
+
log.debug('[proxy] Starting Dynamic Instrumentation via remote config')
|
|
311
|
+
DynamicInstrumentation.start(config, rc)
|
|
312
|
+
}
|
|
313
|
+
} else if (isCurrentlyStarted) {
|
|
314
|
+
log.debug('[proxy] Stopping Dynamic Instrumentation via remote config')
|
|
315
|
+
DynamicInstrumentation.stop()
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
290
319
|
/**
|
|
291
320
|
* @override
|
|
292
321
|
*/
|
|
@@ -31,9 +31,12 @@ module.exports = {
|
|
|
31
31
|
ASM_NETWORK_FINGERPRINT: 1n << 34n,
|
|
32
32
|
ASM_HEADER_FINGERPRINT: 1n << 35n,
|
|
33
33
|
ASM_RASP_CMDI: 1n << 37n,
|
|
34
|
+
APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION: 1n << 38n,
|
|
35
|
+
APM_TRACING_ENABLE_CODE_ORIGIN: 1n << 40n,
|
|
34
36
|
ASM_DD_MULTICONFIG: 1n << 42n,
|
|
35
37
|
ASM_TRACE_TAGGING_RULES: 1n << 43n,
|
|
36
38
|
ASM_EXTENDED_DATA_COLLECTION: 1n << 44n,
|
|
39
|
+
APM_TRACING_MULTICONFIG: 1n << 45n,
|
|
37
40
|
FFE_FLAG_CONFIGURATION_RULES: 1n << 46n,
|
|
38
41
|
/*
|
|
39
42
|
DO NOT ADD ARBITRARY CAPABILITIES IN YOUR CODE
|
|
@@ -8,7 +8,7 @@ const log = require('../log')
|
|
|
8
8
|
const { getExtraServices } = require('../service-naming/extra-services')
|
|
9
9
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
10
10
|
const tagger = require('../tagger')
|
|
11
|
-
const defaults = require('../
|
|
11
|
+
const defaults = require('../config/defaults')
|
|
12
12
|
const processTags = require('../process-tags')
|
|
13
13
|
const Scheduler = require('./scheduler')
|
|
14
14
|
const { UNACKNOWLEDGED, ACKNOWLEDGED, ERROR } = require('./apply_states')
|