dd-trace 5.45.0 → 5.47.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 (86) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/ci/init.js +8 -0
  3. package/ext/exporters.d.ts +2 -1
  4. package/ext/exporters.js +2 -1
  5. package/package.json +8 -9
  6. package/packages/datadog-instrumentations/orchestrion.yml +52 -0
  7. package/packages/datadog-instrumentations/src/cucumber.js +2 -1
  8. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  9. package/packages/datadog-instrumentations/src/helpers/register.js +41 -1
  10. package/packages/datadog-instrumentations/src/jest.js +11 -2
  11. package/packages/datadog-instrumentations/src/langchain.js +49 -53
  12. package/packages/datadog-instrumentations/src/mariadb.js +19 -0
  13. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  14. package/packages/datadog-instrumentations/src/mocha/utils.js +11 -3
  15. package/packages/datadog-instrumentations/src/orchestrion-config/index.js +5 -0
  16. package/packages/datadog-instrumentations/src/playwright.js +333 -46
  17. package/packages/datadog-instrumentations/src/router.js +1 -7
  18. package/packages/datadog-instrumentations/src/vitest.js +11 -3
  19. package/packages/datadog-plugin-cucumber/src/index.js +11 -4
  20. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +17 -5
  21. package/packages/datadog-plugin-jest/src/index.js +11 -4
  22. package/packages/datadog-plugin-langchain/src/index.js +18 -12
  23. package/packages/datadog-plugin-langchain/src/tracing.js +66 -6
  24. package/packages/datadog-plugin-mocha/src/index.js +17 -5
  25. package/packages/datadog-plugin-mongodb-core/src/index.js +24 -0
  26. package/packages/datadog-plugin-playwright/src/index.js +124 -10
  27. package/packages/datadog-plugin-vitest/src/index.js +13 -8
  28. package/packages/datadog-shimmer/src/shimmer.js +3 -42
  29. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +39 -15
  30. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +3 -3
  31. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +0 -3
  32. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +25 -12
  33. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +3 -32
  34. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +99 -57
  35. package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
  36. package/packages/dd-trace/src/appsec/rasp/index.js +4 -2
  37. package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
  38. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +1 -1
  39. package/packages/dd-trace/src/appsec/rasp/ssrf.js +1 -1
  40. package/packages/dd-trace/src/appsec/rasp/utils.js +12 -7
  41. package/packages/dd-trace/src/appsec/recommended.json +256 -84
  42. package/packages/dd-trace/src/appsec/reporter.js +6 -4
  43. package/packages/dd-trace/src/appsec/telemetry/index.js +27 -3
  44. package/packages/dd-trace/src/appsec/telemetry/rasp.js +70 -6
  45. package/packages/dd-trace/src/appsec/telemetry/waf.js +0 -30
  46. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -0
  47. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +8 -3
  48. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +6 -4
  49. package/packages/dd-trace/src/config.js +9 -0
  50. package/packages/dd-trace/src/constants.js +1 -0
  51. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +102 -22
  52. package/packages/dd-trace/src/debugger/devtools_client/condition.js +263 -0
  53. package/packages/dd-trace/src/debugger/devtools_client/index.js +69 -36
  54. package/packages/dd-trace/src/debugger/devtools_client/lock.js +8 -0
  55. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +1 -7
  56. package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -2
  57. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +15 -10
  58. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +3 -3
  59. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +69 -62
  60. package/packages/dd-trace/src/debugger/devtools_client/state.js +3 -2
  61. package/packages/dd-trace/src/debugger/index.js +3 -0
  62. package/packages/dd-trace/src/encode/0.4.js +24 -17
  63. package/packages/dd-trace/src/exporter.js +1 -0
  64. package/packages/dd-trace/src/exporters/common/docker.js +37 -7
  65. package/packages/dd-trace/src/exporters/common/request.js +1 -4
  66. package/packages/dd-trace/src/format.js +58 -60
  67. package/packages/dd-trace/src/llmobs/plugins/base.js +2 -2
  68. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +62 -3
  69. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -0
  70. package/packages/dd-trace/src/llmobs/plugins/vertexai.js +2 -1
  71. package/packages/dd-trace/src/llmobs/writers/spans/base.js +3 -3
  72. package/packages/dd-trace/src/log/index.js +2 -0
  73. package/packages/dd-trace/src/log/writer.js +19 -2
  74. package/packages/dd-trace/src/opentelemetry/span.js +4 -4
  75. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -3
  76. package/packages/dd-trace/src/opentracing/span.js +10 -0
  77. package/packages/dd-trace/src/plugin_manager.js +2 -0
  78. package/packages/dd-trace/src/plugins/util/test.js +11 -0
  79. package/packages/dd-trace/src/profiler.js +1 -1
  80. package/packages/dd-trace/src/profiling/config.js +6 -0
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -5
  82. package/packages/dd-trace/src/profiling/profiler.js +4 -3
  83. package/packages/dd-trace/src/profiling/profilers/wall.js +12 -8
  84. package/packages/dd-trace/src/proxy.js +5 -1
  85. package/packages/dd-trace/src/tagger.js +38 -26
  86. package/packages/dd-trace/src/util.js +1 -7
