dd-trace 4.18.0 → 5.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.
Files changed (209) hide show
  1. package/CONTRIBUTING.md +98 -0
  2. package/LICENSE-3rdparty.csv +4 -5
  3. package/MIGRATING.md +15 -0
  4. package/README.md +20 -140
  5. package/ci/cypress/after-run.js +1 -0
  6. package/ci/cypress/after-spec.js +1 -0
  7. package/ci/init.js +1 -4
  8. package/ext/kinds.d.ts +1 -0
  9. package/ext/kinds.js +2 -1
  10. package/ext/tags.d.ts +2 -1
  11. package/ext/tags.js +6 -1
  12. package/index.d.ts +1523 -1460
  13. package/package.json +19 -19
  14. package/packages/datadog-core/src/storage/async_resource.js +1 -1
  15. package/packages/datadog-core/src/utils/src/get.js +11 -0
  16. package/packages/datadog-core/src/utils/src/has.js +14 -0
  17. package/packages/datadog-core/src/utils/src/kebabcase.js +16 -0
  18. package/packages/datadog-core/src/utils/src/pick.js +11 -0
  19. package/packages/datadog-core/src/utils/src/set.js +16 -0
  20. package/packages/datadog-core/src/utils/src/uniq.js +5 -0
  21. package/packages/datadog-esbuild/index.js +1 -20
  22. package/packages/datadog-instrumentations/src/aerospike.js +47 -0
  23. package/packages/datadog-instrumentations/src/amqplib.js +2 -2
  24. package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
  25. package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
  26. package/packages/datadog-instrumentations/src/child_process.js +150 -0
  27. package/packages/datadog-instrumentations/src/couchbase.js +5 -4
  28. package/packages/datadog-instrumentations/src/crypto.js +2 -1
  29. package/packages/datadog-instrumentations/src/cucumber.js +163 -46
  30. package/packages/datadog-instrumentations/src/dns.js +2 -1
  31. package/packages/datadog-instrumentations/src/express.js +20 -0
  32. package/packages/datadog-instrumentations/src/graphql.js +18 -4
  33. package/packages/datadog-instrumentations/src/grpc/client.js +56 -36
  34. package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
  35. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
  36. package/packages/datadog-instrumentations/src/helpers/hooks.js +12 -3
  37. package/packages/datadog-instrumentations/src/helpers/instrument.js +9 -4
  38. package/packages/datadog-instrumentations/src/helpers/register.js +19 -3
  39. package/packages/datadog-instrumentations/src/http/client.js +12 -2
  40. package/packages/datadog-instrumentations/src/http/server.js +7 -4
  41. package/packages/datadog-instrumentations/src/http2/client.js +3 -1
  42. package/packages/datadog-instrumentations/src/http2/server.js +3 -1
  43. package/packages/datadog-instrumentations/src/jest.js +239 -52
  44. package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
  45. package/packages/datadog-instrumentations/src/mocha.js +154 -18
  46. package/packages/datadog-instrumentations/src/mongodb-core.js +34 -3
  47. package/packages/datadog-instrumentations/src/mongoose.js +23 -10
  48. package/packages/datadog-instrumentations/src/mquery.js +65 -0
  49. package/packages/datadog-instrumentations/src/net.js +10 -2
  50. package/packages/datadog-instrumentations/src/next.js +35 -9
  51. package/packages/datadog-instrumentations/src/playwright.js +110 -16
  52. package/packages/datadog-instrumentations/src/restify.js +14 -1
  53. package/packages/datadog-instrumentations/src/rhea.js +15 -9
  54. package/packages/datadog-plugin-aerospike/src/index.js +113 -0
  55. package/packages/datadog-plugin-amqplib/src/consumer.js +14 -1
  56. package/packages/datadog-plugin-amqplib/src/producer.js +13 -1
  57. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
  58. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +163 -27
  59. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +46 -8
  60. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +129 -22
  61. package/packages/datadog-plugin-child_process/src/index.js +91 -0
  62. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +125 -0
  63. package/packages/datadog-plugin-cucumber/src/index.js +70 -13
  64. package/packages/datadog-plugin-cypress/src/after-run.js +3 -0
  65. package/packages/datadog-plugin-cypress/src/after-spec.js +3 -0
  66. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +625 -0
  67. package/packages/datadog-plugin-cypress/src/plugin.js +6 -454
  68. package/packages/datadog-plugin-cypress/src/support.js +50 -3
  69. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -0
  70. package/packages/datadog-plugin-graphql/src/index.js +1 -6
  71. package/packages/datadog-plugin-graphql/src/resolve.js +28 -18
  72. package/packages/datadog-plugin-grpc/src/client.js +16 -2
  73. package/packages/datadog-plugin-grpc/src/util.js +1 -1
  74. package/packages/datadog-plugin-http/src/client.js +19 -2
  75. package/packages/datadog-plugin-jest/src/index.js +118 -12
  76. package/packages/datadog-plugin-jest/src/util.js +38 -16
  77. package/packages/datadog-plugin-kafkajs/src/consumer.js +76 -6
  78. package/packages/datadog-plugin-kafkajs/src/producer.js +64 -8
  79. package/packages/datadog-plugin-mocha/src/index.js +87 -17
  80. package/packages/datadog-plugin-next/src/index.js +40 -14
  81. package/packages/datadog-plugin-playwright/src/index.js +71 -8
  82. package/packages/datadog-plugin-rhea/src/consumer.js +16 -1
  83. package/packages/datadog-plugin-rhea/src/producer.js +10 -0
  84. package/packages/dd-trace/src/appsec/activation.js +29 -0
  85. package/packages/dd-trace/src/appsec/addresses.js +5 -1
  86. package/packages/dd-trace/src/appsec/api_security_sampler.js +61 -0
  87. package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
  88. package/packages/dd-trace/src/appsec/blocking.js +95 -43
  89. package/packages/dd-trace/src/appsec/channels.js +7 -3
  90. package/packages/dd-trace/src/appsec/graphql.js +146 -0
  91. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -0
  92. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +1 -1
  93. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +105 -0
  94. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +22 -17
  95. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +7 -28
  96. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +10 -6
  97. package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +19 -0
  98. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +90 -0
  99. package/packages/dd-trace/src/appsec/iast/context/kafka-ctx-plugin.js +14 -0
  100. package/packages/dd-trace/src/appsec/iast/iast-log.js +1 -1
  101. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +13 -2
  102. package/packages/dd-trace/src/appsec/iast/index.js +15 -5
  103. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  104. package/packages/dd-trace/src/appsec/iast/path-line.js +1 -1
  105. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -0
  106. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +10 -0
  107. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +53 -0
  108. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +10 -46
  109. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +13 -9
  110. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +47 -0
  111. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +19 -6
  112. package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +3 -1
  113. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +41 -3
  114. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
  115. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +12 -19
  116. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +20 -0
  117. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +6 -10
  118. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +18 -25
  119. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +79 -85
  120. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +27 -36
  121. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +14 -11
  122. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
  123. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +2 -0
  124. package/packages/dd-trace/src/appsec/index.js +49 -33
  125. package/packages/dd-trace/src/appsec/recommended.json +1763 -106
  126. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -1
  127. package/packages/dd-trace/src/appsec/remote_config/index.js +42 -16
  128. package/packages/dd-trace/src/appsec/remote_config/manager.js +9 -8
  129. package/packages/dd-trace/src/appsec/reporter.js +51 -34
  130. package/packages/dd-trace/src/appsec/rule_manager.js +11 -8
  131. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
  132. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +28 -13
  133. package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
  134. package/packages/dd-trace/src/ci-visibility/{intelligent-test-runner/get-itr-configuration.js → early-flake-detection/get-known-tests.js} +17 -22
  135. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +25 -6
  136. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
  137. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +2 -0
  138. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -1
  139. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +95 -37
  140. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +134 -61
  141. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +37 -4
  142. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +131 -0
  143. package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
  144. package/packages/dd-trace/src/config.js +561 -470
  145. package/packages/dd-trace/src/data_streams_context.js +1 -1
  146. package/packages/dd-trace/src/datastreams/pathway.js +58 -1
  147. package/packages/dd-trace/src/datastreams/processor.js +196 -27
  148. package/packages/dd-trace/src/datastreams/writer.js +11 -5
  149. package/packages/dd-trace/src/dogstatsd.js +3 -5
  150. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -6
  151. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
  152. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
  153. package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
  154. package/packages/dd-trace/src/exporters/common/request.js +21 -3
  155. package/packages/dd-trace/src/format.js +30 -2
  156. package/packages/dd-trace/src/id.js +12 -0
  157. package/packages/dd-trace/src/iitm.js +1 -1
  158. package/packages/dd-trace/src/log/channels.js +1 -1
  159. package/packages/dd-trace/src/noop/proxy.js +4 -0
  160. package/packages/dd-trace/src/noop/span.js +1 -0
  161. package/packages/dd-trace/src/opentelemetry/span.js +104 -4
  162. package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
  163. package/packages/dd-trace/src/opentracing/propagation/text_map.js +16 -7
  164. package/packages/dd-trace/src/opentracing/span.js +48 -4
  165. package/packages/dd-trace/src/opentracing/span_context.js +15 -6
  166. package/packages/dd-trace/src/opentracing/tracer.js +4 -3
  167. package/packages/dd-trace/src/plugin_manager.js +1 -1
  168. package/packages/dd-trace/src/plugins/ci_plugin.js +78 -19
  169. package/packages/dd-trace/src/plugins/database.js +1 -1
  170. package/packages/dd-trace/src/plugins/index.js +7 -0
  171. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  172. package/packages/dd-trace/src/plugins/util/ci.js +6 -19
  173. package/packages/dd-trace/src/plugins/util/git.js +104 -22
  174. package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
  175. package/packages/dd-trace/src/plugins/util/test.js +60 -10
  176. package/packages/dd-trace/src/plugins/util/url.js +26 -0
  177. package/packages/dd-trace/src/plugins/util/user-provided-git.js +4 -16
  178. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  179. package/packages/dd-trace/src/priority_sampler.js +30 -38
  180. package/packages/dd-trace/src/profiler.js +5 -3
  181. package/packages/dd-trace/src/profiling/config.js +77 -24
  182. package/packages/dd-trace/src/profiling/exporters/agent.js +77 -31
  183. package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
  184. package/packages/dd-trace/src/profiling/profiler.js +33 -22
  185. package/packages/dd-trace/src/profiling/profilers/events.js +270 -0
  186. package/packages/dd-trace/src/profiling/profilers/shared.js +45 -0
  187. package/packages/dd-trace/src/profiling/profilers/space.js +18 -2
  188. package/packages/dd-trace/src/profiling/profilers/wall.js +146 -70
  189. package/packages/dd-trace/src/proxy.js +56 -24
  190. package/packages/dd-trace/src/ritm.js +1 -1
  191. package/packages/dd-trace/src/sampling_rule.js +130 -0
  192. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +5 -0
  193. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  194. package/packages/dd-trace/src/span_processor.js +9 -1
  195. package/packages/dd-trace/src/span_sampler.js +6 -64
  196. package/packages/dd-trace/src/spanleak.js +98 -0
  197. package/packages/dd-trace/src/startup-log.js +7 -1
  198. package/packages/dd-trace/src/telemetry/dependencies.js +56 -10
  199. package/packages/dd-trace/src/telemetry/index.js +182 -53
  200. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  201. package/packages/dd-trace/src/telemetry/send-data.js +65 -7
  202. package/packages/dd-trace/src/tracer.js +12 -5
  203. package/register.js +4 -0
  204. package/scripts/install_plugin_modules.js +11 -3
  205. package/scripts/st.js +105 -0
  206. package/packages/datadog-instrumentations/src/child-process.js +0 -30
  207. package/packages/dd-trace/src/plugins/util/exec.js +0 -13
  208. package/packages/diagnostics_channel/index.js +0 -3
  209. package/packages/diagnostics_channel/src/index.js +0 -121
