dd-trace 5.60.0 → 5.61.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/index.d.ts +6 -0
- package/package.json +5 -8
- package/packages/datadog-code-origin/index.js +3 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +5 -0
- package/packages/datadog-instrumentations/src/azure-service-bus.js +38 -0
- package/packages/datadog-instrumentations/src/fastify.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/next.js +17 -18
- package/packages/datadog-instrumentations/src/sequelize.js +4 -14
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +6 -38
- package/packages/datadog-plugin-azure-functions/src/index.js +57 -28
- package/packages/datadog-plugin-azure-service-bus/src/index.js +15 -0
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +36 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +24 -23
- package/packages/datadog-plugin-langchain/src/handlers/default.js +0 -18
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +0 -48
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +18 -0
- package/packages/datadog-plugin-langchain/src/tracing.js +5 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +8 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +11 -10
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +25 -18
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +5 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +2 -2
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -0
- package/packages/dd-trace/src/appsec/iast/index.js +25 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +79 -21
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +0 -4
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +4 -8
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +8 -0
- package/packages/dd-trace/src/plugins/util/git.js +50 -15
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +4 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -4
- package/packages/dd-trace/src/remote_config/scheduler.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
- package/packages/dd-trace/src/supported-configurations.json +1 -0
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +0 -50
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +0 -101
- package/packages/datadog-plugin-langchain/src/handlers/language_models/index.js +0 -48
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +0 -58
package/index.d.ts
CHANGED
|
@@ -167,6 +167,7 @@ interface Plugins {
|
|
|
167
167
|
"avsc": tracer.plugins.avsc;
|
|
168
168
|
"aws-sdk": tracer.plugins.aws_sdk;
|
|
169
169
|
"azure-functions": tracer.plugins.azure_functions;
|
|
170
|
+
"azure-service-bus": tracer.plugins.azure_service_bus;
|
|
170
171
|
"bunyan": tracer.plugins.bunyan;
|
|
171
172
|
"cassandra-driver": tracer.plugins.cassandra_driver;
|
|
172
173
|
"child_process": tracer.plugins.child_process;
|
|
@@ -1381,6 +1382,11 @@ declare namespace tracer {
|
|
|
1381
1382
|
*/
|
|
1382
1383
|
interface azure_functions extends Instrumentation {}
|
|
1383
1384
|
|
|
1385
|
+
/**
|
|
1386
|
+
* This plugin automatically instruments the
|
|
1387
|
+
* @azure/service-bus module
|
|
1388
|
+
*/
|
|
1389
|
+
interface azure_service_bus extends Integration {}
|
|
1384
1390
|
/**
|
|
1385
1391
|
* This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
|
|
1386
1392
|
* to automatically inject trace identifiers in log records when the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.61.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"@opentelemetry/api": "1.8.0",
|
|
125
125
|
"@opentelemetry/core": "^1.14.0",
|
|
126
126
|
"crypto-randomuuid": "^1.0.0",
|
|
127
|
-
"dc-polyfill": "^0.1.
|
|
127
|
+
"dc-polyfill": "^0.1.10",
|
|
128
128
|
"ignore": "^7.0.5",
|
|
129
129
|
"import-in-the-middle": "^1.14.2",
|
|
130
130
|
"istanbul-lib-coverage": "^3.2.2",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"@msgpack/msgpack": "^3.1.2",
|
|
156
156
|
"@stylistic/eslint-plugin": "^5.0.0",
|
|
157
157
|
"@types/node": "^18.19.106",
|
|
158
|
-
"axios": "^1.
|
|
158
|
+
"axios": "^1.11.0",
|
|
159
159
|
"benchmark": "^2.1.4",
|
|
160
160
|
"body-parser": "^2.2.0",
|
|
161
161
|
"chai": "^4.5.0",
|
|
@@ -165,11 +165,11 @@
|
|
|
165
165
|
"eslint-plugin-mocha": "^10.5.0",
|
|
166
166
|
"eslint-plugin-n": "^17.20.0",
|
|
167
167
|
"eslint-plugin-promise": "^7.2.1",
|
|
168
|
-
"eslint-plugin-unicorn": "^
|
|
168
|
+
"eslint-plugin-unicorn": "^60.0.0",
|
|
169
169
|
"express": "^5.1.0",
|
|
170
170
|
"get-port": "^5.1.1",
|
|
171
171
|
"glob": "^7.2.3",
|
|
172
|
-
"globals": "^
|
|
172
|
+
"globals": "^16.3.0",
|
|
173
173
|
"graphql": "*",
|
|
174
174
|
"jszip": "^3.10.1",
|
|
175
175
|
"mocha": "^11.6.0",
|
|
@@ -187,8 +187,5 @@
|
|
|
187
187
|
"workerpool": "^9.2.0",
|
|
188
188
|
"yaml": "^2.8.0",
|
|
189
189
|
"yarn-deduplicate": "^6.0.2"
|
|
190
|
-
},
|
|
191
|
-
"resolutions": {
|
|
192
|
-
"eslint-plugin-unicorn/@eslint/plugin-kit": "0.3.3"
|
|
193
190
|
}
|
|
194
191
|
}
|
|
@@ -38,9 +38,12 @@ function exitTags (topOfStackFunc) {
|
|
|
38
38
|
function tag (type, topOfStackFunc, limit) {
|
|
39
39
|
// The `Error.prepareStackTrace` API doesn't support resolving source maps.
|
|
40
40
|
// Fall back to manually parsing the stack trace.
|
|
41
|
+
const originalLimit = Error.stackTraceLimit
|
|
42
|
+
Error.stackTraceLimit = Infinity
|
|
41
43
|
const dummy = {}
|
|
42
44
|
Error.captureStackTrace(dummy, topOfStackFunc)
|
|
43
45
|
const frames = parseUserLandFrames(dummy.stack, limit)
|
|
46
|
+
Error.stackTraceLimit = originalLimit
|
|
44
47
|
|
|
45
48
|
const tags = {
|
|
46
49
|
'_dd.code_origin.type': type
|
|
@@ -11,6 +11,7 @@ const azureFunctionsChannel = dc.tracingChannel('datadog:azure:functions:invoke'
|
|
|
11
11
|
addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
|
|
12
12
|
const { app } = azureFunction
|
|
13
13
|
|
|
14
|
+
// Http triggers
|
|
14
15
|
shimmer.wrap(app, 'deleteRequest', wrapHandler)
|
|
15
16
|
shimmer.wrap(app, 'http', wrapHandler)
|
|
16
17
|
shimmer.wrap(app, 'get', wrapHandler)
|
|
@@ -18,6 +19,10 @@ addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
|
|
|
18
19
|
shimmer.wrap(app, 'post', wrapHandler)
|
|
19
20
|
shimmer.wrap(app, 'put', wrapHandler)
|
|
20
21
|
|
|
22
|
+
// Service Bus triggers
|
|
23
|
+
shimmer.wrap(app, 'serviceBusQueue', wrapHandler)
|
|
24
|
+
shimmer.wrap(app, 'serviceBusTopic', wrapHandler)
|
|
25
|
+
|
|
21
26
|
return azureFunction
|
|
22
27
|
})
|
|
23
28
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const producerStartCh = channel('apm:azure-service-bus:send:start')
|
|
11
|
+
const producerErrorCh = channel('apm:azure-service-bus:send:error')
|
|
12
|
+
const producerFinishCh = channel('apm:azure-service-bus:send:finish')
|
|
13
|
+
|
|
14
|
+
addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'] }, (obj) => {
|
|
15
|
+
const ServiceBusClient = obj.ServiceBusClient
|
|
16
|
+
shimmer.wrap(ServiceBusClient.prototype, 'createSender', createSender => function (queueOrTopicName) {
|
|
17
|
+
const sender = createSender.apply(this, arguments)
|
|
18
|
+
shimmer.wrap(sender._sender, 'send', send => function (msg) {
|
|
19
|
+
const ctx = { sender, msg }
|
|
20
|
+
return producerStartCh.runStores(ctx, () => {
|
|
21
|
+
return send.apply(this, arguments)
|
|
22
|
+
.then(
|
|
23
|
+
response => {
|
|
24
|
+
producerFinishCh.publish(ctx)
|
|
25
|
+
},
|
|
26
|
+
error => {
|
|
27
|
+
ctx.error = error
|
|
28
|
+
producerErrorCh.publish(ctx)
|
|
29
|
+
producerFinishCh.publish(ctx)
|
|
30
|
+
throw error
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
return sender
|
|
36
|
+
})
|
|
37
|
+
return obj
|
|
38
|
+
})
|
|
@@ -11,6 +11,7 @@ const queryParamsReadCh = channel('datadog:fastify:query-params:finish')
|
|
|
11
11
|
const cookieParserReadCh = channel('datadog:fastify-cookie:read:finish')
|
|
12
12
|
const responsePayloadReadCh = channel('datadog:fastify:response:finish')
|
|
13
13
|
const pathParamsReadCh = channel('datadog:fastify:path-params:finish')
|
|
14
|
+
const finishSetHeaderCh = channel('datadog:fastify:set-header:finish')
|
|
14
15
|
|
|
15
16
|
const parsingResources = new WeakMap()
|
|
16
17
|
const cookiesPublished = new WeakSet()
|
|
@@ -275,3 +276,19 @@ addHook({ name: 'fastify', versions: ['2'] }, fastify => {
|
|
|
275
276
|
addHook({ name: 'fastify', versions: ['1'] }, fastify => {
|
|
276
277
|
return shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, false))
|
|
277
278
|
})
|
|
279
|
+
|
|
280
|
+
function wrapReplyHeader (Reply) {
|
|
281
|
+
shimmer.wrap(Reply.prototype, 'header', header => function (key, value) {
|
|
282
|
+
const result = header.apply(this, arguments)
|
|
283
|
+
|
|
284
|
+
if (finishSetHeaderCh.hasSubscribers && key && value) {
|
|
285
|
+
finishSetHeaderCh.publish({ name: key, value, res: getRes(this) })
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return result
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
return Reply
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
addHook({ name: 'fastify', file: 'lib/reply.js', versions: ['1', '2', '>=3'] }, wrapReplyHeader)
|
|
@@ -6,6 +6,7 @@ module.exports = {
|
|
|
6
6
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
7
7
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
8
8
|
'@azure/functions': () => require('../azure-functions'),
|
|
9
|
+
'@azure/service-bus': () => require('../azure-service-bus'),
|
|
9
10
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
10
11
|
'@playwright/test': () => require('../playwright'),
|
|
11
12
|
'@elastic/elasticsearch': () => require('../elasticsearch'),
|
|
@@ -141,6 +141,20 @@ function instrument (req, res, handler, error) {
|
|
|
141
141
|
requests.add(req)
|
|
142
142
|
|
|
143
143
|
const ctx = { req, res }
|
|
144
|
+
// Parse query parameters from request URL
|
|
145
|
+
if (queryParsedChannel.hasSubscribers && req.url) {
|
|
146
|
+
// req.url is only the relative path (/foo?bar=baz) and new URL() needs a full URL
|
|
147
|
+
// so we give it a dummy base
|
|
148
|
+
const { searchParams } = new URL(req.url, 'http://dummy')
|
|
149
|
+
const query = {}
|
|
150
|
+
for (const key of searchParams.keys()) {
|
|
151
|
+
if (!query[key]) {
|
|
152
|
+
query[key] = searchParams.getAll(key)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
queryParsedChannel.publish({ query })
|
|
157
|
+
}
|
|
144
158
|
|
|
145
159
|
return startChannel.runStores(ctx, () => {
|
|
146
160
|
try {
|
|
@@ -280,24 +294,9 @@ addHook({
|
|
|
280
294
|
versions: ['>=13'],
|
|
281
295
|
file: 'dist/server/web/spec-extension/request.js'
|
|
282
296
|
}, request => {
|
|
283
|
-
|
|
284
|
-
return function wrappedGet () {
|
|
285
|
-
const nextUrl = originalGet.apply(this, arguments)
|
|
286
|
-
if (queryParsedChannel.hasSubscribers) {
|
|
287
|
-
const query = {}
|
|
288
|
-
for (const key of nextUrl.searchParams.keys()) {
|
|
289
|
-
if (!query[key]) {
|
|
290
|
-
query[key] = nextUrl.searchParams.getAll(key)
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
queryParsedChannel.publish({ query })
|
|
295
|
-
}
|
|
296
|
-
return nextUrl
|
|
297
|
-
}
|
|
298
|
-
})
|
|
297
|
+
const requestProto = Object.getPrototypeOf(request.NextRequest.prototype)
|
|
299
298
|
|
|
300
|
-
shimmer.massWrap(
|
|
299
|
+
shimmer.massWrap(requestProto, ['text', 'json'], function (originalMethod) {
|
|
301
300
|
return async function wrappedJson () {
|
|
302
301
|
const body = await originalMethod.apply(this, arguments)
|
|
303
302
|
|
|
@@ -307,7 +306,7 @@ addHook({
|
|
|
307
306
|
}
|
|
308
307
|
})
|
|
309
308
|
|
|
310
|
-
shimmer.wrap(
|
|
309
|
+
shimmer.wrap(requestProto, 'formData', function (originalFormData) {
|
|
311
310
|
return async function wrappedFormData () {
|
|
312
311
|
const body = await originalFormData.apply(this, arguments)
|
|
313
312
|
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const {
|
|
4
4
|
channel,
|
|
5
|
-
addHook
|
|
6
|
-
AsyncResource
|
|
5
|
+
addHook
|
|
7
6
|
} = require('./helpers/instrument')
|
|
8
7
|
|
|
9
8
|
const shimmer = require('../../datadog-shimmer')
|
|
@@ -18,8 +17,6 @@ addHook({ name: 'sequelize', versions: ['>=4'] }, Sequelize => {
|
|
|
18
17
|
return query.apply(this, arguments)
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
22
|
-
|
|
23
20
|
let dialect
|
|
24
21
|
if (this.options && this.options.dialect) {
|
|
25
22
|
dialect = this.options.dialect
|
|
@@ -33,22 +30,15 @@ addHook({ name: 'sequelize', versions: ['>=4'] }, Sequelize => {
|
|
|
33
30
|
result = result[0]
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
finishCh.publish({ result })
|
|
38
|
-
}, this).apply(this)
|
|
33
|
+
finishCh.runStores({ result }, () => {})
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
return
|
|
42
|
-
startCh.publish({
|
|
43
|
-
sql,
|
|
44
|
-
dialect
|
|
45
|
-
})
|
|
46
|
-
|
|
36
|
+
return startCh.runStores({ sql, dialect }, () => {
|
|
47
37
|
const promise = query.apply(this, arguments)
|
|
48
38
|
promise.then(onFinish, () => { onFinish() })
|
|
49
39
|
|
|
50
40
|
return promise
|
|
51
|
-
}
|
|
41
|
+
})
|
|
52
42
|
}
|
|
53
43
|
})
|
|
54
44
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const BaseAwsSdkPlugin = require('../../base')
|
|
4
|
-
const { parseModelId
|
|
4
|
+
const { parseModelId } = require('./utils')
|
|
5
5
|
|
|
6
6
|
const enabledOperations = new Set(['invokeModel'])
|
|
7
7
|
|
|
@@ -20,44 +20,12 @@ class BedrockRuntime extends BaseAwsSdkPlugin {
|
|
|
20
20
|
generateTags (params, operation, response) {
|
|
21
21
|
const { modelProvider, modelName } = parseModelId(params.modelId)
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return tags
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function buildTagsFromParams (requestParams, textAndResponseReason, modelProvider, modelName, operation) {
|
|
33
|
-
const tags = {}
|
|
34
|
-
|
|
35
|
-
// add request tags
|
|
36
|
-
tags['resource.name'] = operation
|
|
37
|
-
tags['aws.bedrock.request.model'] = modelName
|
|
38
|
-
tags['aws.bedrock.request.model_provider'] = modelProvider.toLowerCase()
|
|
39
|
-
tags['aws.bedrock.request.prompt'] = requestParams.prompt
|
|
40
|
-
tags['aws.bedrock.request.temperature'] = requestParams.temperature
|
|
41
|
-
tags['aws.bedrock.request.top_p'] = requestParams.topP
|
|
42
|
-
tags['aws.bedrock.request.top_k'] = requestParams.topK
|
|
43
|
-
tags['aws.bedrock.request.max_tokens'] = requestParams.maxTokens
|
|
44
|
-
tags['aws.bedrock.request.stop_sequences'] = requestParams.stopSequences
|
|
45
|
-
tags['aws.bedrock.request.input_type'] = requestParams.inputType
|
|
46
|
-
tags['aws.bedrock.request.truncate'] = requestParams.truncate
|
|
47
|
-
tags['aws.bedrock.request.stream'] = requestParams.stream
|
|
48
|
-
tags['aws.bedrock.request.n'] = requestParams.n
|
|
49
|
-
|
|
50
|
-
// add response tags
|
|
51
|
-
if (modelName.includes('embed')) {
|
|
52
|
-
tags['aws.bedrock.response.embedding_length'] = textAndResponseReason.message.length
|
|
53
|
-
}
|
|
54
|
-
if (textAndResponseReason.choiceId) {
|
|
55
|
-
tags['aws.bedrock.response.choices.id'] = textAndResponseReason.choiceId
|
|
23
|
+
return {
|
|
24
|
+
'resource.name': operation,
|
|
25
|
+
'aws.bedrock.request.model': modelName,
|
|
26
|
+
'aws.bedrock.request.model_provider': modelProvider.toLowerCase()
|
|
27
|
+
}
|
|
56
28
|
}
|
|
57
|
-
tags['aws.bedrock.response.choices.text'] = textAndResponseReason.message
|
|
58
|
-
tags['aws.bedrock.response.choices.finish_reason'] = textAndResponseReason.finishReason
|
|
59
|
-
|
|
60
|
-
return tags
|
|
61
29
|
}
|
|
62
30
|
|
|
63
31
|
module.exports = BedrockRuntime
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
|
-
const { storage } = require('../../datadog-core')
|
|
5
4
|
const serverless = require('../../dd-trace/src/plugins/util/serverless')
|
|
6
5
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
7
6
|
|
|
@@ -11,7 +10,9 @@ const triggerMap = {
|
|
|
11
10
|
get: 'Http',
|
|
12
11
|
patch: 'Http',
|
|
13
12
|
post: 'Http',
|
|
14
|
-
put: 'Http'
|
|
13
|
+
put: 'Http',
|
|
14
|
+
serviceBusQueue: 'ServiceBus',
|
|
15
|
+
serviceBusTopic: 'ServiceBus',
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
class AzureFunctionsPlugin extends TracingPlugin {
|
|
@@ -22,24 +23,16 @@ class AzureFunctionsPlugin extends TracingPlugin {
|
|
|
22
23
|
static get prefix () { return 'tracing:datadog:azure:functions:invoke' }
|
|
23
24
|
|
|
24
25
|
bindStart (ctx) {
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
// httpRequest.headers is a map
|
|
28
|
-
const childOf = this._tracer.extract('http_headers', Object.fromEntries(httpRequest.headers))
|
|
26
|
+
const childOf = extractTraceContext(this._tracer, ctx)
|
|
27
|
+
const meta = getMetaForTrigger(ctx)
|
|
29
28
|
const span = this.startSpan(this.operationName(), {
|
|
30
29
|
childOf,
|
|
31
30
|
service: this.serviceName(),
|
|
32
31
|
type: 'serverless',
|
|
33
|
-
meta
|
|
34
|
-
|
|
35
|
-
'aas.function.trigger': mapTriggerTag(methodName)
|
|
36
|
-
}
|
|
37
|
-
}, false)
|
|
32
|
+
meta,
|
|
33
|
+
}, ctx)
|
|
38
34
|
|
|
39
35
|
ctx.span = span
|
|
40
|
-
ctx.parentStore = store
|
|
41
|
-
ctx.currentStore = { ...store, span }
|
|
42
|
-
|
|
43
36
|
return ctx.currentStore
|
|
44
37
|
}
|
|
45
38
|
|
|
@@ -49,21 +42,26 @@ class AzureFunctionsPlugin extends TracingPlugin {
|
|
|
49
42
|
}
|
|
50
43
|
|
|
51
44
|
asyncEnd (ctx) {
|
|
52
|
-
const { httpRequest, result = {} } = ctx
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
const { httpRequest, methodName, result = {} } = ctx
|
|
46
|
+
if (triggerMap[methodName] === 'Http') {
|
|
47
|
+
// If the method is an HTTP trigger, we need to patch the request and finish the span
|
|
48
|
+
const path = (new URL(httpRequest.url)).pathname
|
|
49
|
+
const req = {
|
|
50
|
+
method: httpRequest.method,
|
|
51
|
+
headers: Object.fromEntries(httpRequest.headers),
|
|
52
|
+
url: path
|
|
53
|
+
}
|
|
54
|
+
const context = web.patch(req)
|
|
55
|
+
context.config = this.config
|
|
56
|
+
context.paths = [path]
|
|
57
|
+
context.res = { statusCode: result.status }
|
|
58
|
+
context.span = ctx.currentStore.span
|
|
65
59
|
|
|
66
|
-
|
|
60
|
+
serverless.finishSpan(context)
|
|
61
|
+
// Fallback for other trigger types
|
|
62
|
+
} else {
|
|
63
|
+
super.finish()
|
|
64
|
+
}
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
configure (config) {
|
|
@@ -71,8 +69,39 @@ class AzureFunctionsPlugin extends TracingPlugin {
|
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
72
|
+
function getMetaForTrigger ({ functionName, methodName, invocationContext }) {
|
|
73
|
+
let meta = {
|
|
74
|
+
'aas.function.name': functionName,
|
|
75
|
+
'aas.function.trigger': mapTriggerTag(methodName)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (triggerMap[methodName] === 'ServiceBus') {
|
|
79
|
+
const triggerEntity = invocationContext.options.trigger.queueName || invocationContext.options.trigger.topicName
|
|
80
|
+
meta = {
|
|
81
|
+
...meta,
|
|
82
|
+
'messaging.message_id': invocationContext.triggerMetadata.messageId,
|
|
83
|
+
'messaging.operation': 'receive',
|
|
84
|
+
'messaging.system': 'servicebus',
|
|
85
|
+
'messaging.destination.name': triggerEntity,
|
|
86
|
+
'resource.name': `ServiceBus ${functionName}`,
|
|
87
|
+
'span.kind': 'consumer'
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return meta
|
|
92
|
+
}
|
|
93
|
+
|
|
74
94
|
function mapTriggerTag (methodName) {
|
|
75
95
|
return triggerMap[methodName] || 'Unknown'
|
|
76
96
|
}
|
|
77
97
|
|
|
98
|
+
function extractTraceContext (tracer, ctx) {
|
|
99
|
+
switch (String(triggerMap[ctx.methodName])) {
|
|
100
|
+
case 'Http':
|
|
101
|
+
return tracer.extract('http_headers', Object.fromEntries(ctx.httpRequest.headers))
|
|
102
|
+
case 'ServiceBus':
|
|
103
|
+
return tracer.extract('text_map', ctx.invocationContext.triggerMetadata.applicationProperties)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
78
107
|
module.exports = AzureFunctionsPlugin
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ProducerPlugin = require('./producer')
|
|
4
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
|
+
|
|
6
|
+
class AzureServiceBusPlugin extends CompositePlugin {
|
|
7
|
+
static get id () { return 'azure-service-bus' }
|
|
8
|
+
static get plugins () {
|
|
9
|
+
return {
|
|
10
|
+
producer: ProducerPlugin
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = AzureServiceBusPlugin
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
4
|
+
|
|
5
|
+
class AzureServiceBusProducerPlugin extends ProducerPlugin {
|
|
6
|
+
static get id () { return 'azure-service-bus' }
|
|
7
|
+
static get operation () { return 'send' }
|
|
8
|
+
|
|
9
|
+
bindStart (ctx) {
|
|
10
|
+
const { sender, msg } = ctx
|
|
11
|
+
const qualifiedSenderNamespace = sender._sender.audience.replace('sb://', '')
|
|
12
|
+
const span = this.startSpan({
|
|
13
|
+
resource: sender.entityPath,
|
|
14
|
+
type: 'messaging',
|
|
15
|
+
meta: {
|
|
16
|
+
component: 'azure-service-bus',
|
|
17
|
+
'messaging.destination.name': sender.entityPath,
|
|
18
|
+
'messaging.operation': 'send',
|
|
19
|
+
'messaging.system': 'servicebus',
|
|
20
|
+
'network.destination.name': qualifiedSenderNamespace,
|
|
21
|
+
}
|
|
22
|
+
}, ctx)
|
|
23
|
+
|
|
24
|
+
// This is the correct key for injecting trace context into Azure Service Bus messages
|
|
25
|
+
// It may not be present in the message properties, so we ensure it exists
|
|
26
|
+
if (!msg.applicationProperties) {
|
|
27
|
+
msg.applicationProperties = {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.tracer.inject(span, 'text_map', msg.applicationProperties)
|
|
31
|
+
|
|
32
|
+
return ctx.currentStore
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = AzureServiceBusProducerPlugin
|
|
@@ -223,10 +223,31 @@ function getSuiteStatus (suiteStats) {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
class CypressPlugin {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
_isInit = false
|
|
227
|
+
testEnvironmentMetadata = getTestEnvironmentMetadata(TEST_FRAMEWORK_NAME)
|
|
228
|
+
|
|
229
|
+
finishedTestsByFile = {}
|
|
230
|
+
testStatuses = {}
|
|
231
|
+
|
|
232
|
+
isTestsSkipped = false
|
|
233
|
+
isSuitesSkippingEnabled = false
|
|
234
|
+
isCodeCoverageEnabled = false
|
|
235
|
+
isFlakyTestRetriesEnabled = false
|
|
236
|
+
isEarlyFlakeDetectionEnabled = false
|
|
237
|
+
isKnownTestsEnabled = false
|
|
238
|
+
earlyFlakeDetectionNumRetries = 0
|
|
239
|
+
testsToSkip = []
|
|
240
|
+
skippedTests = []
|
|
241
|
+
hasForcedToRunSuites = false
|
|
242
|
+
hasUnskippableSuites = false
|
|
243
|
+
unskippableSuites = []
|
|
244
|
+
knownTests = []
|
|
245
|
+
isTestManagementTestsEnabled = false
|
|
246
|
+
testManagementAttemptToFixRetries = 0
|
|
247
|
+
isImpactedTestsEnabled = false
|
|
248
|
+
modifiedTests = []
|
|
229
249
|
|
|
250
|
+
constructor () {
|
|
230
251
|
const {
|
|
231
252
|
[GIT_REPOSITORY_URL]: repositoryUrl,
|
|
232
253
|
[GIT_COMMIT_SHA]: sha,
|
|
@@ -265,26 +286,6 @@ class CypressPlugin {
|
|
|
265
286
|
commitHeadSha,
|
|
266
287
|
commitHeadMessage
|
|
267
288
|
}
|
|
268
|
-
this.finishedTestsByFile = {}
|
|
269
|
-
this.testStatuses = {}
|
|
270
|
-
|
|
271
|
-
this.isTestsSkipped = false
|
|
272
|
-
this.isSuitesSkippingEnabled = false
|
|
273
|
-
this.isCodeCoverageEnabled = false
|
|
274
|
-
this.isFlakyTestRetriesEnabled = false
|
|
275
|
-
this.isEarlyFlakeDetectionEnabled = false
|
|
276
|
-
this.isKnownTestsEnabled = false
|
|
277
|
-
this.earlyFlakeDetectionNumRetries = 0
|
|
278
|
-
this.testsToSkip = []
|
|
279
|
-
this.skippedTests = []
|
|
280
|
-
this.hasForcedToRunSuites = false
|
|
281
|
-
this.hasUnskippableSuites = false
|
|
282
|
-
this.unskippableSuites = []
|
|
283
|
-
this.knownTests = []
|
|
284
|
-
this.isTestManagementTestsEnabled = false
|
|
285
|
-
this.testManagementAttemptToFixRetries = 0
|
|
286
|
-
this.isImpactedTestsEnabled = false
|
|
287
|
-
this.modifiedTests = []
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
// Init function returns a promise that resolves with the Cypress configuration
|
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const makeUtilities = require('../../../dd-trace/src/plugins/util/llm')
|
|
4
|
-
|
|
5
3
|
class LangChainHandler {
|
|
6
|
-
constructor (tracerConfig) {
|
|
7
|
-
const utilities = makeUtilities('langchain', tracerConfig)
|
|
8
|
-
|
|
9
|
-
this.normalize = utilities.normalize
|
|
10
|
-
this.isPromptCompletionSampled = utilities.isPromptCompletionSampled
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// no-op for default handler
|
|
14
|
-
getSpanStartTags (ctx) {}
|
|
15
|
-
|
|
16
|
-
// no-op for default handler
|
|
17
|
-
getSpanEndTags (ctx) {}
|
|
18
|
-
|
|
19
|
-
// no-op for default handler
|
|
20
|
-
extractApiKey (instance) {}
|
|
21
|
-
|
|
22
4
|
// no-op for default handler
|
|
23
5
|
extractProvider (instance) {}
|
|
24
6
|
|
|
@@ -3,54 +3,6 @@
|
|
|
3
3
|
const LangChainHandler = require('./default')
|
|
4
4
|
|
|
5
5
|
class LangChainEmbeddingHandler extends LangChainHandler {
|
|
6
|
-
getSpanStartTags (ctx, provider, span) {
|
|
7
|
-
const tags = {}
|
|
8
|
-
|
|
9
|
-
const inputTexts = ctx.args?.[0]
|
|
10
|
-
|
|
11
|
-
const sampled = this.isPromptCompletionSampled(span)
|
|
12
|
-
if (typeof inputTexts === 'string') {
|
|
13
|
-
// embed query
|
|
14
|
-
if (sampled) {
|
|
15
|
-
tags['langchain.request.inputs.0.text'] = this.normalize(inputTexts)
|
|
16
|
-
}
|
|
17
|
-
tags['langchain.request.input_counts'] = 1
|
|
18
|
-
} else {
|
|
19
|
-
// embed documents
|
|
20
|
-
if (sampled) {
|
|
21
|
-
for (const idx in inputTexts) {
|
|
22
|
-
const inputText = inputTexts[idx]
|
|
23
|
-
tags[`langchain.request.inputs.${idx}.text`] = this.normalize(inputText)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
tags['langchain.request.input_counts'] = inputTexts.length
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return tags
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
getSpanEndTags (ctx) {
|
|
33
|
-
const tags = {}
|
|
34
|
-
|
|
35
|
-
const { result } = ctx
|
|
36
|
-
if (!Array.isArray(result)) return
|
|
37
|
-
|
|
38
|
-
tags['langchain.response.outputs.embedding_length'] = (
|
|
39
|
-
Array.isArray(result[0]) ? result[0] : result
|
|
40
|
-
).length
|
|
41
|
-
|
|
42
|
-
return tags
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
extractApiKey (instance) {
|
|
46
|
-
const apiKey =
|
|
47
|
-
instance.clientConfig?.apiKey ||
|
|
48
|
-
instance.apiKey ||
|
|
49
|
-
instance.client?.apiKey
|
|
50
|
-
if (!apiKey || apiKey.length < 4) return ''
|
|
51
|
-
return `...${apiKey.slice(-4)}`
|
|
52
|
-
}
|
|
53
|
-
|
|
54
6
|
extractProvider (instance) {
|
|
55
7
|
return instance.constructor.name.split('Embeddings')[0].toLowerCase()
|
|
56
8
|
}
|