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
@@ -14,6 +14,7 @@ const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
14
14
  const testToAr = new WeakMap()
15
15
  const testSuiteToAr = new Map()
16
16
  const testSuiteToTestStatuses = new Map()
17
+ const testSuiteToErrors = new Map()
17
18
 
18
19
  let startedSuites = []
19
20
 
@@ -73,14 +74,88 @@ function getRootDir (playwrightRunner) {
73
74
  if (playwrightRunner._configDir) {
74
75
  return playwrightRunner._configDir
75
76
  }
76
- if (playwrightRunner._config && playwrightRunner._config.config) {
77
- return playwrightRunner._config.config.rootDir
77
+ if (playwrightRunner._config) {
78
+ return playwrightRunner._config.config?.rootDir || process.cwd()
78
79
  }
79
80
  return process.cwd()
80
81
  }
81
82
 
82
- function testBeginHandler (test) {
83
- const { _requireFile: testSuiteAbsolutePath, title: testName, _type, location: { line: testSourceLine } } = test
83
+ function getProjectsFromRunner (runner) {
84
+ const config = getPlaywrightConfig(runner)
85
+ return config.projects?.map((project) => {
86
+ if (project.project) {
87
+ return project.project
88
+ }
89
+ return project
90
+ })
91
+ }
92
+
93
+ function getProjectsFromDispatcher (dispatcher) {
94
+ const newConfig = dispatcher._config?.config?.projects
95
+ if (newConfig) {
96
+ return newConfig
97
+ }
98
+ // old
99
+ return dispatcher._loader?.fullConfig()?.projects
100
+ }
101
+
102
+ function getBrowserNameFromProjects (projects, test) {
103
+ if (!projects || !test) {
104
+ return null
105
+ }
106
+ const { _projectIndex, _projectId: testProjectId } = test
107
+
108
+ if (_projectIndex !== undefined) {
109
+ return projects[_projectIndex]?.name
110
+ }
111
+
112
+ return projects.find(({ __projectId, _id, name }) => {
113
+ if (__projectId !== undefined) {
114
+ return __projectId === testProjectId
115
+ }
116
+ if (_id !== undefined) {
117
+ return _id === testProjectId
118
+ }
119
+ return name === testProjectId
120
+ })?.name
121
+ }
122
+
123
+ function formatTestHookError (error, hookType, isTimeout) {
124
+ let hookError = error
125
+ if (error) {
126
+ hookError.message = `Error in ${hookType} hook: ${error.message}`
127
+ }
128
+ if (!hookError && isTimeout) {
129
+ hookError = new Error(`${hookType} hook timed out`)
130
+ }
131
+ return hookError
132
+ }
133
+
134
+ function addErrorToTestSuite (testSuiteAbsolutePath, error) {
135
+ if (testSuiteToErrors.has(testSuiteAbsolutePath)) {
136
+ testSuiteToErrors.get(testSuiteAbsolutePath).push(error)
137
+ } else {
138
+ testSuiteToErrors.set(testSuiteAbsolutePath, [error])
139
+ }
140
+ }
141
+
142
+ function getTestSuiteError (testSuiteAbsolutePath) {
143
+ const errors = testSuiteToErrors.get(testSuiteAbsolutePath)
144
+ if (!errors) {
145
+ return null
146
+ }
147
+ if (errors.length === 1) {
148
+ return errors[0]
149
+ }
150
+ return new Error(`${errors.length} errors in this test suite:\n${errors.map(e => e.message).join('\n------\n')}`)
151
+ }
152
+
153
+ function testBeginHandler (test, browserName) {
154
+ const {
155
+ _requireFile: testSuiteAbsolutePath,
156
+ title: testName, _type,
157
+ location: { line: testSourceLine }
158
+ } = test
84
159
 
85
160
  if (_type === 'beforeAll' || _type === 'afterAll') {
86
161
  return
@@ -100,11 +175,11 @@ function testBeginHandler (test) {
100
175
  const testAsyncResource = new AsyncResource('bound-anonymous-fn')
101
176
  testToAr.set(test, testAsyncResource)
102
177
  testAsyncResource.runInAsyncScope(() => {
103
- testStartCh.publish({ testName, testSuiteAbsolutePath, testSourceLine })
178
+ testStartCh.publish({ testName, testSuiteAbsolutePath, testSourceLine, browserName })
104
179
  })
105
180
  }
106
181
 
107
- function testEndHandler (test, annotations, testStatus, error) {
182
+ function testEndHandler (test, annotations, testStatus, error, isTimeout) {
108
183
  let annotationTags
109
184
  if (annotations.length) {
110
185
  annotationTags = parseAnnotations(annotations)
@@ -112,6 +187,11 @@ function testEndHandler (test, annotations, testStatus, error) {
112
187
  const { _requireFile: testSuiteAbsolutePath, results, _type } = test
113
188
 
114
189
  if (_type === 'beforeAll' || _type === 'afterAll') {
190
+ const hookError = formatTestHookError(error, _type, isTimeout)
191
+
192
+ if (hookError) {
193
+ addErrorToTestSuite(testSuiteAbsolutePath, hookError)
194
+ }
115
195
  return
116
196
  }
117
197
 
@@ -121,15 +201,20 @@ function testEndHandler (test, annotations, testStatus, error) {
121
201
  testFinishCh.publish({ testStatus, steps: testResult.steps, error, extraTags: annotationTags })
122
202
  })
123
203
 
124
- if (!testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
125
- testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
126
- } else {
204
+ if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
127
205
  testSuiteToTestStatuses.get(testSuiteAbsolutePath).push(testStatus)
206
+ } else {
207
+ testSuiteToTestStatuses.set(testSuiteAbsolutePath, [testStatus])
208
+ }
209
+
210
+ if (error) {
211
+ addErrorToTestSuite(testSuiteAbsolutePath, error)
128
212
  }
129
213
 
130
214
  remainingTestsByFile[testSuiteAbsolutePath] = remainingTestsByFile[testSuiteAbsolutePath]
131
215
  .filter(currentTest => currentTest !== test)
132
216
 
217
+ // Last test, we finish the suite
133
218
  if (!remainingTestsByFile[testSuiteAbsolutePath].length) {
134
219
  const testStatuses = testSuiteToTestStatuses.get(testSuiteAbsolutePath)
135
220
 
@@ -140,9 +225,10 @@ function testEndHandler (test, annotations, testStatus, error) {
140
225
  testSuiteStatus = 'skip'
141
226
  }
142
227
 
228
+ const suiteError = getTestSuiteError(testSuiteAbsolutePath)
143
229
  const testSuiteAsyncResource = testSuiteToAr.get(testSuiteAbsolutePath)
144
230
  testSuiteAsyncResource.runInAsyncScope(() => {
145
- testSuiteFinishCh.publish(testSuiteStatus)
231
+ testSuiteFinishCh.publish({ status: testSuiteStatus, error: suiteError })
146
232
  })
147
233
  }
148
234
  }
@@ -166,18 +252,20 @@ function dispatcherHook (dispatcherExport) {
166
252
  shimmer.wrap(dispatcherExport.Dispatcher.prototype, '_createWorker', createWorker => function () {
167
253
  const dispatcher = this
168
254
  const worker = createWorker.apply(this, arguments)
169
-
170
255
  worker.process.on('message', ({ method, params }) => {
171
256
  if (method === 'testBegin') {
172
257
  const { test } = dispatcher._testById.get(params.testId)
173
- testBeginHandler(test)
258
+ const projects = getProjectsFromDispatcher(dispatcher)
259
+ const browser = getBrowserNameFromProjects(projects, test)
260
+ testBeginHandler(test, browser)
174
261
  } else if (method === 'testEnd') {
175
262
  const { test } = dispatcher._testById.get(params.testId)
176
263
 
177
264
  const { results } = test
178
265
  const testResult = results[results.length - 1]
179
266
 
180
- testEndHandler(test, params.annotations, STATUS_TO_TEST_STATUS[testResult.status], testResult.error)
267
+ const isTimeout = testResult.status === 'timedOut'
268
+ testEndHandler(test, params.annotations, STATUS_TO_TEST_STATUS[testResult.status], testResult.error, isTimeout)
181
269
  }
182
270
  })
183
271
 
@@ -203,12 +291,15 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
203
291
 
204
292
  worker.on('testBegin', ({ testId }) => {
205
293
  const test = getTestByTestId(dispatcher, testId)
206
- testBeginHandler(test)
294
+ const projects = getProjectsFromDispatcher(dispatcher)
295
+ const browser = getBrowserNameFromProjects(projects, test)
296
+ testBeginHandler(test, browser)
207
297
  })
208
298
  worker.on('testEnd', ({ testId, status, errors, annotations }) => {
209
299
  const test = getTestByTestId(dispatcher, testId)
210
300
 
211
- testEndHandler(test, annotations, STATUS_TO_TEST_STATUS[status], errors && errors[0])
301
+ const isTimeout = status === 'timedOut'
302
+ testEndHandler(test, annotations, STATUS_TO_TEST_STATUS[status], errors && errors[0], isTimeout)
212
303
  })
213
304
 
214
305
  return worker
@@ -226,6 +317,7 @@ function runnerHook (runnerExport, playwrightVersion) {
226
317
  testSessionAsyncResource.runInAsyncScope(() => {
227
318
  testSessionStartCh.publish({ command, frameworkVersion: playwrightVersion, rootDir })
228
319
  })
320
+ const projects = getProjectsFromRunner(this)
229
321
 
230
322
  const runAllTestsReturn = await runAllTests.apply(this, arguments)
231
323
 
@@ -234,7 +326,8 @@ function runnerHook (runnerExport, playwrightVersion) {
234
326
  // there were tests that did not go through `testBegin` or `testEnd`,
235
327
  // because they were skipped
236
328
  tests.forEach(test => {
237
- testBeginHandler(test)
329
+ const browser = getBrowserNameFromProjects(projects, test)
330
+ testBeginHandler(test, browser)
238
331
  testEndHandler(test, [], 'skip')
239
332
  })
240
333
  })
@@ -295,6 +388,7 @@ addHook({
295
388
  file: 'lib/runner/runner.js',
296
389
  versions: ['>=1.38.0']
297
390
  }, runnerHook)
391
+
298
392
  addHook({
299
393
  name: 'playwright',
300
394
  file: 'lib/runner/dispatcher.js',
@@ -50,7 +50,20 @@ function wrapFn (fn) {
50
50
  enterChannel.publish({ req, route })
51
51
 
52
52
  try {
53
- return fn.apply(this, arguments)
53
+ const result = fn.apply(this, arguments)
54
+ if (result && typeof result === 'object' && typeof result.then === 'function') {
55
+ return result.then(function () {
56
+ nextChannel.publish({ req })
57
+ finishChannel.publish({ req })
58
+ return arguments[0]
59
+ }).catch(function (error) {
60
+ errorChannel.publish({ req, error })
61
+ nextChannel.publish({ req })
62
+ finishChannel.publish({ req })
63
+ throw error
64
+ })
65
+ }
66
+ return result
54
67
  } catch (error) {
55
68
  errorChannel.publish({ req, error })
56
69
  nextChannel.publish({ req })
@@ -22,7 +22,7 @@ const dispatchReceiveCh = channel('apm:rhea:receive:dispatch')
22
22
  const errorReceiveCh = channel('apm:rhea:receive:error')
23
23
  const finishReceiveCh = channel('apm:rhea:receive:finish')
24
24
 
25
- const contexts = new WeakMap()
25
+ const contexts = new WeakMap() // key: delivery Fn, val: context
26
26
 
27
27
  addHook({ name: 'rhea', versions: ['>=1'] }, rhea => {
28
28
  shimmer.wrap(rhea.message, 'encode', encode => function (msg) {
@@ -52,7 +52,8 @@ addHook({ name: 'rhea', versions: ['>=1'], file: 'lib/link.js' }, obj => {
52
52
  startSendCh.publish({ targetAddress, host, port, msg })
53
53
  const delivery = send.apply(this, arguments)
54
54
  const context = {
55
- asyncResource
55
+ asyncResource,
56
+ connection: this.connection
56
57
  }
57
58
  contexts.set(delivery, context)
58
59
 
@@ -80,7 +81,8 @@ addHook({ name: 'rhea', versions: ['>=1'], file: 'lib/link.js' }, obj => {
80
81
 
81
82
  if (msgObj.delivery) {
82
83
  const context = {
83
- asyncResource
84
+ asyncResource,
85
+ connection: this.connection
84
86
  }
85
87
  contexts.set(msgObj.delivery, context)
86
88
  msgObj.delivery.update = wrapDeliveryUpdate(msgObj.delivery, msgObj.delivery.update)
@@ -114,7 +116,7 @@ addHook({ name: 'rhea', versions: ['>=1'], file: 'lib/connection.js' }, Connecti
114
116
 
115
117
  asyncResource.runInAsyncScope(() => {
116
118
  errorReceiveCh.publish(error)
117
- beforeFinish(delivery, null)
119
+ exports.beforeFinish(delivery, null)
118
120
  finishReceiveCh.publish()
119
121
  })
120
122
  })
@@ -187,7 +189,7 @@ function patchCircularBuffer (proto, Session) {
187
189
  const state = remoteState && remoteState.constructor
188
190
  ? entry.remote_state.constructor.composite_type : undefined
189
191
  asyncResource.runInAsyncScope(() => {
190
- beforeFinish(entry, state)
192
+ exports.beforeFinish(entry, state)
191
193
  finishSendCh.publish()
192
194
  })
193
195
  }
@@ -217,13 +219,13 @@ function addToInFlightDeliveries (connection, delivery) {
217
219
  }
218
220
 
219
221
  function beforeFinish (delivery, state) {
220
- const obj = contexts.get(delivery)
221
- if (obj) {
222
+ const context = contexts.get(delivery)
223
+ if (context) {
222
224
  if (state) {
223
225
  dispatchReceiveCh.publish({ state })
224
226
  }
225
- if (obj.connection && obj.connection[inFlightDeliveries]) {
226
- obj.connection[inFlightDeliveries].delete(delivery)
227
+ if (context.connection && context.connection[inFlightDeliveries]) {
228
+ context.connection[inFlightDeliveries].delete(delivery)
227
229
  }
228
230
  }
229
231
  }
@@ -238,3 +240,7 @@ function getStateFromData (stateData) {
238
240
  }
239
241
  }
240
242
  }
243
+
244
+ module.exports.inFlightDeliveries = inFlightDeliveries
245
+ module.exports.beforeFinish = beforeFinish
246
+ module.exports.contexts = contexts
@@ -0,0 +1,113 @@
1
+ 'use strict'
2
+
3
+ const { storage } = require('../../datadog-core')
4
+ const DatabasePlugin = require('../../dd-trace/src/plugins/database')
5
+
6
+ const AEROSPIKE_PEER_SERVICE = 'aerospike.namespace'
7
+
8
+ class AerospikePlugin extends DatabasePlugin {
9
+ static get id () { return 'aerospike' }
10
+ static get operation () { return 'command' }
11
+ static get system () { return 'aerospike' }
12
+ static get prefix () {
13
+ return 'tracing:apm:aerospike:command'
14
+ }
15
+
16
+ static get peerServicePrecursors () {
17
+ return [AEROSPIKE_PEER_SERVICE]
18
+ }
19
+
20
+ bindStart (ctx) {
21
+ const { commandName, commandArgs } = ctx
22
+ const resourceName = commandName.slice(0, commandName.indexOf('Command'))
23
+ const store = storage.getStore()
24
+ const childOf = store ? store.span : null
25
+ const meta = getMeta(resourceName, commandArgs)
26
+
27
+ const span = this.startSpan(this.operationName(), {
28
+ childOf,
29
+ service: this.serviceName({ pluginConfig: this.config }),
30
+ type: 'aerospike',
31
+ kind: 'client',
32
+ resource: resourceName,
33
+ meta
34
+ }, false)
35
+
36
+ ctx.parentStore = store
37
+ ctx.currentStore = { ...store, span }
38
+
39
+ return ctx.currentStore
40
+ }
41
+
42
+ bindAsyncStart (ctx) {
43
+ if (ctx.currentStore) {
44
+ // have to manually trigger peer service calculation when using tracing channel
45
+ this.tagPeerService(ctx.currentStore.span)
46
+ ctx.currentStore.span.finish()
47
+ }
48
+ return ctx.parentStore
49
+ }
50
+
51
+ end (ctx) {
52
+ if (ctx.result) {
53
+ // have to manually trigger peer service calculation when using tracing channel
54
+ this.tagPeerService(ctx.currentStore.span)
55
+ ctx.currentStore.span.finish()
56
+ }
57
+ }
58
+
59
+ error (ctx) {
60
+ if (ctx.error) {
61
+ const error = ctx.error
62
+ const span = ctx.currentStore.span
63
+ span.setTag('error', error)
64
+ }
65
+ }
66
+ }
67
+
68
+ function getMeta (resourceName, commandArgs) {
69
+ let meta = {}
70
+ if (resourceName.includes('Index')) {
71
+ const [ns, set, bin, index] = commandArgs
72
+ meta = getMetaForIndex(ns, set, bin, index)
73
+ } else if (resourceName === 'Query') {
74
+ const { ns, set } = commandArgs[2]
75
+ meta = getMetaForQuery({ ns, set })
76
+ } else if (isKeyObject(commandArgs[0])) {
77
+ const { ns, set, key } = commandArgs[0]
78
+ meta = getMetaForKey(ns, set, key)
79
+ }
80
+ return meta
81
+ }
82
+
83
+ function getMetaForIndex (ns, set, bin, index) {
84
+ return {
85
+ [AEROSPIKE_PEER_SERVICE]: ns,
86
+ 'aerospike.setname': set,
87
+ 'aerospike.bin': bin,
88
+ 'aerospike.index': index
89
+ }
90
+ }
91
+
92
+ function getMetaForKey (ns, set, key) {
93
+ return {
94
+ 'aerospike.key': `${ns}:${set}:${key}`,
95
+ [AEROSPIKE_PEER_SERVICE]: ns,
96
+ 'aerospike.setname': set,
97
+ 'aerospike.userkey': key
98
+ }
99
+ }
100
+
101
+ function getMetaForQuery (queryObj) {
102
+ const { ns, set } = queryObj
103
+ return {
104
+ [AEROSPIKE_PEER_SERVICE]: ns,
105
+ 'aerospike.setname': set
106
+ }
107
+ }
108
+
109
+ function isKeyObject (obj) {
110
+ return obj && obj.ns !== undefined && obj.set !== undefined && obj.key !== undefined
111
+ }
112
+
113
+ module.exports = AerospikePlugin
@@ -2,6 +2,8 @@
2
2
 
3
3
  const { TEXT_MAP } = require('../../../ext/formats')
4
4
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
5
+ const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
6
+ const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
5
7
  const { getResourceName } = require('./util')
6
8
 
7
9
  class AmqplibConsumerPlugin extends ConsumerPlugin {
@@ -13,7 +15,7 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
13
15
 
14
16
  const childOf = extract(this.tracer, message)
15
17
 
16
- this.startSpan({
18
+ const span = this.startSpan({
17
19
  childOf,
18
20
  resource: getResourceName(method, fields),
19
21
  type: 'worker',
@@ -26,6 +28,17 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
26
28
  'amqp.destination': fields.destination
27
29
  }
28
30
  })
31
+
32
+ if (
33
+ this.config.dsmEnabled && message?.properties?.headers &&
34
+ DsmPathwayCodec.contextExists(message.properties.headers)
35
+ ) {
36
+ const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
37
+ const queue = fields.queue ? fields.queue : fields.routingKey
38
+ this.tracer.decodeDataStreamsContext(message.properties.headers)
39
+ this.tracer
40
+ .setCheckpoint(['direction:in', `topic:${queue}`, 'type:rabbitmq'], span, payloadSize)
41
+ }
29
42
  }
30
43
  }
31
44
 
@@ -3,13 +3,15 @@
3
3
  const { TEXT_MAP } = require('../../../ext/formats')
4
4
  const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
5
5
  const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
6
+ const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
7
+ const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
6
8
  const { getResourceName } = require('./util')
7
9
 
8
10
  class AmqplibProducerPlugin extends ProducerPlugin {
9
11
  static get id () { return 'amqplib' }
10
12
  static get operation () { return 'command' }
11
13
 
12
- start ({ channel = {}, method, fields }) {
14
+ start ({ channel = {}, method, fields, message }) {
13
15
  if (method !== 'basic.publish') return
14
16
 
15
17
  const stream = (channel.connection && channel.connection.stream) || {}
@@ -30,6 +32,16 @@ class AmqplibProducerPlugin extends ProducerPlugin {
30
32
  fields.headers = fields.headers || {}
31
33
 
32
34
  this.tracer.inject(span, TEXT_MAP, fields.headers)
35
+
36
+ if (this.config.dsmEnabled) {
37
+ const hasRoutingKey = fields.routingKey != null
38
+ const payloadSize = getAmqpMessageSize({ content: message, headers: fields.headers })
39
+ const dataStreamsContext = this.tracer
40
+ .setCheckpoint(
41
+ ['direction:out', `exchange:${fields.exchange}`, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq']
42
+ , span, payloadSize)
43
+ DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
44
+ }
33
45
  }
34
46
  }
35
47
 
@@ -126,8 +126,9 @@ class BaseAwsSdkPlugin extends ClientPlugin {
126
126
  if (err) {
127
127
  span.setTag('error', err)
128
128
 
129
- if (err.requestId) {
130
- span.addTags({ 'aws.response.request_id': err.requestId })
129
+ const requestId = err.RequestId || err.requestId
130
+ if (requestId) {
131
+ span.addTags({ 'aws.response.request_id': requestId })
131
132
  }
132
133
  }
133
134