@@ -2,10 +2,10 @@ Component,Origin,License,Copyright
2
2
  require,@datadog/libdatadog,Apache license 2.0,Copyright 2024 Datadog Inc.
3
3
  require,@datadog/native-appsec,Apache license 2.0,Copyright 2018 Datadog Inc.
4
4
  require,@datadog/native-metrics,Apache license 2.0,Copyright 2018 Datadog Inc.
5
- require,@datadog/native-iast-rewriter,Apache license 2.0,Copyright 2018 Datadog Inc.
6
5
  require,@datadog/native-iast-taint-tracking,Apache license 2.0,Copyright 2018 Datadog Inc.
7
6
  require,@datadog/pprof,Apache license 2.0,Copyright 2019 Google Inc.
8
7
  require,@datadog/sketches-js,Apache license 2.0,Copyright 2020 Datadog Inc.
8
+ require,@datadog/wasm-js-rewriter,Apache license 2.0,Copyright 2018 Datadog Inc.
9
9
  require,@opentelemetry/api,Apache license 2.0,Copyright OpenTelemetry Authors
10
10
  require,@opentelemetry/core,Apache license 2.0,Copyright OpenTelemetry Authors
11
11
  require,@isaacs/ttlcache,ISC,Copyright (c) 2022-2023 - Isaac Z. Schlueter and Contributors
@@ -38,7 +38,6 @@ dev,@eslint/eslintrc,MIT,Copyright OpenJS Foundation and other contributors, <ww
38
38
  dev,@eslint/js,MIT,Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
39
39
  dev,@msgpack/msgpack,ISC,Copyright 2019 The MessagePack Community
40
40
  dev,@stylistic/eslint-plugin-js,MIT,Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
41
- dev,application-config-path,MIT,Copyright (c) 2015, 2023 Linus Unnebäck
42
41
  dev,autocannon,MIT,Copyright 2016 Matteo Collina
43
42
  dev,aws-sdk,Apache 2.0,Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
44
43
  dev,axios,MIT,Copyright 2014-present Matt Zabriskie
package/ci/init.js CHANGED
@@ -7,6 +7,8 @@ const isJestWorker = !!process.env.JEST_WORKER_ID
7
7
  const isCucumberWorker = !!process.env.CUCUMBER_WORKER_ID
8
8
  const isMochaWorker = !!process.env.MOCHA_WORKER_ID
9
9
 
10
+ const isPlaywrightWorker = !!process.env.DD_PLAYWRIGHT_WORKER
11
+
10
12
  const packageManagers = [
11
13
  'npm',
12
14
  'yarn',
@@ -67,6 +69,12 @@ if (isMochaWorker) {
67
69
  }
68
70
  }
69
71
 
