dd-trace 5.25.0 → 5.27.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 +2 -0
- package/index.d.ts +17 -8
- package/init.js +60 -47
- package/package.json +5 -2
- package/packages/datadog-core/index.js +1 -3
- package/packages/datadog-core/src/storage.js +21 -0
- package/packages/datadog-instrumentations/src/express.js +1 -1
- package/packages/datadog-instrumentations/src/handlebars.js +40 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -0
- package/packages/datadog-instrumentations/src/jest.js +6 -2
- package/packages/datadog-instrumentations/src/langchain.js +77 -0
- package/packages/datadog-instrumentations/src/next.js +19 -7
- package/packages/datadog-instrumentations/src/pug.js +23 -0
- package/packages/datadog-instrumentations/src/router.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +7 -6
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +34 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +8 -8
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +59 -45
- package/packages/datadog-plugin-cypress/src/support.js +1 -0
- package/packages/datadog-plugin-http/src/client.js +42 -1
- package/packages/datadog-plugin-http2/src/client.js +26 -1
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +50 -0
- package/packages/datadog-plugin-langchain/src/handlers/default.js +53 -0
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +63 -0
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +99 -0
- package/packages/datadog-plugin-langchain/src/handlers/language_models/index.js +48 -0
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +57 -0
- package/packages/datadog-plugin-langchain/src/index.js +89 -0
- package/packages/datadog-plugin-langchain/src/tokens.js +35 -0
- package/packages/datadog-plugin-mocha/src/index.js +1 -1
- package/packages/datadog-plugin-moleculer/src/server.js +0 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +50 -27
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +33 -16
- package/packages/dd-trace/src/appsec/iast/analyzers/template-injection-analyzer.js +18 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +6 -6
- package/packages/dd-trace/src/appsec/recommended.json +353 -155
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +1 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +0 -7
- package/packages/dd-trace/src/appsec/reporter.js +1 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +21 -2
- package/packages/dd-trace/src/config.js +21 -4
- package/packages/dd-trace/src/constants.js +6 -1
- package/packages/dd-trace/src/crashtracking/crashtracker.js +98 -0
- package/packages/dd-trace/src/crashtracking/index.js +15 -0
- package/packages/dd-trace/src/crashtracking/noop.js +8 -0
- package/packages/dd-trace/src/llmobs/sdk.js +1 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/writers/spans/base.js +3 -0
- package/packages/dd-trace/src/log/index.js +10 -13
- package/packages/dd-trace/src/log/log.js +52 -0
- package/packages/dd-trace/src/log/writer.js +50 -19
- package/packages/dd-trace/src/noop/span.js +1 -0
- package/packages/dd-trace/src/opentelemetry/span.js +15 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +35 -22
- package/packages/dd-trace/src/opentracing/span.js +14 -0
- package/packages/dd-trace/src/opentracing/span_context.js +1 -0
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/tracing.js +2 -2
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +121 -0
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +0 -1
- package/packages/dd-trace/src/plugins/util/web.js +39 -11
- package/packages/dd-trace/src/profiling/exporters/agent.js +42 -5
- package/packages/dd-trace/src/profiling/profiler.js +5 -2
- package/packages/dd-trace/src/proxy.js +5 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -11
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -8
- package/packages/dd-trace/src/telemetry/metrics.js +6 -1
- package/packages/dd-trace/src/util.js +16 -1
- package/version.js +4 -2
- /package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/{code-injection-sensitive-analyzer.js → tainted-range-based-sensitive-analyzer.js} +0 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Component,Origin,License,Copyright
|
|
2
|
+
require,@datadog/libdatadog,Apache license 2.0,Copyright 2024 Datadog Inc.
|
|
2
3
|
require,@datadog/native-appsec,Apache license 2.0,Copyright 2018 Datadog Inc.
|
|
3
4
|
require,@datadog/native-metrics,Apache license 2.0,Copyright 2018 Datadog Inc.
|
|
4
5
|
require,@datadog/native-iast-rewriter,Apache license 2.0,Copyright 2018 Datadog Inc.
|
|
@@ -7,6 +8,7 @@ require,@datadog/pprof,Apache license 2.0,Copyright 2019 Google Inc.
|
|
|
7
8
|
require,@datadog/sketches-js,Apache license 2.0,Copyright 2020 Datadog Inc.
|
|
8
9
|
require,@opentelemetry/api,Apache license 2.0,Copyright OpenTelemetry Authors
|
|
9
10
|
require,@opentelemetry/core,Apache license 2.0,Copyright OpenTelemetry Authors
|
|
11
|
+
require,@isaacs/ttlcache,ISC,Copyright (c) 2022-2023 - Isaac Z. Schlueter and Contributors
|
|
10
12
|
require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
|
|
11
13
|
require,dc-polyfill,MIT,Copyright 2023 Datadog Inc.
|
|
12
14
|
require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
|
package/index.d.ts
CHANGED
|
@@ -179,6 +179,7 @@ interface Plugins {
|
|
|
179
179
|
"kafkajs": tracer.plugins.kafkajs
|
|
180
180
|
"knex": tracer.plugins.knex;
|
|
181
181
|
"koa": tracer.plugins.koa;
|
|
182
|
+
"langchain": tracer.plugins.langchain;
|
|
182
183
|
"mariadb": tracer.plugins.mariadb;
|
|
183
184
|
"memcached": tracer.plugins.memcached;
|
|
184
185
|
"microgateway-core": tracer.plugins.microgateway_core;
|
|
@@ -662,19 +663,13 @@ declare namespace tracer {
|
|
|
662
663
|
mode?: 'safe' | 'extended' | 'disabled'
|
|
663
664
|
},
|
|
664
665
|
/**
|
|
665
|
-
* Configuration for Api Security
|
|
666
|
+
* Configuration for Api Security
|
|
666
667
|
*/
|
|
667
668
|
apiSecurity?: {
|
|
668
669
|
/** Whether to enable Api Security.
|
|
669
|
-
* @default
|
|
670
|
+
* @default true
|
|
670
671
|
*/
|
|
671
672
|
enabled?: boolean,
|
|
672
|
-
|
|
673
|
-
/** Controls the request sampling rate (between 0 and 1) in which Api Security is triggered.
|
|
674
|
-
* The value will be coerced back if it's outside of the 0-1 range.
|
|
675
|
-
* @default 0.1
|
|
676
|
-
*/
|
|
677
|
-
requestSampling?: number
|
|
678
673
|
},
|
|
679
674
|
/**
|
|
680
675
|
* Configuration for RASP
|
|
@@ -1043,6 +1038,14 @@ declare namespace tracer {
|
|
|
1043
1038
|
* @default code => code < 500
|
|
1044
1039
|
*/
|
|
1045
1040
|
validateStatus?: (code: number) => boolean;
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Enable injection of tracing headers into requests signed with AWS IAM headers.
|
|
1044
|
+
* Disable this if you get AWS signature errors (HTTP 403).
|
|
1045
|
+
*
|
|
1046
|
+
* @default false
|
|
1047
|
+
*/
|
|
1048
|
+
enablePropagationWithAmazonHeaders?: boolean;
|
|
1046
1049
|
}
|
|
1047
1050
|
|
|
1048
1051
|
/** @hidden */
|
|
@@ -1590,6 +1593,12 @@ declare namespace tracer {
|
|
|
1590
1593
|
*/
|
|
1591
1594
|
interface kafkajs extends Instrumentation {}
|
|
1592
1595
|
|
|
1596
|
+
/**
|
|
1597
|
+
* This plugin automatically instruments the
|
|
1598
|
+
* [langchain](https://js.langchain.com/) module
|
|
1599
|
+
*/
|
|
1600
|
+
interface langchain extends Instrumentation {}
|
|
1601
|
+
|
|
1593
1602
|
/**
|
|
1594
1603
|
* This plugin automatically instruments the
|
|
1595
1604
|
* [ldapjs](https://github.com/ldapjs/node-ldapjs/) module.
|
package/init.js
CHANGED
|
@@ -1,58 +1,71 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const Module = require('module')
|
|
5
|
-
const semver = require('semver')
|
|
6
|
-
const log = require('./packages/dd-trace/src/log')
|
|
7
|
-
const { isTrue } = require('./packages/dd-trace/src/util')
|
|
8
|
-
const telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
|
|
3
|
+
/* eslint-disable no-var */
|
|
9
4
|
|
|
10
|
-
|
|
11
|
-
let clobberBailout = false
|
|
12
|
-
const forced = isTrue(process.env.DD_INJECT_FORCE)
|
|
5
|
+
var NODE_MAJOR = require('./version').NODE_MAJOR
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
7
|
+
// We use several things that are not supported by older versions of Node:
|
|
8
|
+
// - AsyncLocalStorage
|
|
9
|
+
// - The `semver` module
|
|
10
|
+
// - dc-polyfill
|
|
11
|
+
// - Mocha (for testing)
|
|
12
|
+
// and probably others.
|
|
13
|
+
// TODO: Remove all these dependencies so that we can report telemetry.
|
|
14
|
+
if (NODE_MAJOR >= 12) {
|
|
15
|
+
var path = require('path')
|
|
16
|
+
var Module = require('module')
|
|
17
|
+
var semver = require('semver')
|
|
18
|
+
var log = require('./packages/dd-trace/src/log')
|
|
19
|
+
var isTrue = require('./packages/dd-trace/src/util').isTrue
|
|
20
|
+
var telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
|
|
21
|
+
|
|
22
|
+
var initBailout = false
|
|
23
|
+
var clobberBailout = false
|
|
24
|
+
var forced = isTrue(process.env.DD_INJECT_FORCE)
|
|
25
|
+
|
|
26
|
+
if (process.env.DD_INJECTION_ENABLED) {
|
|
27
|
+
// If we're running via single-step install, and we're not in the app's
|
|
28
|
+
// node_modules, then we should not initialize the tracer. This prevents
|
|
29
|
+
// single-step-installed tracer from clobbering the manually-installed tracer.
|
|
30
|
+
var resolvedInApp
|
|
31
|
+
var entrypoint = process.argv[1]
|
|
32
|
+
try {
|
|
33
|
+
resolvedInApp = Module.createRequire(entrypoint).resolve('dd-trace')
|
|
34
|
+
} catch (e) {
|
|
35
|
+
// Ignore. If we can't resolve the module, we assume it's not in the app.
|
|
36
|
+
}
|
|
37
|
+
if (resolvedInApp) {
|
|
38
|
+
var ourselves = path.join(__dirname, 'index.js')
|
|
39
|
+
if (ourselves !== resolvedInApp) {
|
|
40
|
+
clobberBailout = true
|
|
41
|
+
}
|
|
29
42
|
}
|
|
30
|
-
}
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
// If we're running via single-step install, and the runtime doesn't match
|
|
45
|
+
// the engines field in package.json, then we should not initialize the tracer.
|
|
46
|
+
if (!clobberBailout) {
|
|
47
|
+
var engines = require('./package.json').engines
|
|
48
|
+
var version = process.versions.node
|
|
49
|
+
if (!semver.satisfies(version, engines.node)) {
|
|
50
|
+
initBailout = true
|
|
51
|
+
telemetry([
|
|
52
|
+
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
|
|
53
|
+
{ name: 'abort.runtime', tags: [] }
|
|
54
|
+
])
|
|
55
|
+
log.info('Aborting application instrumentation due to incompatible_runtime.')
|
|
56
|
+
log.info('Found incompatible runtime nodejs ' + version + ', Supported runtimes: nodejs ' + engines.node + '.')
|
|
57
|
+
if (forced) {
|
|
58
|
+
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
|
|
59
|
+
}
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
|
-
}
|
|
51
63
|
|
|
52
|
-
if (!clobberBailout && (!initBailout || forced)) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
if (!clobberBailout && (!initBailout || forced)) {
|
|
65
|
+
var tracer = require('.')
|
|
66
|
+
tracer.init()
|
|
67
|
+
module.exports = tracer
|
|
68
|
+
telemetry('complete', ['injection_forced:' + (forced && initBailout ? 'true' : 'false')])
|
|
69
|
+
log.info('Application instrumentation bootstrapping complete')
|
|
70
|
+
}
|
|
58
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.27.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"type:test": "cd docs && yarn && yarn test",
|
|
16
16
|
"lint": "node scripts/check_licenses.js && eslint . && yarn audit",
|
|
17
17
|
"lint-fix": "node scripts/check_licenses.js && eslint . --fix && yarn audit",
|
|
18
|
+
"release:proposal": "node scripts/release/proposal",
|
|
18
19
|
"services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
|
|
19
20
|
"test": "SERVICES=* yarn services && mocha --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
|
|
20
21
|
"test:appsec": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
|
|
@@ -81,12 +82,14 @@
|
|
|
81
82
|
"node": ">=18"
|
|
82
83
|
},
|
|
83
84
|
"dependencies": {
|
|
84
|
-
"@datadog/
|
|
85
|
+
"@datadog/libdatadog": "^0.2.2",
|
|
86
|
+
"@datadog/native-appsec": "8.3.0",
|
|
85
87
|
"@datadog/native-iast-rewriter": "2.5.0",
|
|
86
88
|
"@datadog/native-iast-taint-tracking": "3.2.0",
|
|
87
89
|
"@datadog/native-metrics": "^3.0.1",
|
|
88
90
|
"@datadog/pprof": "5.4.1",
|
|
89
91
|
"@datadog/sketches-js": "^2.1.0",
|
|
92
|
+
"@isaacs/ttlcache": "^1.4.1",
|
|
90
93
|
"@opentelemetry/api": ">=1.0.0 <1.9.0",
|
|
91
94
|
"@opentelemetry/core": "^1.14.0",
|
|
92
95
|
"crypto-randomuuid": "^1.0.0",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AsyncLocalStorage } = require('async_hooks')
|
|
4
|
+
|
|
5
|
+
const storages = Object.create(null)
|
|
6
|
+
const legacyStorage = new AsyncLocalStorage()
|
|
7
|
+
|
|
8
|
+
const storage = function (namespace) {
|
|
9
|
+
if (!storages[namespace]) {
|
|
10
|
+
storages[namespace] = new AsyncLocalStorage()
|
|
11
|
+
}
|
|
12
|
+
return storages[namespace]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
storage.disable = legacyStorage.disable.bind(legacyStorage)
|
|
16
|
+
storage.enterWith = legacyStorage.enterWith.bind(legacyStorage)
|
|
17
|
+
storage.exit = legacyStorage.exit.bind(legacyStorage)
|
|
18
|
+
storage.getStore = legacyStorage.getStore.bind(legacyStorage)
|
|
19
|
+
storage.run = legacyStorage.run.bind(legacyStorage)
|
|
20
|
+
|
|
21
|
+
module.exports = storage
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const handlebarsCompileCh = channel('datadog:handlebars:compile:start')
|
|
7
|
+
const handlebarsRegisterPartialCh = channel('datadog:handlebars:register-partial:start')
|
|
8
|
+
|
|
9
|
+
function wrapCompile (compile) {
|
|
10
|
+
return function wrappedCompile (source) {
|
|
11
|
+
if (handlebarsCompileCh.hasSubscribers) {
|
|
12
|
+
handlebarsCompileCh.publish({ source })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return compile.apply(this, arguments)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function wrapRegisterPartial (registerPartial) {
|
|
20
|
+
return function wrappedRegisterPartial (name, partial) {
|
|
21
|
+
if (handlebarsRegisterPartialCh.hasSubscribers) {
|
|
22
|
+
handlebarsRegisterPartialCh.publish({ partial })
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return registerPartial.apply(this, arguments)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
addHook({ name: 'handlebars', file: 'dist/cjs/handlebars/compiler/compiler.js', versions: ['>=4.0.0'] }, compiler => {
|
|
30
|
+
shimmer.wrap(compiler, 'compile', wrapCompile)
|
|
31
|
+
shimmer.wrap(compiler, 'precompile', wrapCompile)
|
|
32
|
+
|
|
33
|
+
return compiler
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
addHook({ name: 'handlebars', file: 'dist/cjs/handlebars/base.js', versions: ['>=4.0.0'] }, base => {
|
|
37
|
+
shimmer.wrap(base.HandlebarsEnvironment.prototype, 'registerPartial', wrapRegisterPartial)
|
|
38
|
+
|
|
39
|
+
return base
|
|
40
|
+
})
|
|
@@ -19,6 +19,8 @@ module.exports = {
|
|
|
19
19
|
'@jest/test-sequencer': () => require('../jest'),
|
|
20
20
|
'@jest/transform': () => require('../jest'),
|
|
21
21
|
'@koa/router': () => require('../koa'),
|
|
22
|
+
'@langchain/core': () => require('../langchain'),
|
|
23
|
+
'@langchain/openai': () => require('../langchain'),
|
|
22
24
|
'@node-redis/client': () => require('../redis'),
|
|
23
25
|
'@opensearch-project/opensearch': () => require('../opensearch'),
|
|
24
26
|
'@opentelemetry/sdk-trace-node': () => require('../otel-sdk-trace'),
|
|
@@ -51,6 +53,7 @@ module.exports = {
|
|
|
51
53
|
'generic-pool': () => require('../generic-pool'),
|
|
52
54
|
graphql: () => require('../graphql'),
|
|
53
55
|
grpc: () => require('../grpc'),
|
|
56
|
+
handlebars: () => require('../handlebars'),
|
|
54
57
|
hapi: () => require('../hapi'),
|
|
55
58
|
http: () => require('../http'),
|
|
56
59
|
http2: () => require('../http2'),
|
|
@@ -66,6 +69,7 @@ module.exports = {
|
|
|
66
69
|
koa: () => require('../koa'),
|
|
67
70
|
'koa-router': () => require('../koa'),
|
|
68
71
|
kafkajs: () => require('../kafkajs'),
|
|
72
|
+
langchain: () => require('../langchain'),
|
|
69
73
|
ldapjs: () => require('../ldapjs'),
|
|
70
74
|
'limitd-client': () => require('../limitd-client'),
|
|
71
75
|
lodash: () => require('../lodash'),
|
|
@@ -105,6 +109,7 @@ module.exports = {
|
|
|
105
109
|
'promise-js': () => require('../promise-js'),
|
|
106
110
|
promise: () => require('../promise'),
|
|
107
111
|
protobufjs: () => require('../protobufjs'),
|
|
112
|
+
pug: () => require('../pug'),
|
|
108
113
|
q: () => require('../q'),
|
|
109
114
|
qs: () => require('../qs'),
|
|
110
115
|
redis: () => require('../redis'),
|
|
@@ -127,6 +127,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
127
127
|
|
|
128
128
|
if (repositoryRoot) {
|
|
129
129
|
this.testSourceFile = getTestSuitePath(context.testPath, repositoryRoot)
|
|
130
|
+
this.repositoryRoot = repositoryRoot
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
this.isEarlyFlakeDetectionEnabled = this.testEnvironmentOptions._ddIsEarlyFlakeDetectionEnabled
|
|
@@ -667,10 +668,13 @@ function jestAdapterWrapper (jestAdapter, jestVersion) {
|
|
|
667
668
|
* controls whether coverage is reported.
|
|
668
669
|
*/
|
|
669
670
|
if (environment.testEnvironmentOptions?._ddTestCodeCoverageEnabled) {
|
|
671
|
+
const root = environment.repositoryRoot || environment.rootDir
|
|
672
|
+
|
|
670
673
|
const coverageFiles = getCoveredFilenamesFromCoverage(environment.global.__coverage__)
|
|
671
|
-
.map(filename => getTestSuitePath(filename,
|
|
674
|
+
.map(filename => getTestSuitePath(filename, root))
|
|
675
|
+
|
|
672
676
|
asyncResource.runInAsyncScope(() => {
|
|
673
|
-
testSuiteCodeCoverageCh.publish({ coverageFiles, testSuite: environment.
|
|
677
|
+
testSuiteCodeCoverageCh.publish({ coverageFiles, testSuite: environment.testSourceFile })
|
|
674
678
|
})
|
|
675
679
|
}
|
|
676
680
|
testSuiteFinishCh.publish({ status, errorMessage })
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
const tracingChannel = require('dc-polyfill').tracingChannel
|
|
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
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return invokeTracingChannel.tracePromise(fn, ctx, this, ...arguments)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// langchain compiles into ESM and CommonJS, with ESM being the default and landing in the `.js` files
|
|
32
|
+
// however, CommonJS ends up in `cjs` files, and are required under the hood with `.cjs` files
|
|
33
|
+
// we patch each separately and explicitly to match against exports only once, and not rely on file regex matching
|
|
34
|
+
const extensions = ['js', 'cjs']
|
|
35
|
+
|
|
36
|
+
for (const extension of extensions) {
|
|
37
|
+
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'))
|
|
41
|
+
return exports
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
addHook({
|
|
45
|
+
name: '@langchain/core',
|
|
46
|
+
file: `dist/language_models/chat_models.${extension}`,
|
|
47
|
+
versions: ['>=0.1']
|
|
48
|
+
}, exports => {
|
|
49
|
+
const BaseChatModel = exports.BaseChatModel
|
|
50
|
+
shimmer.wrap(
|
|
51
|
+
BaseChatModel.prototype,
|
|
52
|
+
'generate',
|
|
53
|
+
generate => wrapLangChainPromise(generate, 'chat_model')
|
|
54
|
+
)
|
|
55
|
+
return exports
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
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'))
|
|
61
|
+
return exports
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
addHook({ name: '@langchain/openai', file: `dist/embeddings.${extension}`, versions: ['>=0.1'] }, exports => {
|
|
65
|
+
const OpenAIEmbeddings = exports.OpenAIEmbeddings
|
|
66
|
+
|
|
67
|
+
// OpenAI (and Embeddings in general) do not define an lc_namespace
|
|
68
|
+
const namespace = ['langchain', 'embeddings', 'openai']
|
|
69
|
+
shimmer.wrap(OpenAIEmbeddings.prototype, 'embedDocuments', embedDocuments =>
|
|
70
|
+
wrapLangChainPromise(embedDocuments, 'embedding', namespace)
|
|
71
|
+
)
|
|
72
|
+
shimmer.wrap(OpenAIEmbeddings.prototype, 'embedQuery', embedQuery =>
|
|
73
|
+
wrapLangChainPromise(embedQuery, 'embedding', namespace)
|
|
74
|
+
)
|
|
75
|
+
return exports
|
|
76
|
+
})
|
|
77
|
+
}
|
|
@@ -14,8 +14,14 @@ const queryParsedChannel = channel('apm:next:query-parsed')
|
|
|
14
14
|
const requests = new WeakSet()
|
|
15
15
|
const nodeNextRequestsToNextRequests = new WeakMap()
|
|
16
16
|
|
|
17
|
+
// Next.js <= 14.2.6
|
|
17
18
|
const MIDDLEWARE_HEADER = 'x-middleware-invoke'
|
|
18
19
|
|
|
20
|
+
// Next.js >= 14.2.7
|
|
21
|
+
const NEXT_REQUEST_META = Symbol.for('NextInternalRequestMeta')
|
|
22
|
+
const META_IS_MIDDLEWARE = 'middlewareInvoke'
|
|
23
|
+
const encounteredMiddleware = new WeakSet()
|
|
24
|
+
|
|
19
25
|
function wrapHandleRequest (handleRequest) {
|
|
20
26
|
return function (req, res, pathname, query) {
|
|
21
27
|
return instrument(req, res, () => handleRequest.apply(this, arguments))
|
|
@@ -111,6 +117,11 @@ function getPageFromPath (page, dynamicRoutes = []) {
|
|
|
111
117
|
return getPagePath(page)
|
|
112
118
|
}
|
|
113
119
|
|
|
120
|
+
function getRequestMeta (req, key) {
|
|
121
|
+
const meta = req[NEXT_REQUEST_META] || {}
|
|
122
|
+
return typeof key === 'string' ? meta[key] : meta
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
function instrument (req, res, error, handler) {
|
|
115
126
|
if (typeof error === 'function') {
|
|
116
127
|
handler = error
|
|
@@ -121,8 +132,9 @@ function instrument (req, res, error, handler) {
|
|
|
121
132
|
res = res.originalResponse || res
|
|
122
133
|
|
|
123
134
|
// TODO support middleware properly in the future?
|
|
124
|
-
const isMiddleware = req.headers[MIDDLEWARE_HEADER]
|
|
125
|
-
if (isMiddleware || requests.has(req)) {
|
|
135
|
+
const isMiddleware = req.headers[MIDDLEWARE_HEADER] || getRequestMeta(req, META_IS_MIDDLEWARE)
|
|
136
|
+
if ((isMiddleware && !encounteredMiddleware.has(req)) || requests.has(req)) {
|
|
137
|
+
encounteredMiddleware.add(req)
|
|
126
138
|
if (error) {
|
|
127
139
|
errorChannel.publish({ error })
|
|
128
140
|
}
|
|
@@ -188,7 +200,7 @@ function finish (ctx, result, err) {
|
|
|
188
200
|
// however, it is not provided as a class function or exported property
|
|
189
201
|
addHook({
|
|
190
202
|
name: 'next',
|
|
191
|
-
versions: ['>=13.3.0 <
|
|
203
|
+
versions: ['>=13.3.0 <15'],
|
|
192
204
|
file: 'dist/server/web/spec-extension/adapters/next-request.js'
|
|
193
205
|
}, NextRequestAdapter => {
|
|
194
206
|
shimmer.wrap(NextRequestAdapter.NextRequestAdapter, 'fromNodeNextRequest', fromNodeNextRequest => {
|
|
@@ -203,7 +215,7 @@ addHook({
|
|
|
203
215
|
|
|
204
216
|
addHook({
|
|
205
217
|
name: 'next',
|
|
206
|
-
versions: ['>=11.1 <
|
|
218
|
+
versions: ['>=11.1 <15'],
|
|
207
219
|
file: 'dist/server/serve-static.js'
|
|
208
220
|
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
209
221
|
|
|
@@ -213,7 +225,7 @@ addHook({
|
|
|
213
225
|
file: 'dist/next-server/server/serve-static.js'
|
|
214
226
|
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
215
227
|
|
|
216
|
-
addHook({ name: 'next', versions: ['>=11.1 <
|
|
228
|
+
addHook({ name: 'next', versions: ['>=11.1 <15'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
217
229
|
const Server = nextServer.default
|
|
218
230
|
|
|
219
231
|
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
@@ -230,7 +242,7 @@ addHook({ name: 'next', versions: ['>=11.1 <14.2.7'], file: 'dist/server/next-se
|
|
|
230
242
|
})
|
|
231
243
|
|
|
232
244
|
// `handleApiRequest` changes parameters/implementation at 13.2.0
|
|
233
|
-
addHook({ name: 'next', versions: ['>=13.2 <
|
|
245
|
+
addHook({ name: 'next', versions: ['>=13.2 <15'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
234
246
|
const Server = nextServer.default
|
|
235
247
|
shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
|
|
236
248
|
return nextServer
|
|
@@ -264,7 +276,7 @@ addHook({
|
|
|
264
276
|
|
|
265
277
|
addHook({
|
|
266
278
|
name: 'next',
|
|
267
|
-
versions: ['>=13 <
|
|
279
|
+
versions: ['>=13 <15'],
|
|
268
280
|
file: 'dist/server/web/spec-extension/request.js'
|
|
269
281
|
}, request => {
|
|
270
282
|
const nextUrlDescriptor = Object.getOwnPropertyDescriptor(request.NextRequest.prototype, 'nextUrl')
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const pugCompileCh = channel('datadog:pug:compile:start')
|
|
7
|
+
|
|
8
|
+
function wrapCompile (compile) {
|
|
9
|
+
return function wrappedCompile (source) {
|
|
10
|
+
if (pugCompileCh.hasSubscribers) {
|
|
11
|
+
pugCompileCh.publish({ source })
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return compile.apply(this, arguments)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
addHook({ name: 'pug', versions: ['>=2.0.4'] }, compiler => {
|
|
19
|
+
shimmer.wrap(compiler, 'compile', wrapCompile)
|
|
20
|
+
shimmer.wrap(compiler, 'compileClientWithDependenciesTracked', wrapCompile)
|
|
21
|
+
|
|
22
|
+
return compiler
|
|
23
|
+
})
|
|
@@ -112,7 +112,6 @@ function createWrapRouterMethod (name) {
|
|
|
112
112
|
path: pattern instanceof RegExp ? `(${pattern})` : pattern,
|
|
113
113
|
test: layer => {
|
|
114
114
|
const matchers = layerMatchers.get(layer)
|
|
115
|
-
|
|
116
115
|
return !isFastStar(layer, matchers) &&
|
|
117
116
|
!isFastSlash(layer, matchers) &&
|
|
118
117
|
cachedPathToRegExp(pattern).test(layer.path)
|
|
@@ -121,7 +120,7 @@ function createWrapRouterMethod (name) {
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
function isFastStar (layer, matchers) {
|
|
124
|
-
if (layer.regexp
|
|
123
|
+
if (layer.regexp?.fast_star !== undefined) {
|
|
125
124
|
return layer.regexp.fast_star
|
|
126
125
|
}
|
|
127
126
|
|
|
@@ -129,7 +128,7 @@ function createWrapRouterMethod (name) {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
function isFastSlash (layer, matchers) {
|
|
132
|
-
if (layer.regexp
|
|
131
|
+
if (layer.regexp?.fast_slash !== undefined) {
|
|
133
132
|
return layer.regexp.fast_slash
|
|
134
133
|
}
|
|
135
134
|
|
|
@@ -93,6 +93,7 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
93
93
|
this.responseExtractDSMContext(operation, params, response.data ?? response, span)
|
|
94
94
|
}
|
|
95
95
|
this.addResponseTags(span, response)
|
|
96
|
+
this.addSpanPointers(span, response)
|
|
96
97
|
this.finish(span, response, response.error)
|
|
97
98
|
})
|
|
98
99
|
}
|
|
@@ -101,6 +102,10 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
101
102
|
// implemented by subclasses, or not
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
addSpanPointers (span, response) {
|
|
106
|
+
// Optionally implemented by subclasses, for services where we're unable to inject trace context
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
operationFromRequest (request) {
|
|
105
110
|
// can be overriden by subclasses
|
|
106
111
|
return this.operationName({
|
|
@@ -113,14 +113,15 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
113
113
|
response.Records.forEach(record => {
|
|
114
114
|
const parsedAttributes = JSON.parse(Buffer.from(record.Data).toString())
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
) {
|
|
119
|
-
const payloadSize = getSizeOrZero(record.Data)
|
|
116
|
+
const payloadSize = getSizeOrZero(record.Data)
|
|
117
|
+
if (parsedAttributes?._datadog) {
|
|
120
118
|
this.tracer.decodeDataStreamsContext(parsedAttributes._datadog)
|
|
121
|
-
this.tracer
|
|
122
|
-
.setCheckpoint(['direction:in', `topic:${streamName}`, 'type:kinesis'], span, payloadSize)
|
|
123
119
|
}
|
|
120
|
+
const tags = streamName
|
|
121
|
+
? ['direction:in', `topic:${streamName}`, 'type:kinesis']
|
|
122
|
+
: ['direction:in', 'type:kinesis']
|
|
123
|
+
this.tracer
|
|
124
|
+
.setCheckpoint(tags, span, payloadSize)
|
|
124
125
|
})
|
|
125
126
|
}
|
|
126
127
|
|