@@ -8,17 +8,28 @@ const log = require('./log')
8
8
  const pkg = require('./pkg')
9
9
  const coalesce = require('koalas')
10
10
  const tagger = require('./tagger')
11
+ const get = require('../../datadog-core/src/utils/src/get')
12
+ const has = require('../../datadog-core/src/utils/src/has')
13
+ const set = require('../../datadog-core/src/utils/src/set')
11
14
  const { isTrue, isFalse } = require('./util')
12
15
  const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('./plugins/util/tags')
13
16
  const { getGitMetadataFromGitProperties, removeUserSensitiveInfo } = require('./git_properties')
14
17
  const { updateConfig } = require('./telemetry')
15
18
  const { getIsGCPFunction, getIsAzureFunctionConsumptionPlan } = require('./serverless')
19
+ const { ORIGIN_KEY } = require('./constants')
16
20
 
17
21
  const fromEntries = Object.fromEntries || (entries =>
18
22
  entries.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {}))
19
23
 
20
24
  // eslint-disable-next-line max-len
21
25
  const qsRegex = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:"|%22)(?:%2[^2]|%[^2]|[^"%])+(?:"|%22))|bearer(?:\\s|%20)+[a-z0-9\\._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L](?:[\\w=-]|%3D)+\\.ey[I-L](?:[\\w=-]|%3D)+(?:\\.(?:[\\w.+\\/=-]|%3D|%2F|%2B)+)?|[\\-]{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY[\\-]{5}[^\\-]+[\\-]{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY|ssh-rsa(?:\\s|%20)*(?:[a-z0-9\\/\\.+]|%2F|%5C|%2B){100,}'
26
+ const defaultWafObfuscatorKeyRegex = `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?\
27
+ |public_?)key)|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization`
28
+ const defaultWafObfuscatorValueRegex =
29
+ `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|to\
30
+ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\
31
+ \\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?\
32
+ |[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
22
33
 
23
34
  function maybeFile (filepath) {
24
35
  if (!filepath) return
@@ -93,6 +104,11 @@ function propagationStyle (key, option, defaultValue) {
93
104
  class Config {
94
105
  constructor (options) {
95
106
  options = options || {}
107
+ options = this.options = {
108
+ ...options,
109
+ appsec: options.appsec != null ? options.appsec : options.experimental?.appsec,
110
+ iastOptions: options.experimental?.iast
111
+ }
96
112
 
97
113
  // Configure the logger first so it can be used to warn about other configs
98
114
  this.debug = isTrue(coalesce(
@@ -109,174 +125,23 @@ class Config {
109
125
  log.use(this.logger)
110
126
  log.toggle(this.debug, this.logLevel, this)
111
127
 
112
- this.tags = {}
113
-
114
- tagger.add(this.tags, process.env.DD_TAGS)
115
- tagger.add(this.tags, process.env.DD_TRACE_TAGS)
116
- tagger.add(this.tags, process.env.DD_TRACE_GLOBAL_TAGS)
117
- tagger.add(this.tags, options.tags)
118
-
119
- const DD_TRACING_ENABLED = coalesce(
120
- process.env.DD_TRACING_ENABLED,
121
- true
122
- )
123
- const DD_PROFILING_ENABLED = coalesce(
124
- options.profiling, // TODO: remove when enabled by default
125
- process.env.DD_EXPERIMENTAL_PROFILING_ENABLED,
126
- process.env.DD_PROFILING_ENABLED,
127
- false
128
- )
129
- const DD_PROFILING_EXPORTERS = coalesce(
130
- process.env.DD_PROFILING_EXPORTERS,
131
- 'agent'
132
- )
133
- const DD_PROFILING_SOURCE_MAP = process.env.DD_PROFILING_SOURCE_MAP
134
- const DD_RUNTIME_METRICS_ENABLED = coalesce(
135
- options.runtimeMetrics, // TODO: remove when enabled by default
136
- process.env.DD_RUNTIME_METRICS_ENABLED,
137
- false
138
- )
139
- const DD_DBM_PROPAGATION_MODE = coalesce(
140
- options.dbmPropagationMode,
141
- process.env.DD_DBM_PROPAGATION_MODE,
142
- 'disabled'
143
- )
144
- const DD_DATA_STREAMS_ENABLED = coalesce(
145
- options.dsmEnabled,
146
- process.env.DD_DATA_STREAMS_ENABLED,
147
- false
148
- )
149
- const DD_AGENT_HOST = coalesce(
150
- options.hostname,
151
- process.env.DD_AGENT_HOST,
152
- process.env.DD_TRACE_AGENT_HOSTNAME,
153
- '127.0.0.1'
154
- )
155
- const DD_TRACE_AGENT_PORT = coalesce(
156
- options.port,
157
- process.env.DD_TRACE_AGENT_PORT,
158
- '8126'
159
- )
160
- const DD_TRACE_AGENT_URL = coalesce(
161
- options.url,
162
- process.env.DD_TRACE_AGENT_URL,
163
- process.env.DD_TRACE_URL,
164
- null
165
- )
166
- const DD_IS_CIVISIBILITY = coalesce(
167
- options.isCiVisibility,
168
- false
169
- )
170
- const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
171
-
172
- const DD_CIVISIBILITY_ITR_ENABLED = coalesce(
173
- process.env.DD_CIVISIBILITY_ITR_ENABLED,
174
- true
175
- )
176
-
177
- const DD_CIVISIBILITY_MANUAL_API_ENABLED = coalesce(
178
- process.env.DD_CIVISIBILITY_MANUAL_API_ENABLED,
179
- false
180
- )
181
-
182
128
  const DD_TRACE_MEMCACHED_COMMAND_ENABLED = coalesce(
183
129
  process.env.DD_TRACE_MEMCACHED_COMMAND_ENABLED,
184
130
  false
185
131
  )
186
132
 
187
- const DD_SERVICE = options.service ||
188
- process.env.DD_SERVICE ||
189
- process.env.DD_SERVICE_NAME ||
190
- this.tags.service ||
191
- process.env.AWS_LAMBDA_FUNCTION_NAME ||
192
- process.env.FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
193
- process.env.K_SERVICE || // Google Cloud Function Name set by newer runtimes
194
- process.env.WEBSITE_SITE_NAME || // set by Azure Functions
195
- pkg.name ||
196
- 'node'
197
133
  const DD_SERVICE_MAPPING = coalesce(
198
134
  options.serviceMapping,
199
135
  process.env.DD_SERVICE_MAPPING ? fromEntries(
200
136
  process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
201
137
  ) : {}
202
138
  )
203
- const DD_ENV = coalesce(
204
- options.env,
205
- process.env.DD_ENV,
206
- this.tags.env
207
- )
208
- const DD_VERSION = coalesce(
209
- options.version,
210
- process.env.DD_VERSION,
211
- this.tags.version,
212
- pkg.version
213
- )
214
- const DD_TRACE_STARTUP_LOGS = coalesce(
215
- options.startupLogs,
216
- process.env.DD_TRACE_STARTUP_LOGS,
217
- false
218
- )
219
-
220
- const DD_OPENAI_LOGS_ENABLED = coalesce(
221
- options.openAiLogsEnabled,
222
- process.env.DD_OPENAI_LOGS_ENABLED,
223
- false
224
- )
225
139
 
226
140
  const DD_API_KEY = coalesce(
227
141
  process.env.DATADOG_API_KEY,
228
142
  process.env.DD_API_KEY
229
143
  )
230
144
 
231
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
232
-
233
- const isGCPFunction = getIsGCPFunction()
234
- const isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
235
-
236
- const inServerlessEnvironment = inAWSLambda || isGCPFunction || isAzureFunctionConsumptionPlan
237
-
238
- const DD_TRACE_TELEMETRY_ENABLED = coalesce(
239
- process.env.DD_TRACE_TELEMETRY_ENABLED,
240
- !inServerlessEnvironment
241
- )
242
- const DD_TELEMETRY_HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
243
- ? Math.floor(parseFloat(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000)
244
- : 60000
245
- const DD_OPENAI_SPAN_CHAR_LIMIT = process.env.DD_OPENAI_SPAN_CHAR_LIMIT
246
- ? parseInt(process.env.DD_OPENAI_SPAN_CHAR_LIMIT)
247
- : 128
248
- const DD_TELEMETRY_DEBUG = coalesce(
249
- process.env.DD_TELEMETRY_DEBUG,
250
- false
251
- )
252
- const DD_TELEMETRY_METRICS_ENABLED = coalesce(
253
- process.env.DD_TELEMETRY_METRICS_ENABLED,
254
- true
255
- )
256
- const DD_TRACE_AGENT_PROTOCOL_VERSION = coalesce(
257
- options.protocolVersion,
258
- process.env.DD_TRACE_AGENT_PROTOCOL_VERSION,
259
- '0.4'
260
- )
261
- const DD_TRACE_PARTIAL_FLUSH_MIN_SPANS = coalesce(
262
- parseInt(options.flushMinSpans),
263
- parseInt(process.env.DD_TRACE_PARTIAL_FLUSH_MIN_SPANS),
264
- 1000
265
- )
266
- const DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP = coalesce(
267
- process.env.DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
268
- qsRegex
269
- )
270
- const DD_TRACE_CLIENT_IP_ENABLED = coalesce(
271
- options.clientIpEnabled,
272
- process.env.DD_TRACE_CLIENT_IP_ENABLED && isTrue(process.env.DD_TRACE_CLIENT_IP_ENABLED),
273
- false
274
- )
275
- const DD_TRACE_CLIENT_IP_HEADER = coalesce(
276
- options.clientIpHeader,
277
- process.env.DD_TRACE_CLIENT_IP_HEADER,
278
- null
279
- )
280
145
  // TODO: Remove the experimental env vars as a major?
281
146
  const DD_TRACE_B3_ENABLED = coalesce(
282
147
  options.experimental && options.experimental.b3,
@@ -308,222 +173,60 @@ class Config {
308
173
  options.tracePropagationStyle,
309
174
  defaultPropagationStyle
310
175
  )
311
- const DD_TRACE_RUNTIME_ID_ENABLED = coalesce(
312
- options.experimental && options.experimental.runtimeId,
313
- process.env.DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
314
- false
315
- )
316
- const DD_TRACE_EXPORTER = coalesce(
317
- options.experimental && options.experimental.exporter,
318
- process.env.DD_TRACE_EXPERIMENTAL_EXPORTER
319
- )
320
- const DD_TRACE_GET_RUM_DATA_ENABLED = coalesce(
321
- options.experimental && options.experimental.enableGetRumData,
322
- process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
323
- false
324
- )
325
- const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
326
- coalesce(
327
- options.spanAttributeSchema,
328
- process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
329
- )
330
- )
331
- const DD_TRACE_PEER_SERVICE_MAPPING = coalesce(
332
- options.peerServiceMapping,
333
- process.env.DD_TRACE_PEER_SERVICE_MAPPING ? fromEntries(
334
- process.env.DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
335
- ) : {}
336
- )
337
-
338
- const peerServiceSet = (
339
- options.hasOwnProperty('spanComputePeerService') ||
340
- process.env.hasOwnProperty('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
341
- )
342
- const peerServiceValue = coalesce(
343
- options.spanComputePeerService,
344
- process.env.DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
345
- )
346
-
347
- const DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED = (
348
- DD_TRACE_SPAN_ATTRIBUTE_SCHEMA === 'v0'
349
- // In v0, peer service is computed only if it is explicitly set to true
350
- ? peerServiceSet && isTrue(peerServiceValue)
351
- // In >v0, peer service is false only if it is explicitly set to false
352
- : (peerServiceSet ? !isFalse(peerServiceValue) : true)
353
- )
354
-
355
- const DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED = coalesce(
356
- options.spanRemoveIntegrationFromService,
357
- isTrue(process.env.DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
358
- )
359
- const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
360
- process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
361
- '512'
362
- )
363
-
364
- const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
365
- options.stats,
366
- process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
367
- isGCPFunction || isAzureFunctionConsumptionPlan
368
- )
369
-
370
- const DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = coalesce(
371
- options.traceId128BitGenerationEnabled,
372
- process.env.DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED,
373
- false
374
- )
375
-
376
- const DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED = coalesce(
377
- options.traceId128BitLoggingEnabled,
378
- process.env.DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED,
176
+ const DD_TRACE_PROPAGATION_EXTRACT_FIRST = coalesce(
177
+ process.env.DD_TRACE_PROPAGATION_EXTRACT_FIRST,
379
178
  false
380
179
  )
381
180
 
382
- let appsec = options.appsec != null ? options.appsec : options.experimental && options.experimental.appsec
383
-
384
- if (typeof appsec === 'boolean') {
385
- appsec = {
386
- enabled: appsec
181
+ if (typeof options.appsec === 'boolean') {
182
+ options.appsec = {
183
+ enabled: options.appsec
387
184
  }
388
- } else if (appsec == null) {
389
- appsec = {}
185
+ } else if (options.appsec == null) {
186
+ options.appsec = {}
390
187
  }
391
188
 
392
- const DD_APPSEC_ENABLED = coalesce(
393
- appsec.enabled,
394
- process.env.DD_APPSEC_ENABLED && isTrue(process.env.DD_APPSEC_ENABLED)
395
- )
396
-
397
- const DD_APPSEC_RULES = coalesce(
398
- appsec.rules,
399
- process.env.DD_APPSEC_RULES
400
- )
401
- const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
402
- parseInt(appsec.rateLimit),
403
- parseInt(process.env.DD_APPSEC_TRACE_RATE_LIMIT),
404
- 100
405
- )
406
- const DD_APPSEC_WAF_TIMEOUT = coalesce(
407
- parseInt(appsec.wafTimeout),
408
- parseInt(process.env.DD_APPSEC_WAF_TIMEOUT),
409
- 5e3 // µs
410
- )
411
- const DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP = coalesce(
412
- appsec.obfuscatorKeyRegex,
413
- process.env.DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
414
- `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?)key)|token|consumer_?(?:id|key|se\
415
- cret)|sign(?:ed|ature)|bearer|authorization`
416
- )
417
- const DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP = coalesce(
418
- appsec.obfuscatorValueRegex,
419
- process.env.DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
420
- `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|to\
421
- ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\
422
- \\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?\
423
- |[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
424
- )
425
- const DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML = coalesce(
426
- maybeFile(appsec.blockedTemplateHtml),
427
- maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML)
428
- )
429
- const DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON = coalesce(
430
- maybeFile(appsec.blockedTemplateJson),
431
- maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
189
+ const DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON = coalesce(
190
+ maybeFile(options.appsec.blockedTemplateGraphql),
191
+ maybeFile(process.env.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
432
192
  )
433
193
  const DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING = coalesce(
434
- appsec.eventTracking && appsec.eventTracking.mode,
194
+ options.appsec.eventTracking && options.appsec.eventTracking.mode,
435
195
  process.env.DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
436
196
  'safe'
437
197
  ).toLowerCase()
438
-
439
- const remoteConfigOptions = options.remoteConfig || {}
440
- const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
441
- process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
442
- !inServerlessEnvironment
443
- )
444
- const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
445
- parseFloat(remoteConfigOptions.pollInterval),
446
- parseFloat(process.env.DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS),
447
- 5 // seconds
448
- )
449
-
450
- const iastOptions = options?.experimental?.iast
451
- const DD_IAST_ENABLED = coalesce(
452
- iastOptions &&
453
- (iastOptions === true || iastOptions.enabled === true),
454
- process.env.DD_IAST_ENABLED,
455
- false
456
- )
457
- const DD_TELEMETRY_LOG_COLLECTION_ENABLED = coalesce(
458
- process.env.DD_TELEMETRY_LOG_COLLECTION_ENABLED,
459
- DD_IAST_ENABLED
460
- )
461
-
462
- const defaultIastRequestSampling = 30
463
- const iastRequestSampling = coalesce(
464
- parseInt(iastOptions?.requestSampling),
465
- parseInt(process.env.DD_IAST_REQUEST_SAMPLING),
466
- defaultIastRequestSampling
467
- )
468
- const DD_IAST_REQUEST_SAMPLING = iastRequestSampling < 0 ||
469
- iastRequestSampling > 100 ? defaultIastRequestSampling : iastRequestSampling
470
-
471
- const DD_IAST_MAX_CONCURRENT_REQUESTS = coalesce(
472
- parseInt(iastOptions?.maxConcurrentRequests),
473
- parseInt(process.env.DD_IAST_MAX_CONCURRENT_REQUESTS),
474
- 2
475
- )
476
-
477
- const DD_IAST_MAX_CONTEXT_OPERATIONS = coalesce(
478
- parseInt(iastOptions?.maxContextOperations),
479
- parseInt(process.env.DD_IAST_MAX_CONTEXT_OPERATIONS),
480
- 2
481
- )
482
-
483
- const DD_IAST_DEDUPLICATION_ENABLED = coalesce(
484
- iastOptions?.deduplicationEnabled,
485
- process.env.DD_IAST_DEDUPLICATION_ENABLED && isTrue(process.env.DD_IAST_DEDUPLICATION_ENABLED),
198
+ const DD_API_SECURITY_ENABLED = coalesce(
199
+ options.appsec?.apiSecurity?.enabled,
200
+ process.env.DD_API_SECURITY_ENABLED && isTrue(process.env.DD_API_SECURITY_ENABLED),
201
+ process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED),
486
202
  true
487
203
  )
