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.
Files changed (45) hide show
  1. package/index.d.ts +6 -0
  2. package/package.json +5 -8
  3. package/packages/datadog-code-origin/index.js +3 -0
  4. package/packages/datadog-instrumentations/src/azure-functions.js +5 -0
  5. package/packages/datadog-instrumentations/src/azure-service-bus.js +38 -0
  6. package/packages/datadog-instrumentations/src/fastify.js +17 -0
  7. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  8. package/packages/datadog-instrumentations/src/next.js +17 -18
  9. package/packages/datadog-instrumentations/src/sequelize.js +4 -14
  10. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +6 -38
  11. package/packages/datadog-plugin-azure-functions/src/index.js +57 -28
  12. package/packages/datadog-plugin-azure-service-bus/src/index.js +15 -0
  13. package/packages/datadog-plugin-azure-service-bus/src/producer.js +36 -0
  14. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +24 -23
  15. package/packages/datadog-plugin-langchain/src/handlers/default.js +0 -18
  16. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +0 -48
  17. package/packages/datadog-plugin-langchain/src/handlers/language_models.js +18 -0
  18. package/packages/datadog-plugin-langchain/src/tracing.js +5 -17
  19. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +8 -1
  20. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +2 -2
  21. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +11 -10
  22. package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +25 -18
  23. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -5
  24. package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +5 -1
  25. package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +2 -2
  26. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -0
  27. package/packages/dd-trace/src/appsec/iast/index.js +25 -7
  28. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +79 -21
  29. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
  30. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +0 -4
  31. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +4 -8
  32. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -4
  33. package/packages/dd-trace/src/plugins/index.js +1 -0
  34. package/packages/dd-trace/src/plugins/util/ci.js +8 -0
  35. package/packages/dd-trace/src/plugins/util/git.js +50 -15
  36. package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
  37. package/packages/dd-trace/src/profiling/profilers/space.js +4 -3
  38. package/packages/dd-trace/src/profiling/profilers/wall.js +5 -4
  39. package/packages/dd-trace/src/remote_config/scheduler.js +2 -1
  40. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
  41. package/packages/dd-trace/src/supported-configurations.json +1 -0
  42. package/packages/datadog-plugin-langchain/src/handlers/chain.js +0 -50
  43. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +0 -101
  44. package/packages/datadog-plugin-langchain/src/handlers/language_models/index.js +0 -48
  45. 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.60.0",
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.9",
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.10.0",
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": "^59.0.1",
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": "^15.15.0",
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
- shimmer.wrap(request.NextRequest.prototype, 'nextUrl', function (originalGet) {
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(request.NextRequest.prototype, ['text', 'json'], function (originalMethod) {
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(request.NextRequest.prototype, 'formData', function (originalFormData) {
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
- asyncResource.bind(function () {
37
- finishCh.publish({ result })
38
- }, this).apply(this)
33
+ finishCh.runStores({ result }, () => {})
39
34
  }
40
35
 
41
- return asyncResource.bind(function () {
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
- }, this).apply(this, arguments)
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, extractRequestParams, extractTextAndResponseReason } = require('./utils')
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
- const requestParams = extractRequestParams(params, modelProvider)
24
- const textAndResponseReason = extractTextAndResponseReason(response, modelProvider, modelName)
25
-
26
- const tags = buildTagsFromParams(requestParams, textAndResponseReason, modelProvider, modelName, operation)
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 { functionName, methodName, httpRequest } = ctx
26
- const store = storage('legacy').getStore()
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
- 'aas.function.name': functionName,
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
- const path = (new URL(httpRequest.url)).pathname
54
- const req = {
55
- method: httpRequest.method,
56
- headers: Object.fromEntries(httpRequest.headers),
57
- url: path
58
- }
59
-
60
- const context = web.patch(req)
61
- context.config = this.config
62
- context.paths = [path]
63
- context.res = { statusCode: result.status }
64
- context.span = ctx.currentStore.span
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
- serverless.finishSpan(context)
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
- constructor () {
227
- this._isInit = false
228
- this.testEnvironmentMetadata = getTestEnvironmentMetadata(TEST_FRAMEWORK_NAME)
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
  }