72
+ if (isPlaywrightWorker) {
73
+ options.experimental = {
74
+ exporter: 'playwright_worker'
75
+ }
76
+ }
77
+
70
78
  if (shouldInit) {
71
79
  tracer.init(options)
72
80
  tracer.use('fs', false)
@@ -5,7 +5,8 @@ declare const exporters: {
5
5
  AGENT_PROXY: 'agent_proxy',
6
6
  JEST_WORKER: 'jest_worker',
7
7
  CUCUMBER_WORKER: 'cucumber_worker',
8
- MOCHA_WORKER: 'mocha_worker'
8
+ MOCHA_WORKER: 'mocha_worker',
9
+ PLAYWRIGHT_WORKER: 'playwright_worker'
9
10
  }
10
11
 
11
12
  export = exporters
package/ext/exporters.js CHANGED
@@ -6,5 +6,6 @@ module.exports = {
6
6
  AGENT_PROXY: 'agent_proxy',
7
7
  JEST_WORKER: 'jest_worker',
8
8
  CUCUMBER_WORKER: 'cucumber_worker',
9
- MOCHA_WORKER: 'mocha_worker'
9
+ MOCHA_WORKER: 'mocha_worker',
10
+ PLAYWRIGHT_WORKER: 'playwright_worker'
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.45.0",
3
+ "version": "5.47.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -84,18 +84,18 @@
84
84
  "node": ">=18"
85
85
  },
86
86
  "dependencies": {
87
- "@datadog/libdatadog": "^0.5.0",
88
- "@datadog/native-appsec": "8.5.1",
89
- "@datadog/native-iast-rewriter": "2.8.0",
90
- "@datadog/native-iast-taint-tracking": "3.3.0",
91
- "@datadog/native-metrics": "^3.1.0",
92
- "@datadog/pprof": "5.6.0",
87
+ "@datadog/libdatadog": "^0.5.1",
88
+ "@datadog/native-appsec": "8.5.2",
89
+ "@datadog/native-iast-taint-tracking": "3.3.1",
90
+ "@datadog/native-metrics": "^3.1.1",
91
+ "@datadog/pprof": "5.7.1",
93
92
  "@datadog/sketches-js": "^2.1.0",
93
+ "@datadog/wasm-js-rewriter": "4.0.0",
94
94
  "@isaacs/ttlcache": "^1.4.1",
95
95
  "@opentelemetry/api": ">=1.0.0 <1.9.0",
96
96
  "@opentelemetry/core": "^1.14.0",
97
97
  "crypto-randomuuid": "^1.0.0",
98
- "dc-polyfill": "0.1.6",
98
+ "dc-polyfill": "0.1.8",
99
99
  "ignore": "^5.2.4",
100
100
  "import-in-the-middle": "1.13.1",
101
101
  "istanbul-lib-coverage": "3.2.0",
@@ -125,7 +125,6 @@
125
125
  "@msgpack/msgpack": "^3.0.0-beta3",
126
126
  "@stylistic/eslint-plugin-js": "^3.0.1",
127
127
  "@types/node": "^16.0.0",
128
- "application-config-path": "^0.1.1",
129
128
  "autocannon": "^4.5.2",
130
129
  "aws-sdk": "^2.1446.0",
131
130
  "axios": "^1.8.2",
@@ -0,0 +1,52 @@
1
+ version: 1
2
+ dc_module: dc-polyfill
3
+ instrumentations:
4
+ - module_name: "@langchain/core"
5
+ version_range: ">=0.1.0"
6
+ file_path: dist/runnables/base.js
7
+ function_query:
8
+ name: invoke
9
+ type: method
10
+ kind: async
11
+ class: RunnableSequence
12
+ operator: tracePromise
13
+ channel_name: "RunnableSequence_invoke"
14
+ - module_name: "@langchain/core"
15
+ version_range: ">=0.1.0"
16
+ file_path: dist/runnables/base.js
17
+ function_query:
18
+ name: batch
19
+ type: method
20
+ kind: async
21
+ class: RunnableSequence
22
+ operator: tracePromise
23
+ channel_name: "RunnableSequence_batch"
24
+ - module_name: "@langchain/core"
25
+ version_range: ">=0.1.0"
26
+ file_path: dist/language_models/chat_models.js
27
+ function_query:
28
+ name: generate
29
+ type: method
30
+ kind: async
31
+ class: BaseChatModel
32
+ operator: tracePromise
33
+ channel_name: "BaseChatModel_generate"
34
+ - module_name: "@langchain/core"
35
+ version_range: ">=0.1.0"
36
+ file_path: dist/language_models/llms.js
37
+ function_query:
38
+ name: generate
39
+ type: method
40
+ kind: async
41
+ operator: tracePromise
42
+ channel_name: "BaseLLM_generate"
43
+ - module_name: "@langchain/core"
44
+ version_range: ">=0.1.0"
45
+ file_path: dist/embeddings.js
46
+ function_query:
47
+ name: constructor
48
+ type: method
49
+ kind: sync
50
+ class: Embeddings
51
+ operator: traceSync
52
+ channel_name: "Embeddings_constructor"
@@ -267,6 +267,7 @@ function wrapRun (pl, isLatestVersion) {
267
267
 
268
268
  const failedAttemptAsyncResource = numAttemptToAsyncResource.get(numAttempt)
269
269
  const isFirstAttempt = numAttempt++ === 0
270
+ const isAtrRetry = !isFirstAttempt && isFlakyTestRetriesEnabled
270
271
 
271
272
  if (promises.hitBreakpointPromise) {
272
273
  await promises.hitBreakpointPromise
@@ -274,7 +275,7 @@ function wrapRun (pl, isLatestVersion) {
274
275
 
275
276
  failedAttemptAsyncResource.runInAsyncScope(() => {
276
277
  // the current span will be finished and a new one will be created
277
- testRetryCh.publish({ isFirstAttempt, error })
278
+ testRetryCh.publish({ isFirstAttempt, error, isAtrRetry })
278
279
  })
279
280
 
280
281
  const newAsyncResource = new AsyncResource('bound-anonymous-fn')
@@ -111,6 +111,7 @@ module.exports = {
111
111
  pino: () => require('../pino'),
112
112
  'pino-pretty': () => require('../pino'),
113
113
  playwright: () => require('../playwright'),
114
+ 'playwright-core': () => require('../playwright'),
114
115
  'promise-js': () => require('../promise-js'),
115
116
  promise: () => require('../promise'),
116
117
  protobufjs: () => require('../protobufjs'),
@@ -51,6 +51,7 @@ if (DD_TRACE_DEBUG && DD_TRACE_DEBUG.toLowerCase() !== 'false') {
51
51
  }
52
52
 
53
53
  const seenCombo = new Set()
54
+ const allInstrumentations = {}
54
55
 
55
56
  // TODO: make this more efficient
56
57
  for (const packageName of names) {
@@ -67,6 +68,9 @@ for (const packageName of names) {
67
68
  hook = hook.fn
68
69
  }
69
70
 
71
+ // get the instrumentation file name to save all hooked versions
72
+ const instrumentationFileName = parseHookInstrumentationFileName(packageName)
73
+
70
74
  Hook([packageName], hookOptions, (moduleExports, moduleName, moduleBaseDir, moduleVersion) => {
71
75
  moduleName = moduleName.replace(pathSepExpr, '/')
72
76
 
@@ -105,6 +109,7 @@ for (const packageName of names) {
105
109
  let version = moduleVersion
106
110
  try {
107
111
  version = version || getVersion(moduleBaseDir)
112
+ allInstrumentations[instrumentationFileName] = allInstrumentations[instrumentationFileName] || false
108
113
  } catch (e) {
109
114
  log.error('Error getting version for "%s": %s', name, e.message, e)
110
115
  continue
@@ -114,6 +119,8 @@ for (const packageName of names) {
114
119
  }
115
120
 
116
121
  if (matchVersion(version, versions)) {
122
+ allInstrumentations[instrumentationFileName] = true
123
+
117
124
  // Check if the hook already has a set moduleExport
118
125
  if (hook[HOOK_SYMBOL].has(moduleExports)) {
119
126
  namesAndSuccesses[`${name}@${version}`] = true
@@ -143,7 +150,8 @@ for (const packageName of names) {
143
150
  for (const nameVersion of Object.keys(namesAndSuccesses)) {
144
151
  const [name, version] = nameVersion.split('@')
145
152
  const success = namesAndSuccesses[nameVersion]
146
- if (!success && !seenCombo.has(nameVersion)) {
153
+ // we check allVersions to see if any version of the integration was successfully instrumented
154
+ if (!success && !seenCombo.has(nameVersion) && !allInstrumentations[instrumentationFileName]) {
147
155
  telemetry('abort.integration', [
148
156
  `integration:${name}`,
149
157
  `integration_version:${version}`
@@ -171,6 +179,38 @@ function filename (name, file) {
171
179
  return [name, file].filter(val => val).join('/')
172
180
  }
173
181
 
182
+ // This function captures the instrumentation file name for a given package by parsing the hook require
183
+ // function given the module name. It is used to ensure that instrumentations such as redis
184
+ // that have several different modules being hooked, ie: 'redis' main package, and @redis/client submodule
185
+ // return a consistent instrumentation name. This is used later to ensure that atleast some portion of
186
+ // the integration was successfully instrumented. Prevents incorrect `Found incompatible integration version: ` messages
187
+ // Example:
188
+ // redis -> "() => require('../redis')" -> redis
189
+ // @redis/client -> "() => require('../redis')" -> redis
190
+ //
191
+ function parseHookInstrumentationFileName (packageName) {
192
+ let hook = hooks[packageName]
193
+ if (hook.fn) {
194
+ hook = hook.fn
195
+ }
196
+ const hookString = hook.toString()
197
+
198
+ const regex = /require\('([^']*)'\)/
199
+ const match = hookString.match(regex)
200
+
201
+ // try to capture the hook require file location.
202
+ if (match && match[1]) {
203
+ let moduleName = match[1]
204
+ // Remove leading '../' if present
205
+ if (moduleName.startsWith('../')) {
206
+ moduleName = moduleName.substring(3)
207
+ }
208
+ return moduleName
209
+ }
210
+
211
+ return null
212
+ }
213
+
174
214
  module.exports = {
175
215
  filename,
176
216
  pathSepExpr,
@@ -399,10 +399,11 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
399
399
 
400
400
  let attemptToFixPassed = false
401
401
  let failedAllTests = false
402
+ let isAttemptToFix = false
402
403
  if (this.isTestManagementTestsEnabled) {
403
404
  const testName = getJestTestName(event.test)
404
405
  const originalTestName = removeAttemptToFixStringFromTestName(testName)
405
- const isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(originalTestName)
406
+ isAttemptToFix = this.testManagementTestsForThisSuite?.attemptToFix?.includes(originalTestName)
406
407
  if (isAttemptToFix) {
407
408
  if (attemptToFixRetriedTestsStatuses.has(originalTestName)) {
408
409
  attemptToFixRetriedTestsStatuses.get(originalTestName).push(status)
@@ -423,6 +424,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
423
424
  }
424
425
  }
425
426
 
427
+ let isEfdRetry = false
426
428
  // We'll store the test statuses of the retries
427
429
  if (this.isKnownTestsEnabled) {
428
430
  const testName = getJestTestName(event.test)
@@ -431,6 +433,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
431
433
  if (isNewTest) {
432
434
  if (newTestsTestStatuses.has(originalTestName)) {
433
435
  newTestsTestStatuses.get(originalTestName).push(status)
436
+ isEfdRetry = true
434
437
  } else {
435
438
  newTestsTestStatuses.set(originalTestName, [status])
436
439
  }
@@ -466,12 +469,18 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
466
469
  })
467
470
  }
468
471
 
472
+ let isAtrRetry = false
473
+ if (this.isFlakyTestRetriesEnabled && event.test?.invocations > 1 && !isAttemptToFix && !isEfdRetry) {
474
+ isAtrRetry = true
475
+ }
476
+
469
477
  asyncResource.runInAsyncScope(() => {
470
478
  testFinishCh.publish({
471
479
  status,
472
480
  testStartLine: getTestLineStart(event.test.asyncError, this.testSuite),
473
481
  attemptToFixPassed,
474
- failedAllTests
482
+ failedAllTests,
483
+ isAtrRetry
475
484
  })
476
485
  })
477
486
 
@@ -1,31 +1,24 @@
1
1
  'use strict'
2
-
3
2
  const { addHook } = require('./helpers/instrument')
3
+
4
4
  const shimmer = require('../../datadog-shimmer')
5
5
 
6
6
  const tracingChannel = require('dc-polyfill').tracingChannel
7
7
 
8
- const invokeTracingChannel = tracingChannel('apm:langchain:invoke')
9
-
10
- function wrapLangChainPromise (fn, type, namespace = []) {
11
- return function () {
12
- if (!invokeTracingChannel.start.hasSubscribers) {
13
- return fn.apply(this, arguments)
14
- }
15
-
16
- // Runnable interfaces have an `lc_namespace` property
17
- const ns = this.lc_namespace || namespace
18
- const resource = [...ns, this.constructor.name].join('.')
19
-
20
- const ctx = {
21
- args: arguments,
22
- instance: this,
23
- type,
24
- resource
8
+ function wrap (obj, name, channelName, namespace) {
9
+ const channel = tracingChannel(channelName)
10
+ shimmer.wrap(obj, name, function (original) {
11
+ return function () {
12
+ if (!channel.start.hasSubscribers) {
13
+ return original.apply(this, arguments)
14
+ }
15
+ const ctx = { self: this, arguments }
16
+ if (namespace) {
17
+ ctx.namespace = namespace
18
+ }
19
+ return channel.tracePromise(original, ctx, this, ...arguments)
25
20
  }
26
-
27
- return invokeTracingChannel.tracePromise(fn, ctx, this, ...arguments)
28
- }
21
+ })
29
22
  }
30
23
 
31
24
  // langchain compiles into ESM and CommonJS, with ESM being the default and landing in the `.js` files
@@ -35,9 +28,10 @@ const extensions = ['js', 'cjs']
35
28
 
36
29
  for (const extension of extensions) {
37
30
  addHook({ name: '@langchain/core', file: `dist/runnables/base.${extension}`, versions: ['>=0.1'] }, exports => {
38
- const RunnableSequence = exports.RunnableSequence
39
- shimmer.wrap(RunnableSequence.prototype, 'invoke', invoke => wrapLangChainPromise(invoke, 'chain'))
40
- shimmer.wrap(RunnableSequence.prototype, 'batch', batch => wrapLangChainPromise(batch, 'chain'))
31
+ if (extension === 'cjs') {
32
+ wrap(exports.RunnableSequence.prototype, 'invoke', 'orchestrion:@langchain/core:RunnableSequence_invoke')
33
+ wrap(exports.RunnableSequence.prototype, 'batch', 'orchestrion:@langchain/core:RunnableSequence_batch')
34
+ }
41
35
  return exports
42
36
  })
43
37
 
@@ -46,51 +40,53 @@ for (const extension of extensions) {
46
40
  file: `dist/language_models/chat_models.${extension}`,
47
41
  versions: ['>=0.1']
48
42
  }, exports => {
49
- const BaseChatModel = exports.BaseChatModel
50
- shimmer.wrap(
51
- BaseChatModel.prototype,
52
- 'generate',
53
- generate => wrapLangChainPromise(generate, 'chat_model')
54
- )
43
+ if (extension === 'cjs') {
44
+ wrap(exports.BaseChatModel.prototype, 'generate', 'orchestrion:@langchain/core:BaseChatModel_generate')
45
+ }
55
46
  return exports
56
47
  })
57
48
 
58
49
  addHook({ name: '@langchain/core', file: `dist/language_models/llms.${extension}`, versions: ['>=0.1'] }, exports => {
59
- const BaseLLM = exports.BaseLLM
60
- shimmer.wrap(BaseLLM.prototype, 'generate', generate => wrapLangChainPromise(generate, 'llm'))
50
+ if (extension === 'cjs') {
51
+ wrap(exports.BaseLLM.prototype, 'generate', 'orchestrion:@langchain/core:BaseLLM_generate')
52
+ }
61
53
  return exports
62
54
  })
63
55
 
64
56
  addHook({ name: '@langchain/core', file: `dist/embeddings.${extension}`, versions: ['>=0.1'] }, exports => {
65
- // we cannot patch the prototype of the Embeddings class directly
66
- // this is because the "abstract class Embeddings" is transpiled from TypeScript to not include abstract functions
67
- // thus, we patch the exported class directly instead instead.
57
+ if (extension === 'cjs') {
58
+ shimmer.wrap(exports, 'Embeddings', Embeddings => {
59
+ return class extends Embeddings {
60
+ constructor (...args) {
61
+ super(...args)
62
+
63
+ const namespace = ['langchain', 'embeddings']
68
64
 
69
- shimmer.wrap(exports, 'Embeddings', Embeddings => {
70
- return class extends Embeddings {
71
- constructor (...args) {
72
- super(...args)
65
+ if (this.constructor.name === 'OpenAIEmbeddings') {
66
+ namespace.push('openai')
67
+ }
73
68
 
69
+ wrap(this, 'embedQuery', 'apm:@langchain/core:Embeddings_embedQuery', namespace)
70
+ wrap(this, 'embedDocuments', 'apm:@langchain/core:Embeddings_embedDocuments', namespace)
71
+ }
72
+ }
73
+ })
74
+ } else {
75
+ const channel = tracingChannel('orchestrion:@langchain/core:Embeddings_constructor')
76
+ channel.subscribe({
77
+ end (ctx) {
78
+ const { self } = ctx
74
79
  const namespace = ['langchain', 'embeddings']
75
80
 
76
- // when originally implemented, we only wrapped OpenAI embeddings
77
- // these embeddings had the resource name of `langchain.embeddings.openai.OpenAIEmbeddings`
78
- // we need to make sure `openai` is appended to the resource name until a new tracer major version
79
- if (this.constructor.name === 'OpenAIEmbeddings') {
81
+ if (self.constructor.name === 'OpenAIEmbeddings') {
80
82
  namespace.push('openai')
81
83
  }
82
84
 
83
- shimmer.wrap(this, 'embedQuery', embedQuery => wrapLangChainPromise(embedQuery, 'embedding', namespace))
84
- shimmer.wrap(this, 'embedDocuments',
85
- embedDocuments => wrapLangChainPromise(embedDocuments, 'embedding', namespace))
85
+ wrap(self, 'embedQuery', 'apm:@langchain/core:Embeddings_embedQuery', namespace)
86
+ wrap(self, 'embedDocuments', 'apm:@langchain/core:Embeddings_embedDocuments', namespace)
86
87
  }
87
-
88
- static [Symbol.hasInstance] (instance) {
89
- return instance instanceof Embeddings
90
- }
91
- }
92
- })
93
-
88
+ })
89
+ }
94
90
  return exports
95
91
  })
96
92
  }
@@ -153,6 +153,18 @@ function wrapPoolMethod (createConnection) {
153
153
  }
154
154
  }
155
155
 
156
+ function wrapPoolGetConnectionMethod (getConnection) {
157
+ return function wrappedGetConnection () {
158
+ const cb = arguments[arguments.length - 1]
159
+ if (typeof cb !== 'function') return getConnection.apply(this, arguments)
160
+
161
+ const callbackResource = new AsyncResource('bound-anonymous-fn')
162
+ arguments[arguments.length - 1] = callbackResource.bind(cb)
163
+
164
+ return getConnection.apply(this, arguments)
165
+ }
166
+ }
167
+
156
168
  const name = 'mariadb'
157
169
 
158
170
  addHook({ name, file: 'lib/cmd/query.js', versions: ['>=3'] }, (Query) => {
@@ -163,6 +175,13 @@ addHook({ name, file: 'lib/cmd/execute.js', versions: ['>=3'] }, (Execute) => {
163
175
  return wrapCommand(Execute)
164
176
  })
165
177
 
178
+ // in 3.4.1 getConnection method start to use callbacks instead of promises
179
+ addHook({ name, file: 'lib/pool.js', versions: ['>=3.4.1'] }, (Pool) => {
180
+ shimmer.wrap(Pool.prototype, 'getConnection', wrapPoolGetConnectionMethod)
181
+
182
+ return Pool
183
+ })
184
+
166
185
  addHook({ name, file: 'lib/pool.js', versions: ['>=3'] }, (Pool) => {
167
186
  shimmer.wrap(Pool.prototype, '_createConnection', wrapPoolMethod)
168
187
 
@@ -417,7 +417,7 @@ addHook({
417
417
 
418
418
  this.on('test end', getOnTestEndHandler(config))
419
419
 
420
- this.on('retry', getOnTestRetryHandler())
420
+ this.on('retry', getOnTestRetryHandler(config))
421
421
 
422
422
  // If the hook passes, 'hook end' will be emitted. Otherwise, 'fail' will be emitted
423
423
  this.on('hook end', getOnHookEndHandler())
@@ -286,6 +286,9 @@ function getOnTestEndHandler (config) {
286
286
  }
287
287
 
288
288
  const isAttemptToFixRetry = test._ddIsAttemptToFix && testStatuses.length > 1
289
+ const isAtrRetry = config.isFlakyTestRetriesEnabled &&
290
+ !test._ddIsAttemptToFix &&
291
+ !test._ddIsEfdRetry
289
292
 
290
293
  // if there are afterEach to be run, we don't finish the test yet
291
294
  if (asyncResource && !getAfterEachHooks(test).length) {
@@ -296,7 +299,8 @@ function getOnTestEndHandler (config) {
296
299
  isLastRetry: getIsLastRetry(test),
297
300
  hasFailedAllRetries,
298
301
  attemptToFixPassed,
299
- isAttemptToFixRetry
302
+ isAttemptToFixRetry,
303
+ isAtrRetry
300
304
  })
301
305
  })
302
306
  }
@@ -364,14 +368,18 @@ function getOnFailHandler (isMain) {
364
368
  }
365
369
  }
366
370
 
367
- function getOnTestRetryHandler () {
371
+ function getOnTestRetryHandler (config) {
368
372
  return function (test, err) {
369
373
  const asyncResource = getTestAsyncResource(test)
370
374
  if (asyncResource) {
371
375
  const isFirstAttempt = test._currentRetry === 0
372
376
  const willBeRetried = test._currentRetry < test._retries
377
+ const isAtrRetry = !isFirstAttempt &&
378
+ config.isFlakyTestRetriesEnabled &&
379
+ !test._ddIsAttemptToFix &&
380
+ !test._ddIsEfdRetry
373
381
  asyncResource.runInAsyncScope(() => {
374
- testRetryCh.publish({ isFirstAttempt, err, willBeRetried, test })
382
+ testRetryCh.publish({ isFirstAttempt, err, willBeRetried, test, isAtrRetry })
375
383
  })
376
384
  }
377
385
  const key = getTestToArKey(test)
@@ -0,0 +1,5 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+
4
+ // TODO this needs to be inlined to prevent issues in bundling
5
+ module.exports = fs.readFileSync(path.join(__dirname, '../../orchestrion.yml'), 'utf8')