488
-
489
- const DD_IAST_REDACTION_ENABLED = coalesce(
490
- iastOptions?.redactionEnabled,
491
- !isFalse(process.env.DD_IAST_REDACTION_ENABLED),
492
- true
204
+ const DD_API_SECURITY_REQUEST_SAMPLE_RATE = coalesce(
205
+ options.appsec?.apiSecurity?.requestSampling,
206
+ parseFloat(process.env.DD_API_SECURITY_REQUEST_SAMPLE_RATE),
207
+ 0.1
493
208
  )
494
209
 
495
- const DD_IAST_REDACTION_NAME_PATTERN = coalesce(
496
- iastOptions?.redactionNamePattern,
497
- process.env.DD_IAST_REDACTION_NAME_PATTERN,
498
- null
210
+ // 0: disabled, 1: logging, 2: garbage collection + logging
211
+ const DD_TRACE_SPAN_LEAK_DEBUG = coalesce(
212
+ process.env.DD_TRACE_SPAN_LEAK_DEBUG,
213
+ 0
499
214
  )
500
215
 
501
- const DD_IAST_REDACTION_VALUE_PATTERN = coalesce(
502
- iastOptions?.redactionValuePattern,
503
- process.env.DD_IAST_REDACTION_VALUE_PATTERN,
216
+ const DD_INSTRUMENTATION_INSTALL_ID = coalesce(
217
+ process.env.DD_INSTRUMENTATION_INSTALL_ID,
504
218
  null
505
219
  )
506
-
507
- const DD_IAST_TELEMETRY_VERBOSITY = coalesce(
508
- iastOptions?.telemetryVerbosity,
509
- process.env.DD_IAST_TELEMETRY_VERBOSITY,
510
- 'INFORMATION'
511
- )
512
-
513
- const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
514
- process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
515
- true
220
+ const DD_INSTRUMENTATION_INSTALL_TIME = coalesce(
221
+ process.env.DD_INSTRUMENTATION_INSTALL_TIME,
222
+ null
516
223
  )
517
-
518
- const DD_TRACE_GIT_METADATA_ENABLED = coalesce(
519
- process.env.DD_TRACE_GIT_METADATA_ENABLED,
520
- true
224
+ const DD_INSTRUMENTATION_INSTALL_TYPE = coalesce(
225
+ process.env.DD_INSTRUMENTATION_INSTALL_TYPE,
226
+ null
521
227
  )
522
228
 
523
- const ingestion = options.ingestion || {}
524
- const dogstatsd = coalesce(options.dogstatsd, {})
525
229
  const sampler = {
526
- rateLimit: coalesce(options.rateLimit, process.env.DD_TRACE_RATE_LIMIT, ingestion.rateLimit),
527
230
  rules: coalesce(
528
231
  options.samplingRules,
529
232
  safeJsonParse(process.env.DD_TRACE_SAMPLING_RULES),
@@ -546,110 +249,57 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
546
249
  })
547
250
  }
548
251
 
549
- const defaultFlushInterval = inAWSLambda ? 0 : 2000
550
-
551
- this.tracing = !isFalse(DD_TRACING_ENABLED)
552
- this.dbmPropagationMode = DD_DBM_PROPAGATION_MODE
553
- this.dsmEnabled = isTrue(DD_DATA_STREAMS_ENABLED)
554
- this.openAiLogsEnabled = DD_OPENAI_LOGS_ENABLED
252
+ // TODO: refactor
555
253
  this.apiKey = DD_API_KEY
556
- this.env = DD_ENV
557
- this.url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
558
- : getAgentUrl(DD_TRACE_AGENT_URL, options)
559
- this.site = coalesce(options.site, process.env.DD_SITE, 'datadoghq.com')
560
- this.hostname = DD_AGENT_HOST || (this.url && this.url.hostname)
561
- this.port = String(DD_TRACE_AGENT_PORT || (this.url && this.url.port))
562
- this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
563
- this.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
564
- this.queryStringObfuscation = DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP
565
- this.clientIpEnabled = DD_TRACE_CLIENT_IP_ENABLED
566
- this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
567
- this.plugins = !!coalesce(options.plugins, true)
568
- this.service = DD_SERVICE
569
254
  this.serviceMapping = DD_SERVICE_MAPPING
570
- this.version = DD_VERSION
571
- this.dogstatsd = {
572
- hostname: coalesce(dogstatsd.hostname, process.env.DD_DOGSTATSD_HOSTNAME, this.hostname),
573
- port: String(coalesce(dogstatsd.port, process.env.DD_DOGSTATSD_PORT, 8125))
574
- }
575
- this.runtimeMetrics = isTrue(DD_RUNTIME_METRICS_ENABLED)
576
255
  this.tracePropagationStyle = {
577
256
  inject: DD_TRACE_PROPAGATION_STYLE_INJECT,
578
257
  extract: DD_TRACE_PROPAGATION_STYLE_EXTRACT
579
258
  }
580
- this.experimental = {
581
- runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
582
- exporter: DD_TRACE_EXPORTER,
583
- enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED)
584
- }
259
+ this.tracePropagationExtractFirst = isTrue(DD_TRACE_PROPAGATION_EXTRACT_FIRST)
585
260
  this.sampler = sampler
586
- this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
587
- this.scope = process.env.DD_TRACE_SCOPE
588
- this.profiling = {
589
- enabled: isTrue(DD_PROFILING_ENABLED),
590
- sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
591
- exporters: DD_PROFILING_EXPORTERS
592
- }
593
- this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
594
- this.spanComputePeerService = DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
595
- this.spanRemoveIntegrationFromService = DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED
596
- this.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
597
- this.lookup = options.lookup
598
- this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
599
- // Disabled for CI Visibility's agentless
600
- this.telemetry = {
601
- enabled: DD_TRACE_EXPORTER !== 'datadog' && isTrue(DD_TRACE_TELEMETRY_ENABLED),
602
- heartbeatInterval: DD_TELEMETRY_HEARTBEAT_INTERVAL,
603
- debug: isTrue(DD_TELEMETRY_DEBUG),
604
- logCollection: isTrue(DD_TELEMETRY_LOG_COLLECTION_ENABLED),
605
- metrics: isTrue(DD_TELEMETRY_METRICS_ENABLED)
606
- }
607
- this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
608
- this.tagsHeaderMaxLength = parseInt(DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
609
261
  this.appsec = {
610
- enabled: DD_APPSEC_ENABLED,
611
- rules: DD_APPSEC_RULES ? safeJsonParse(maybeFile(DD_APPSEC_RULES)) : require('./appsec/recommended.json'),
612
- customRulesProvided: !!DD_APPSEC_RULES,
613
- rateLimit: DD_APPSEC_TRACE_RATE_LIMIT,
614
- wafTimeout: DD_APPSEC_WAF_TIMEOUT,
615
- obfuscatorKeyRegex: DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
616
- obfuscatorValueRegex: DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
617
- blockedTemplateHtml: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
618
- blockedTemplateJson: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
262
+ blockedTemplateGraphql: DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
619
263
  eventTracking: {
620
264
  enabled: ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING),
621
265
  mode: DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING
266
+ },
267
+ apiSecurity: {
268
+ enabled: DD_API_SECURITY_ENABLED,
269
+ // Coerce value between 0 and 1
270
+ requestSampling: Math.min(1, Math.max(0, DD_API_SECURITY_REQUEST_SAMPLE_RATE))
622
271
  }
623
272
  }
624
- this.remoteConfig = {
625
- enabled: DD_REMOTE_CONFIGURATION_ENABLED,
626
- pollInterval: DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
627
- }
628
- this.iast = {
629
- enabled: isTrue(DD_IAST_ENABLED),
630
- requestSampling: DD_IAST_REQUEST_SAMPLING,
631
- maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
632
- maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
633
- deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED,
634
- redactionEnabled: DD_IAST_REDACTION_ENABLED,
635
- redactionNamePattern: DD_IAST_REDACTION_NAME_PATTERN,
636
- redactionValuePattern: DD_IAST_REDACTION_VALUE_PATTERN,
637
- telemetryVerbosity: DD_IAST_TELEMETRY_VERBOSITY
638
- }
639
273
 
640
- this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
641
-
642
- this.isIntelligentTestRunnerEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_ITR_ENABLED)
643
- this.isGitUploadEnabled = this.isCiVisibility &&
644
- (this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
274
+ // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
275
+ this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
276
+ this.isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
277
+ this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
278
+ this.installSignature = {
279
+ id: DD_INSTRUMENTATION_INSTALL_ID,
280
+ time: DD_INSTRUMENTATION_INSTALL_TIME,
281
+ type: DD_INSTRUMENTATION_INSTALL_TYPE
282
+ }
645
283
 
646
- this.gitMetadataEnabled = isTrue(DD_TRACE_GIT_METADATA_ENABLED)
647
- this.isManualApiEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_MANUAL_API_ENABLED)
284
+ this._applyDefaults()
285
+ this._applyEnvironment()
286
+ this._applyOptions(options)
287
+ this._applyCalculated()
288
+ this._applyRemote({})
289
+ this._merge()
648
290
 
649
- this.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
291
+ tagger.add(this.tags, {
292
+ service: this.service,
293
+ env: this.env,
294
+ version: this.version,
295
+ 'runtime-id': uuid()
296
+ })
650
297
 
651
- // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
652
- this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
298
+ if (this.isCiVisibility) {
299
+ tagger.add(this.tags, {
300
+ [ORIGIN_KEY]: 'ciapp-test'
301
+ })
302
+ }
653
303
 
654
304
  if (this.gitMetadataEnabled) {
655
305
  this.repositoryUrl = removeUserSensitiveInfo(
@@ -683,29 +333,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
683
333
  }
684
334
  }
685
335
  }
