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.
- package/LICENSE-3rdparty.csv +1 -2
- package/ci/init.js +8 -0
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/package.json +8 -9
- package/packages/datadog-instrumentations/orchestrion.yml +52 -0
- package/packages/datadog-instrumentations/src/cucumber.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +41 -1
- package/packages/datadog-instrumentations/src/jest.js +11 -2
- package/packages/datadog-instrumentations/src/langchain.js +49 -53
- package/packages/datadog-instrumentations/src/mariadb.js +19 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +11 -3
- package/packages/datadog-instrumentations/src/orchestrion-config/index.js +5 -0
- package/packages/datadog-instrumentations/src/playwright.js +333 -46
- package/packages/datadog-instrumentations/src/router.js +1 -7
- package/packages/datadog-instrumentations/src/vitest.js +11 -3
- package/packages/datadog-plugin-cucumber/src/index.js +11 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +17 -5
- package/packages/datadog-plugin-jest/src/index.js +11 -4
- package/packages/datadog-plugin-langchain/src/index.js +18 -12
- package/packages/datadog-plugin-langchain/src/tracing.js +66 -6
- package/packages/datadog-plugin-mocha/src/index.js +17 -5
- package/packages/datadog-plugin-mongodb-core/src/index.js +24 -0
- package/packages/datadog-plugin-playwright/src/index.js +124 -10
- package/packages/datadog-plugin-vitest/src/index.js +13 -8
- package/packages/datadog-shimmer/src/shimmer.js +3 -42
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +39 -15
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +0 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +25 -12
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +3 -32
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +99 -57
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +4 -2
- package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/utils.js +12 -7
- package/packages/dd-trace/src/appsec/recommended.json +256 -84
- package/packages/dd-trace/src/appsec/reporter.js +6 -4
- package/packages/dd-trace/src/appsec/telemetry/index.js +27 -3
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +70 -6
- package/packages/dd-trace/src/appsec/telemetry/waf.js +0 -30
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +8 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +6 -4
- package/packages/dd-trace/src/config.js +9 -0
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +102 -22
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +263 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +69 -36
- package/packages/dd-trace/src/debugger/devtools_client/lock.js +8 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +1 -7
- package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +15 -10
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +69 -62
- package/packages/dd-trace/src/debugger/devtools_client/state.js +3 -2
- package/packages/dd-trace/src/debugger/index.js +3 -0
- package/packages/dd-trace/src/encode/0.4.js +24 -17
- package/packages/dd-trace/src/exporter.js +1 -0
- package/packages/dd-trace/src/exporters/common/docker.js +37 -7
- package/packages/dd-trace/src/exporters/common/request.js +1 -4
- package/packages/dd-trace/src/format.js +58 -60
- package/packages/dd-trace/src/llmobs/plugins/base.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +62 -3
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -0
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +2 -1
- package/packages/dd-trace/src/llmobs/writers/spans/base.js +3 -3
- package/packages/dd-trace/src/log/index.js +2 -0
- package/packages/dd-trace/src/log/writer.js +19 -2
- package/packages/dd-trace/src/opentelemetry/span.js +4 -4
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -3
- package/packages/dd-trace/src/opentracing/span.js +10 -0
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +11 -0
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/config.js +6 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -5
- package/packages/dd-trace/src/profiling/profiler.js +4 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +12 -8
- package/packages/dd-trace/src/proxy.js +5 -1
- package/packages/dd-trace/src/tagger.js +38 -26
- package/packages/dd-trace/src/util.js +1 -7
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -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)
|
package/ext/exporters.d.ts
CHANGED
package/ext/exporters.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
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.
|
|
88
|
-
"@datadog/native-appsec": "8.5.
|
|
89
|
-
"@datadog/native-iast-
|
|
90
|
-
"@datadog/native-
|
|
91
|
-
"@datadog/
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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)
|