686
-
687
- this.stats = {
688
- enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
689
- }
690
-
691
- this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
692
- this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
693
-
694
- this.isGCPFunction = isGCPFunction
695
- this.isAzureFunctionConsumptionPlan = isAzureFunctionConsumptionPlan
696
-
697
- tagger.add(this.tags, {
698
- service: this.service,
699
- env: this.env,
700
- version: this.version,
701
- 'runtime-id': uuid()
702
- })
703
-
704
- this._applyDefaults()
705
- this._applyEnvironment()
706
- this._applyOptions(options)
707
- this._applyRemote({})
708
- this._merge()
709
336
  }
710
337
 
711
338
  // Supports only a subset of options for now.
@@ -716,52 +343,492 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
716
343
  this._applyOptions(options)
717
344
  }
718
345
 
346
+ // TODO: test
347
+ this._applyCalculated()
719
348
  this._merge()
720
349
  }
721
350
 
351
+ _isInServerlessEnvironment () {
352
+ const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
353
+ const isGCPFunction = getIsGCPFunction()
354
+ const isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
355
+ return inAWSLambda || isGCPFunction || isAzureFunctionConsumptionPlan
356
+ }
357
+
358
+ // for _merge to work, every config value must have a default value
722
359
  _applyDefaults () {
360
+ const {
361
+ AWS_LAMBDA_FUNCTION_NAME,
362
+ FUNCTION_NAME,
363
+ K_SERVICE,
364
+ WEBSITE_SITE_NAME
365
+ } = process.env
366
+
367
+ const service = AWS_LAMBDA_FUNCTION_NAME ||
368
+ FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
369
+ K_SERVICE || // Google Cloud Function Name set by newer runtimes
370
+ WEBSITE_SITE_NAME || // set by Azure Functions
371
+ pkg.name ||
372
+ 'node'
373
+
723
374
  const defaults = this._defaults = {}
724
375
 
725
- this._setUnit(defaults, 'sampleRate', undefined)
726
- this._setBoolean(defaults, 'logInjection', false)
727
- this._setArray(defaults, 'headerTags', [])
376
+ this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
377
+ this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
378
+ this._setValue(defaults, 'appsec.enabled', undefined)
379
+ this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)
380
+ this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)
381
+ this._setValue(defaults, 'appsec.rateLimit', 100)
382
+ this._setValue(defaults, 'appsec.rules', undefined)
383
+ this._setValue(defaults, 'appsec.wafTimeout', 5e3) // µs
384
+ this._setValue(defaults, 'clientIpEnabled', false)
385
+ this._setValue(defaults, 'clientIpHeader', null)
386
+ this._setValue(defaults, 'dbmPropagationMode', 'disabled')
387
+ this._setValue(defaults, 'dogstatsd.hostname', '127.0.0.1')
388
+ this._setValue(defaults, 'dogstatsd.port', '8125')
389
+ this._setValue(defaults, 'dsmEnabled', false)
390
+ this._setValue(defaults, 'env', undefined)
391
+ this._setValue(defaults, 'experimental.enableGetRumData', false)
392
+ this._setValue(defaults, 'experimental.exporter', undefined)
393
+ this._setValue(defaults, 'experimental.runtimeId', false)
394
+ this._setValue(defaults, 'flushInterval', 2000)
395
+ this._setValue(defaults, 'flushMinSpans', 1000)
396
+ this._setValue(defaults, 'gitMetadataEnabled', true)
397
+ this._setValue(defaults, 'headerTags', [])
398
+ this._setValue(defaults, 'hostname', '127.0.0.1')
399
+ this._setValue(defaults, 'iast.deduplicationEnabled', true)
400
+ this._setValue(defaults, 'iast.enabled', false)
401
+ this._setValue(defaults, 'iast.maxConcurrentRequests', 2)
402
+ this._setValue(defaults, 'iast.maxContextOperations', 2)
403
+ this._setValue(defaults, 'iast.redactionEnabled', true)
404
+ this._setValue(defaults, 'iast.redactionNamePattern', null)
405
+ this._setValue(defaults, 'iast.redactionValuePattern', null)
406
+ this._setValue(defaults, 'iast.requestSampling', 30)
407
+ this._setValue(defaults, 'iast.telemetryVerbosity', 'INFORMATION')
408
+ this._setValue(defaults, 'isCiVisibility', false)
409
+ this._setValue(defaults, 'isEarlyFlakeDetectionEnabled', false)
410
+ this._setValue(defaults, 'isGCPFunction', false)
411
+ this._setValue(defaults, 'isGitUploadEnabled', false)
412
+ this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
413
+ this._setValue(defaults, 'isManualApiEnabled', false)
414
+ this._setValue(defaults, 'logInjection', false)
415
+ this._setValue(defaults, 'lookup', undefined)
416
+ this._setValue(defaults, 'openAiLogsEnabled', false)
417
+ this._setValue(defaults, 'openaiSpanCharLimit', 128)
418
+ this._setValue(defaults, 'peerServiceMapping', {})
419
+ this._setValue(defaults, 'plugins', true)
420
+ this._setValue(defaults, 'port', '8126')
421
+ this._setValue(defaults, 'profiling.enabled', false)
422
+ this._setValue(defaults, 'profiling.exporters', 'agent')
423
+ this._setValue(defaults, 'profiling.sourceMap', true)
424
+ this._setValue(defaults, 'protocolVersion', '0.4')
425
+ this._setValue(defaults, 'queryStringObfuscation', qsRegex)
426
+ this._setValue(defaults, 'remoteConfig.enabled', true)
427
+ this._setValue(defaults, 'remoteConfig.pollInterval', 5) // seconds
428
+ this._setValue(defaults, 'reportHostname', false)
429
+ this._setValue(defaults, 'runtimeMetrics', false)
430
+ this._setValue(defaults, 'sampleRate', undefined)
431
+ this._setValue(defaults, 'sampler.rateLimit', undefined)
432
+ this._setValue(defaults, 'scope', undefined)
433
+ this._setValue(defaults, 'service', service)
434
+ this._setValue(defaults, 'site', 'datadoghq.com')
435
+ this._setValue(defaults, 'spanAttributeSchema', 'v0')
436
+ this._setValue(defaults, 'spanComputePeerService', false)
437
+ this._setValue(defaults, 'spanRemoveIntegrationFromService', false)
438
+ this._setValue(defaults, 'startupLogs', false)
439
+ this._setValue(defaults, 'stats.enabled', false)
440
+ this._setValue(defaults, 'tags', {})
441
+ this._setValue(defaults, 'tagsHeaderMaxLength', 512)
442
+ this._setValue(defaults, 'telemetry.debug', false)
443
+ this._setValue(defaults, 'telemetry.dependencyCollection', true)
444
+ this._setValue(defaults, 'telemetry.enabled', true)
445
+ this._setValue(defaults, 'telemetry.heartbeatInterval', 60000)
446
+ this._setValue(defaults, 'telemetry.logCollection', false)
447
+ this._setValue(defaults, 'telemetry.metrics', true)
448
+ this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
449
+ this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
450
+ this._setValue(defaults, 'tracing', true)
451
+ this._setValue(defaults, 'url', undefined)
452
+ this._setValue(defaults, 'version', pkg.version)
728
453
  }
729
454
 
730
455
  _applyEnvironment () {
731
456
  const {
732
- DD_TRACE_SAMPLE_RATE,
457
+ AWS_LAMBDA_FUNCTION_NAME,
458
+ DD_AGENT_HOST,
459
+ DD_APPSEC_ENABLED,
460
+ DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
461
+ DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
462
+ DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
463
+ DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
464
+ DD_APPSEC_RULES,
465
+ DD_APPSEC_TRACE_RATE_LIMIT,
466
+ DD_APPSEC_WAF_TIMEOUT,
467
+ DD_DATA_STREAMS_ENABLED,
468
+ DD_DBM_PROPAGATION_MODE,
469
+ DD_DOGSTATSD_HOSTNAME,
470
+ DD_DOGSTATSD_PORT,
471
+ DD_ENV,
472
+ DD_EXPERIMENTAL_PROFILING_ENABLED,
473
+ JEST_WORKER_ID,
474
+ DD_IAST_DEDUPLICATION_ENABLED,
475
+ DD_IAST_ENABLED,
476
+ DD_IAST_MAX_CONCURRENT_REQUESTS,
477
+ DD_IAST_MAX_CONTEXT_OPERATIONS,
478
+ DD_IAST_REDACTION_ENABLED,
479
+ DD_IAST_REDACTION_NAME_PATTERN,
480
+ DD_IAST_REDACTION_VALUE_PATTERN,
481
+ DD_IAST_REQUEST_SAMPLING,
482
+ DD_IAST_TELEMETRY_VERBOSITY,
483
+ DD_INSTRUMENTATION_TELEMETRY_ENABLED,
733
484
  DD_LOGS_INJECTION,
734
- DD_TRACE_HEADER_TAGS
485
+ DD_OPENAI_LOGS_ENABLED,
486
+ DD_OPENAI_SPAN_CHAR_LIMIT,
487
+ DD_PROFILING_ENABLED,
488
+ DD_PROFILING_EXPORTERS,
489
+ DD_PROFILING_SOURCE_MAP,
490
+ DD_REMOTE_CONFIGURATION_ENABLED,
491
+ DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS,
492
+ DD_RUNTIME_METRICS_ENABLED,
493
+ DD_SERVICE,
494
+ DD_SERVICE_NAME,
495
+ DD_SITE,
496
+ DD_TAGS,
497
+ DD_TELEMETRY_DEBUG,
498
+ DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED,
499
+ DD_TELEMETRY_HEARTBEAT_INTERVAL,
500
+ DD_TELEMETRY_LOG_COLLECTION_ENABLED,
501
+ DD_TELEMETRY_METRICS_ENABLED,
502
+ DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED,
503
+ DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED,
504
+ DD_TRACE_AGENT_HOSTNAME,
505
+ DD_TRACE_AGENT_PORT,
506
+ DD_TRACE_AGENT_PROTOCOL_VERSION,
507
+ DD_TRACE_CLIENT_IP_ENABLED,
508
+ DD_TRACE_CLIENT_IP_HEADER,
509
+ DD_TRACE_EXPERIMENTAL_EXPORTER,
510
+ DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
511
+ DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
512
+ DD_TRACE_GIT_METADATA_ENABLED,
513
+ DD_TRACE_GLOBAL_TAGS,
514
+ DD_TRACE_HEADER_TAGS,
515
+ DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
516
+ DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
517
+ DD_TRACE_PEER_SERVICE_MAPPING,
518
+ DD_TRACE_RATE_LIMIT,
519
+ DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,
520
+ DD_TRACE_REPORT_HOSTNAME,
521
+ DD_TRACE_SAMPLE_RATE,
522
+ DD_TRACE_SCOPE,
523
+ DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
524
+ DD_TRACE_STARTUP_LOGS,
525
+ DD_TRACE_TAGS,
526
+ DD_TRACE_TELEMETRY_ENABLED,
527
+ DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
528
+ DD_TRACING_ENABLED,
529
+ DD_VERSION
735
530
  } = process.env
736
531
 
532
+ const tags = {}
737
533
  const env = this._env = {}
738
534
 
739
- this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
740
- this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
535
+ tagger.add(tags, DD_TAGS)
536
+ tagger.add(tags, DD_TRACE_TAGS)
537
+ tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
538
+
539
+ this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
540
+ this._setValue(env, 'appsec.blockedTemplateJson', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON))
541
+ this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
542
+ this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
543
+ this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
544
+ this._setValue(env, 'appsec.rateLimit', maybeInt(DD_APPSEC_TRACE_RATE_LIMIT))
545
+ this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
546
+ this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
547
+ this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
548
+ this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
549
+ this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
550
+ this._setString(env, 'dogstatsd.hostname', DD_DOGSTATSD_HOSTNAME)
551
+ this._setString(env, 'dogstatsd.port', DD_DOGSTATSD_PORT)
552
+ this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
553
+ this._setString(env, 'env', DD_ENV || tags.env)
554
+ this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
555
+ this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
556
+ this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
557
+ if (AWS_LAMBDA_FUNCTION_NAME) this._setValue(env, 'flushInterval', 0)
558
+ this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
559
+ this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
741
560
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
561
+ this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
562
+ this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
563
+ this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
564
+ this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
565
+ this._setValue(env, 'iast.maxContextOperations', maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS))
566
+ this._setBoolean(env, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
567
+ this._setString(env, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
568
+ this._setString(env, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
569
+ const iastRequestSampling = maybeInt(DD_IAST_REQUEST_SAMPLING)
570
+ if (iastRequestSampling > -1 && iastRequestSampling < 101) {
571
+ this._setValue(env, 'iast.requestSampling', iastRequestSampling)
572
+ }
573
+ this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
574
+ this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
575
+ this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
576
+ this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
577
+ this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
578
+ if (DD_TRACE_PEER_SERVICE_MAPPING) {
579
+ this._setValue(env, 'peerServiceMapping', fromEntries(
580
+ process.env.DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
581
+ ))
582
+ }
583
+ this._setString(env, 'port', DD_TRACE_AGENT_PORT)
584
+ this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
585
+ this._setString(env, 'profiling.exporters', DD_PROFILING_EXPORTERS)
586
+ this._setBoolean(env, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
587
+ this._setString(env, 'protocolVersion', DD_TRACE_AGENT_PROTOCOL_VERSION)
588
+ this._setString(env, 'queryStringObfuscation', DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP)
589
+ this._setBoolean(env, 'remoteConfig.enabled', coalesce(
590
+ DD_REMOTE_CONFIGURATION_ENABLED,
591
+ !this._isInServerlessEnvironment()
592
+ ))
593
+ this._setValue(env, 'remoteConfig.pollInterval', maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS))
594
+ this._setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
595
+ this._setBoolean(env, 'runtimeMetrics', DD_RUNTIME_METRICS_ENABLED)
596
+ this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
597
+ this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
598
+ this._setString(env, 'scope', DD_TRACE_SCOPE)
599
+ this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
600
+ this._setString(env, 'site', DD_SITE)
601
+ if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
602
+ this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
603
+ }
604
+ this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
605
+ this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
606
+ this._setTags(env, 'tags', tags)
607
+ this._setValue(env, 'tagsHeaderMaxLength', DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
608
+ this._setBoolean(env, 'telemetry.enabled', coalesce(
609
+ DD_TRACE_TELEMETRY_ENABLED, // for backward compatibility
610
+ DD_INSTRUMENTATION_TELEMETRY_ENABLED, // to comply with instrumentation telemetry specs
611
+ !(this._isInServerlessEnvironment() || JEST_WORKER_ID)
612
+ ))
613
+ this._setBoolean(env, 'telemetry.debug', DD_TELEMETRY_DEBUG)
614
+ this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
615
+ this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
616
+ this._setBoolean(env, 'telemetry.logCollection', coalesce(DD_TELEMETRY_LOG_COLLECTION_ENABLED, DD_IAST_ENABLED))
617
+ this._setBoolean(env, 'telemetry.metrics', DD_TELEMETRY_METRICS_ENABLED)
618
+ this._setBoolean(env, 'traceId128BitGenerationEnabled', DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
619
+ this._setBoolean(env, 'traceId128BitLoggingEnabled', DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
620
+ this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)
621
+ this._setString(env, 'version', DD_VERSION || tags.version)
742
622
  }
743
623
 
744
624
  _applyOptions (options) {
745
625
  const opts = this._options = this._options || {}
626
+ const tags = {}
627
+
628
+ options = this.options = Object.assign({ ingestion: {} }, options, opts)
629
+
630
+ tagger.add(tags, options.tags)
631
+
632
+ this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
633
+ this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
634
+ this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
635
+ this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
636
+ this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
637
+ this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
638
+ this._setString(opts, 'appsec.rules', options.appsec.rules)
639
+ this._setValue(opts, 'appsec.wafTimeout', maybeInt(options.appsec.wafTimeout))
640
+ this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
641
+ this._setString(opts, 'clientIpHeader', options.clientIpHeader)
642
+ this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
643
+ if (options.dogstatsd) {
644
+ this._setString(opts, 'dogstatsd.hostname', options.dogstatsd.hostname)
645
+ this._setString(opts, 'dogstatsd.port', options.dogstatsd.port)
646
+ }
647
+ this._setBoolean(opts, 'dsmEnabled', options.dsmEnabled)
648
+ this._setString(opts, 'env', options.env || tags.env)
649
+ this._setBoolean(opts, 'experimental.enableGetRumData',
650
+ options.experimental && options.experimental.enableGetRumData)
651
+ this._setString(opts, 'experimental.exporter', options.experimental && options.experimental.exporter)
652
+ this._setBoolean(opts, 'experimental.runtimeId', options.experimental && options.experimental.runtimeId)
653
+ this._setValue(opts, 'flushInterval', maybeInt(options.flushInterval))
654
+ this._setValue(opts, 'flushMinSpans', maybeInt(options.flushMinSpans))
655
+ this._setArray(opts, 'headerTags', options.headerTags)
656
+ this._setString(opts, 'hostname', options.hostname)
657
+ this._setBoolean(opts, 'iast.deduplicationEnabled', options.iastOptions && options.iastOptions.deduplicationEnabled)
658
+ this._setBoolean(opts, 'iast.enabled',
659
+ options.iastOptions && (options.iastOptions === true || options.iastOptions.enabled === true))
660
+ const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
661
+ this._setValue(opts, 'iast.maxConcurrentRequests',
662
+ maybeInt(options.iastOptions?.maxConcurrentRequests))
663
+ this._setValue(opts, 'iast.maxContextOperations',
664
+ maybeInt(options.iastOptions && options.iastOptions.maxContextOperations))
665
+ this._setBoolean(opts, 'iast.redactionEnabled', options.iastOptions && options.iastOptions.redactionEnabled)
666
+ this._setString(opts, 'iast.redactionNamePattern', options.iastOptions?.redactionNamePattern)
667
+ this._setString(opts, 'iast.redactionValuePattern', options.iastOptions?.redactionValuePattern)
668
+ if (iastRequestSampling > -1 && iastRequestSampling < 101) {
669
+ this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
670
+ }
671
+ this._setString(opts, 'iast.telemetryVerbosity', options.iastOptions && options.iastOptions.telemetryVerbosity)
672
+ this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
673
+ this._setBoolean(opts, 'logInjection', options.logInjection)
674
+ this._setString(opts, 'lookup', options.lookup)
675
+ this._setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
676
+ this._setValue(opts, 'peerServiceMapping', options.peerServiceMapping)
677
+ this._setBoolean(opts, 'plugins', options.plugins)
678
+ this._setString(opts, 'port', options.port)
679
+ this._setBoolean(opts, 'profiling.enabled', options.profiling)
680
+ this._setString(opts, 'protocolVersion', options.protocolVersion)
681
+ if (options.remoteConfig) {
682
+ this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
683
+ }
684
+ this._setBoolean(opts, 'reportHostname', options.reportHostname)
685
+ this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
686
+ this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
687
+ const ingestion = options.ingestion || {}
688
+ this._setValue(opts, 'sampler.rateLimit', coalesce(options.rateLimit, ingestion.rateLimit))
689
+ this._setString(opts, 'service', options.service || tags.service)
690
+ this._setString(opts, 'site', options.site)
691
+ if (options.spanAttributeSchema) {
692
+ this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
693
+ }
694
+ this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
695
+ this._setBoolean(opts, 'startupLogs', options.startupLogs)
696
+ this._setTags(opts, 'tags', tags)
697
+ this._setBoolean(opts, 'telemetry.logCollection', options.iastOptions &&
698
+ (options.iastOptions === true || options.iastOptions.enabled === true))
699
+ this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
700
+ this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
701
+ this._setString(opts, 'version', options.version || tags.version)
702
+ }
746
703
 
747
- options = Object.assign({ ingestion: {} }, options, opts)
704
+ _isCiVisibility () {
705
+ return coalesce(
706
+ this.options.isCiVisibility,
707
+ this._defaults['isCiVisibility']
708
+ )
709
+ }
748
710
 
749
- this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
750
- this._setBoolean(opts, 'logInjection', options.logInjection)
751
- this._setArray(opts, 'headerTags', options.headerTags)
711
+ _isCiVisibilityItrEnabled () {
712
+ return coalesce(
713
+ process.env.DD_CIVISIBILITY_ITR_ENABLED,
714
+ true
715
+ )
716
+ }
717
+
718
+ _getHostname () {
719
+ const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
720
+ const url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
721
+ : getAgentUrl(this._getTraceAgentUrl(), this.options)
722
+ const DD_AGENT_HOST = coalesce(
723
+ this.options.hostname,
724
+ process.env.DD_AGENT_HOST,
725
+ process.env.DD_TRACE_AGENT_HOSTNAME,
726
+ '127.0.0.1'
727
+ )
728
+ return DD_AGENT_HOST || (url && url.hostname)
729
+ }
730
+
731
+ _getSpanComputePeerService () {
732
+ const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
733
+ coalesce(
734
+ this.options.spanAttributeSchema,
735
+ process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
736
+ )
737
+ )
738
+
739
+ const peerServiceSet = (
740
+ this.options.hasOwnProperty('spanComputePeerService') ||
741
+ process.env.hasOwnProperty('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
742
+ )
743
+ const peerServiceValue = coalesce(
744
+ this.options.spanComputePeerService,
745
+ process.env.DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
746
+ )
747
+
748
+ const spanComputePeerService = (
749
+ DD_TRACE_SPAN_ATTRIBUTE_SCHEMA === 'v0'
750
+ // In v0, peer service is computed only if it is explicitly set to true
751
+ ? peerServiceSet && isTrue(peerServiceValue)
752
+ // In >v0, peer service is false only if it is explicitly set to false
753
+ : (peerServiceSet ? !isFalse(peerServiceValue) : true)
754
+ )
755
+
756
+ return spanComputePeerService
757
+ }
758
+
759
+ _isCiVisibilityGitUploadEnabled () {
760
+ return coalesce(
761
+ process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
762
+ true
763
+ )
764
+ }
765
+
766
+ _isCiVisibilityManualApiEnabled () {
767
+ return isTrue(coalesce(
768
+ process.env.DD_CIVISIBILITY_MANUAL_API_ENABLED,
769
+ false
770
+ ))
771
+ }
772
+
773
+ _isTraceStatsComputationEnabled () {
774
+ return coalesce(
775
+ this.options.stats,
776
+ process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
777
+ getIsGCPFunction() || getIsAzureFunctionConsumptionPlan()
778
+ )
779
+ }
780
+
781
+ _getTraceAgentUrl () {
782
+ return coalesce(
783
+ this.options.url,
784
+ process.env.DD_TRACE_AGENT_URL,
785
+ process.env.DD_TRACE_URL,
786
+ null
787
+ )
788
+ }
789
+
790
+ // handles values calculated from a mixture of options and env vars
791
+ _applyCalculated () {
792
+ const calc = this._calculated = {}
793
+
794
+ const {
795
+ DD_CIVISIBILITY_AGENTLESS_URL
796
+ } = process.env
797
+
798
+ if (DD_CIVISIBILITY_AGENTLESS_URL) {
799
+ this._setValue(calc, 'url', new URL(DD_CIVISIBILITY_AGENTLESS_URL))
800
+ } else {
801
+ this._setValue(calc, 'url', getAgentUrl(this._getTraceAgentUrl(), this.options))
802
+ }
803
+ if (this._isCiVisibility()) {
804
+ this._setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
805
+ coalesce(process.env.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
806
+ this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))
807
+ this._setBoolean(calc, 'isManualApiEnabled', this._isCiVisibilityManualApiEnabled())
808
+ }
809
+ this._setString(calc, 'dogstatsd.hostname', this._getHostname())
810
+ this._setBoolean(calc, 'isGitUploadEnabled',
811
+ calc['isIntelligentTestRunnerEnabled'] && !isFalse(this._isCiVisibilityGitUploadEnabled()))
812
+ this._setBoolean(calc, 'spanComputePeerService', this._getSpanComputePeerService())
813
+ this._setBoolean(calc, 'stats.enabled', this._isTraceStatsComputationEnabled())
752
814
  }
753
815
 
754
816
  _applyRemote (options) {
755
817
  const opts = this._remote = this._remote || {}
818
+ const tags = {}
756
819
  const headerTags = options.tracing_header_tags
757
820
  ? options.tracing_header_tags.map(tag => {
758
821
  return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
759
822
  })
760
823
  : undefined
761
824
 
825
+ tagger.add(tags, options.tracing_tags)
826
+
762
827
  this._setUnit(opts, 'sampleRate', options.tracing_sampling_rate)
763
828
  this._setBoolean(opts, 'logInjection', options.log_injection_enabled)
764
829
  this._setArray(opts, 'headerTags', headerTags)
830
+ this._setTags(opts, 'tags', tags)
831
+ this._setBoolean(opts, 'tracing', options.tracing_enabled)
765
832
  }
766
833
 
767
834
  _setBoolean (obj, name, value) {
@@ -801,6 +868,18 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
801
868
  }
802
869
  }
803
870
 
871
+ _setString (obj, name, value) {
872
+ obj[name] = value ? String(value) : undefined // unset for empty strings
873
+ }
874
+
875
+ _setTags (obj, name, value) {
876
+ if (!value || Object.keys(value).length === 0) {
877
+ return this._setValue(obj, name, null)
878
+ }
879
+
880
+ this._setValue(obj, name, value)
881
+ }
882
+
804
883
  _setValue (obj, name, value) {
805
884
  obj[name] = value
806
885
  }
@@ -808,9 +887,12 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
808
887
  // TODO: Report origin changes and errors to telemetry.
809
888
  // TODO: Deeply merge configurations.
810
889
  // TODO: Move change tracking to telemetry.
890
+ // for telemetry reporting, `name`s in `containers` need to be keys from:
891
+ // eslint-disable-next-line max-len
892
+ // https://github.com/DataDog/dd-go/blob/prod/trace/apps/tracer-telemetry-intake/telemetry-payload/static/config_norm_rules.json
811
893
  _merge () {
812
- const containers = [this._remote, this._options, this._env, this._defaults]
813
- const origins = ['remote_config', 'code', 'env_var', 'default']
894
+ const containers = [this._remote, this._options, this._env, this._calculated, this._defaults]
895
+ const origins = ['remote_config', 'code', 'env_var', 'calculated', 'default']
814
896
  const changes = []
815
897
 
816
898
  for (const name in this._defaults) {
@@ -819,9 +901,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
819
901
  const origin = origins[i]
820
902
 
821
903
  if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
822
- if (this[name] === container[name] && this.hasOwnProperty(name)) break
904
+ if (get(this, name) === container[name] && has(this, name)) break
823
905
 
824
- const value = this[name] = container[name]
906
+ const value = container[name]
907
+ set(this, name, value)
825
908
 
826
909
  changes.push({ name, value, origin })
827
910
 
@@ -831,11 +914,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
831
914
  }
832
915
 
833
916
  this.sampler.sampleRate = this.sampleRate
834
-
835
917
  updateConfig(changes, this)
836
918
  }
837
919
  }
838
920
 
921
+ function maybeInt (number) {
922
+ const parsed = parseInt(number)
923
+ return isNaN(parsed) ? undefined : parsed
924
+ }
925
+ function maybeFloat (number) {
926
+ const parsed = parseFloat(number)
927
+ return isNaN(parsed) ? undefined : parsed
928
+ }
929
+
839
930
  function getAgentUrl (url, options) {
840
931
  if (url) return new URL(url)
841
932