dd-trace 5.102.0 → 5.104.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 (201) hide show
  1. package/ext/exporters.js +1 -0
  2. package/index.d.ts +25 -3
  3. package/package.json +15 -13
  4. package/packages/datadog-esbuild/src/utils.js +2 -2
  5. package/packages/datadog-instrumentations/src/ai.js +1 -1
  6. package/packages/datadog-instrumentations/src/aws-sdk.js +2 -2
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -2
  8. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +32 -15
  9. package/packages/datadog-instrumentations/src/couchbase.js +69 -220
  10. package/packages/datadog-instrumentations/src/cucumber.js +104 -31
  11. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  12. package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
  13. package/packages/datadog-instrumentations/src/electron.js +240 -0
  14. package/packages/datadog-instrumentations/src/fetch.js +5 -5
  15. package/packages/datadog-instrumentations/src/graphql.js +13 -17
  16. package/packages/datadog-instrumentations/src/grpc/client.js +48 -32
  17. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +2 -2
  18. package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
  21. package/packages/datadog-instrumentations/src/helpers/kafka.js +58 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +3 -2
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +19 -5
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +14 -13
  25. package/packages/datadog-instrumentations/src/http/client.js +2 -2
  26. package/packages/datadog-instrumentations/src/ioredis.js +18 -14
  27. package/packages/datadog-instrumentations/src/jest.js +382 -84
  28. package/packages/datadog-instrumentations/src/kafkajs.js +184 -174
  29. package/packages/datadog-instrumentations/src/mariadb.js +1 -1
  30. package/packages/datadog-instrumentations/src/memcached.js +2 -1
  31. package/packages/datadog-instrumentations/src/mocha/main.js +309 -56
  32. package/packages/datadog-instrumentations/src/mocha/utils.js +48 -8
  33. package/packages/datadog-instrumentations/src/mongodb-core.js +34 -9
  34. package/packages/datadog-instrumentations/src/mongoose.js +10 -12
  35. package/packages/datadog-instrumentations/src/mysql.js +2 -2
  36. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  37. package/packages/datadog-instrumentations/src/pg.js +25 -11
  38. package/packages/datadog-instrumentations/src/playwright.js +449 -60
  39. package/packages/datadog-instrumentations/src/redis.js +19 -10
  40. package/packages/datadog-instrumentations/src/router.js +4 -2
  41. package/packages/datadog-instrumentations/src/vitest.js +246 -149
  42. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
  43. package/packages/datadog-plugin-aws-sdk/src/base.js +18 -24
  44. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
  45. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
  46. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  47. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  48. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
  49. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  50. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
  51. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
  52. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  53. package/packages/datadog-plugin-couchbase/src/index.js +58 -52
  54. package/packages/datadog-plugin-cucumber/src/index.js +1 -0
  55. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +239 -40
  56. package/packages/datadog-plugin-cypress/src/support.js +13 -1
  57. package/packages/datadog-plugin-elasticsearch/src/index.js +28 -8
  58. package/packages/datadog-plugin-electron/src/index.js +17 -0
  59. package/packages/datadog-plugin-electron/src/ipc.js +143 -0
  60. package/packages/datadog-plugin-electron/src/net.js +82 -0
  61. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
  62. package/packages/datadog-plugin-graphql/src/execute.js +6 -28
  63. package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
  64. package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
  65. package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
  66. package/packages/datadog-plugin-graphql/src/utils.js +33 -1
  67. package/packages/datadog-plugin-grpc/src/client.js +6 -7
  68. package/packages/datadog-plugin-grpc/src/util.js +57 -22
  69. package/packages/datadog-plugin-http/src/client.js +2 -2
  70. package/packages/datadog-plugin-jest/src/index.js +92 -50
  71. package/packages/datadog-plugin-kafkajs/src/producer.js +32 -0
  72. package/packages/datadog-plugin-mocha/src/index.js +1 -0
  73. package/packages/datadog-plugin-mongodb-core/src/index.js +70 -69
  74. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  75. package/packages/datadog-plugin-openai/src/services.js +2 -1
  76. package/packages/datadog-plugin-pg/src/index.js +3 -3
  77. package/packages/datadog-plugin-playwright/src/index.js +4 -0
  78. package/packages/datadog-plugin-redis/src/index.js +54 -24
  79. package/packages/datadog-plugin-undici/src/index.js +19 -0
  80. package/packages/datadog-plugin-vitest/src/index.js +19 -7
  81. package/packages/datadog-shimmer/src/shimmer.js +35 -0
  82. package/packages/dd-trace/src/aiguard/index.js +3 -1
  83. package/packages/dd-trace/src/aiguard/sdk.js +36 -30
  84. package/packages/dd-trace/src/aiguard/tags.js +20 -11
  85. package/packages/dd-trace/src/appsec/blocking.js +2 -2
  86. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
  87. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  88. package/packages/dd-trace/src/appsec/index.js +10 -3
  89. package/packages/dd-trace/src/appsec/reporter.js +19 -5
  90. package/packages/dd-trace/src/azure_metadata.js +17 -6
  91. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
  92. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
  93. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
  94. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
  95. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -1
  96. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +5 -3
  97. package/packages/dd-trace/src/config/defaults.js +3 -14
  98. package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -1
  99. package/packages/dd-trace/src/config/helper.js +4 -0
  100. package/packages/dd-trace/src/config/index.js +2 -2
  101. package/packages/dd-trace/src/config/major-overrides.js +98 -0
  102. package/packages/dd-trace/src/config/parsers.js +7 -1
  103. package/packages/dd-trace/src/config/supported-configurations.json +60 -38
  104. package/packages/dd-trace/src/crashtracking/crashtracker.js +15 -3
  105. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  106. package/packages/dd-trace/src/datastreams/context.js +4 -2
  107. package/packages/dd-trace/src/datastreams/manager.js +1 -1
  108. package/packages/dd-trace/src/datastreams/processor.js +2 -2
  109. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
  110. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  111. package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
  112. package/packages/dd-trace/src/debugger/index.js +7 -7
  113. package/packages/dd-trace/src/dogstatsd.js +2 -2
  114. package/packages/dd-trace/src/encode/0.4.js +45 -54
  115. package/packages/dd-trace/src/encode/0.5.js +34 -3
  116. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +26 -19
  117. package/packages/dd-trace/src/encode/agentless-json.js +1 -1
  118. package/packages/dd-trace/src/exporter.js +2 -0
  119. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  120. package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
  121. package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
  122. package/packages/dd-trace/src/exporters/common/agents.js +3 -1
  123. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
  124. package/packages/dd-trace/src/exporters/common/request.js +4 -2
  125. package/packages/dd-trace/src/exporters/electron/index.js +49 -0
  126. package/packages/dd-trace/src/external-logger/src/index.js +2 -1
  127. package/packages/dd-trace/src/git_metadata.js +10 -8
  128. package/packages/dd-trace/src/id.js +17 -4
  129. package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
  130. package/packages/dd-trace/src/lambda/handler.js +2 -4
  131. package/packages/dd-trace/src/lambda/index.js +62 -14
  132. package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
  133. package/packages/dd-trace/src/llmobs/index.js +13 -2
  134. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
  135. package/packages/dd-trace/src/llmobs/sdk.js +10 -0
  136. package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
  137. package/packages/dd-trace/src/log/writer.js +3 -1
  138. package/packages/dd-trace/src/noop/span.js +3 -1
  139. package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
  140. package/packages/dd-trace/src/openfeature/writers/exposures.js +51 -20
  141. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
  142. package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
  143. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
  144. package/packages/dd-trace/src/plugins/apollo.js +3 -1
  145. package/packages/dd-trace/src/plugins/ci_plugin.js +52 -17
  146. package/packages/dd-trace/src/plugins/database.js +54 -12
  147. package/packages/dd-trace/src/plugins/index.js +1 -0
  148. package/packages/dd-trace/src/plugins/log_plugin.js +3 -1
  149. package/packages/dd-trace/src/plugins/plugin.js +2 -4
  150. package/packages/dd-trace/src/plugins/tracing.js +5 -3
  151. package/packages/dd-trace/src/plugins/util/ci.js +8 -8
  152. package/packages/dd-trace/src/plugins/util/git-cache.js +20 -18
  153. package/packages/dd-trace/src/plugins/util/git.js +3 -1
  154. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
  155. package/packages/dd-trace/src/plugins/util/test.js +119 -5
  156. package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -15
  157. package/packages/dd-trace/src/plugins/util/web.js +11 -0
  158. package/packages/dd-trace/src/priority_sampler.js +1 -1
  159. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  160. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
  161. package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
  162. package/packages/dd-trace/src/rate_limiter.js +1 -1
  163. package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
  164. package/packages/dd-trace/src/ritm.js +2 -1
  165. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
  166. package/packages/dd-trace/src/scope.js +7 -5
  167. package/packages/dd-trace/src/serverless.js +5 -2
  168. package/packages/dd-trace/src/service-naming/extra-services.js +14 -0
  169. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +20 -0
  170. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  171. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +20 -0
  172. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  173. package/packages/dd-trace/src/span_stats.js +1 -1
  174. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  175. package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
  176. package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
  177. package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
  178. package/vendor/dist/opentracing/LICENSE +0 -201
  179. package/vendor/dist/opentracing/binary_carrier.d.ts +0 -11
  180. package/vendor/dist/opentracing/constants.d.ts +0 -61
  181. package/vendor/dist/opentracing/examples/demo/demo.d.ts +0 -2
  182. package/vendor/dist/opentracing/ext/tags.d.ts +0 -90
  183. package/vendor/dist/opentracing/functions.d.ts +0 -20
  184. package/vendor/dist/opentracing/global_tracer.d.ts +0 -14
  185. package/vendor/dist/opentracing/index.d.ts +0 -12
  186. package/vendor/dist/opentracing/index.js +0 -1
  187. package/vendor/dist/opentracing/mock_tracer/index.d.ts +0 -5
  188. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +0 -13
  189. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +0 -16
  190. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +0 -50
  191. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +0 -26
  192. package/vendor/dist/opentracing/noop.d.ts +0 -8
  193. package/vendor/dist/opentracing/reference.d.ts +0 -33
  194. package/vendor/dist/opentracing/span.d.ts +0 -147
  195. package/vendor/dist/opentracing/span_context.d.ts +0 -26
  196. package/vendor/dist/opentracing/test/api_compatibility.d.ts +0 -16
  197. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +0 -3
  198. package/vendor/dist/opentracing/test/noop_implementation.d.ts +0 -4
  199. package/vendor/dist/opentracing/test/opentracing_api.d.ts +0 -3
  200. package/vendor/dist/opentracing/test/unittest.d.ts +0 -2
  201. package/vendor/dist/opentracing/tracer.d.ts +0 -127
@@ -0,0 +1,143 @@
1
+ 'use strict'
2
+
3
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
4
+ const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
5
+ const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
6
+
7
+ class ElectronIpcPlugin extends CompositePlugin {
8
+ static id = 'electron:ipc'
9
+ static get plugins () {
10
+ return {
11
+ main: ElectronMainPlugin,
12
+ renderer: ElectronRendererPlugin,
13
+ }
14
+ }
15
+ }
16
+
17
+ class ElectronMainPlugin extends CompositePlugin {
18
+ static id = 'electron:ipc:main'
19
+ static get plugins () {
20
+ return {
21
+ receive: ElectronMainReceivePlugin,
22
+ handle: ElectronMainHandlePlugin,
23
+ send: ElectronMainSendPlugin,
24
+ }
25
+ }
26
+ }
27
+
28
+ class ElectronRendererPlugin extends CompositePlugin {
29
+ static id = 'electron:ipc:renderer'
30
+ static get plugins () {
31
+ return {
32
+ receive: ElectronRendererReceivePlugin,
33
+ send: ElectronRendererSendPlugin,
34
+ }
35
+ }
36
+ }
37
+
38
+ class ElectronRendererReceivePlugin extends ConsumerPlugin {
39
+ static id = 'electron:ipc:renderer:receive'
40
+ static component = 'electron'
41
+ static operation = 'receive'
42
+ static prefix = 'tracing:apm:electron:ipc:renderer:receive'
43
+
44
+ bindStart (ctx) {
45
+ const { args, channel } = ctx
46
+
47
+ if (channel?.startsWith('datadog:')) return
48
+
49
+ const childOf = this._tracer.extract('text_map', args[args.length - 1])
50
+
51
+ if (childOf) {
52
+ args.pop()
53
+ }
54
+
55
+ this.startSpan({
56
+ childOf,
57
+ resource: channel,
58
+ type: 'worker',
59
+ meta: {},
60
+ }, ctx)
61
+
62
+ return ctx.currentStore
63
+ }
64
+
65
+ asyncEnd (ctx) {
66
+ this.finish(ctx)
67
+ }
68
+ }
69
+
70
+ class ElectronRendererSendPlugin extends ProducerPlugin {
71
+ static id = 'electron:ipc:renderer:send'
72
+ static component = 'electron'
73
+ static operation = 'send'
74
+ static prefix = 'tracing:apm:electron:ipc:renderer:send'
75
+
76
+ bindStart (ctx) {
77
+ const { args, channel } = ctx
78
+
79
+ if (channel?.startsWith('datadog:')) return
80
+
81
+ const span = this.startSpan({
82
+ resource: channel,
83
+ meta: {},
84
+ }, ctx)
85
+
86
+ if (this._shouldInject(ctx)) {
87
+ const carrier = {}
88
+
89
+ this._tracer.inject(span, 'text_map', carrier)
90
+
91
+ args.push(carrier)
92
+ }
93
+
94
+ return ctx.currentStore
95
+ }
96
+
97
+ end (ctx) {
98
+ if (ctx.hasOwnProperty('result')) {
99
+ this.finish(ctx)
100
+ }
101
+ }
102
+
103
+ asyncEnd (ctx) {
104
+ this.finish(ctx)
105
+ }
106
+
107
+ // Renderer can always inject since main is guaranteed to be patched.
108
+ _shouldInject () {
109
+ return true
110
+ }
111
+ }
112
+
113
+ class ElectronMainReceivePlugin extends ElectronRendererReceivePlugin {
114
+ static id = 'electron:ipc:main:receive'
115
+ static prefix = 'tracing:apm:electron:ipc:main:receive'
116
+ }
117
+
118
+ class ElectronMainHandlePlugin extends ElectronMainReceivePlugin {
119
+ static id = 'electron:ipc:main:handle'
120
+ static prefix = 'tracing:apm:electron:ipc:main:handle'
121
+ }
122
+
123
+ class ElectronMainSendPlugin extends ElectronRendererSendPlugin {
124
+ static id = 'electron:ipc:main:send'
125
+ static prefix = 'tracing:apm:electron:ipc:main:send'
126
+
127
+ constructor (...args) {
128
+ super(...args)
129
+
130
+ this._renderers = new WeakSet()
131
+
132
+ this.addSub('apm:electron:ipc:renderer:patched', event => {
133
+ this._renderers.add(event.sender)
134
+ })
135
+ }
136
+
137
+ // Only inject when the renderer was patched.
138
+ _shouldInject ({ self }) {
139
+ return this._renderers.has(self)
140
+ }
141
+ }
142
+
143
+ module.exports = ElectronIpcPlugin
@@ -0,0 +1,82 @@
1
+ 'use strict'
2
+
3
+ const HttpClientPlugin = require('../../datadog-plugin-http/src/client')
4
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
5
+
6
+ class ElectronNetPlugin extends CompositePlugin {
7
+ static id = 'electron:net'
8
+ static get plugins () {
9
+ return {
10
+ request: ElectronRequestPlugin,
11
+ }
12
+ }
13
+ }
14
+
15
+ class ElectronRequestPlugin extends HttpClientPlugin {
16
+ static id = 'electron:net:request'
17
+ static component = 'electron'
18
+ static operation = 'request'
19
+ static prefix = 'tracing:apm:electron:net:request'
20
+
21
+ bindStart (ctx) {
22
+ const args = ctx.args
23
+
24
+ let options = args[0]
25
+
26
+ if (typeof options === 'string') {
27
+ options = args[0] = { url: options }
28
+ } else if (!options) {
29
+ options = args[0] = {}
30
+ }
31
+
32
+ const headers = options.headers || {}
33
+
34
+ try {
35
+ if (typeof options === 'string') {
36
+ options = new URL(options)
37
+ } else if (options.url) {
38
+ options = new URL(options.url)
39
+ }
40
+ } catch {
41
+ // leave options as-is
42
+ }
43
+
44
+ options.headers = headers
45
+ ctx.args = { options }
46
+
47
+ const store = super.bindStart(ctx)
48
+
49
+ ctx.args = args
50
+
51
+ for (const name in options.headers) {
52
+ if (!headers[name]) {
53
+ args[0].headers ??= {}
54
+ args[0].headers[name] = options.headers[name]
55
+ }
56
+ }
57
+
58
+ return store
59
+ }
60
+
61
+ asyncStart (ctx) {
62
+ const reqHeaders = {}
63
+ const resHeaders = {}
64
+ const responseHead = ctx.res?._responseHead
65
+ const { statusCode } = responseHead || {}
66
+
67
+ for (const header in ctx.req._urlLoaderOptions?.headers || {}) {
68
+ reqHeaders[header.name] = header.value
69
+ }
70
+
71
+ for (const header in responseHead?.rawHeaders || {}) {
72
+ resHeaders[header.name] = header.value
73
+ }
74
+
75
+ ctx.req = { headers: reqHeaders }
76
+ ctx.res = { headers: resHeaders, statusCode }
77
+
78
+ this.finish(ctx)
79
+ }
80
+ }
81
+
82
+ module.exports = ElectronNetPlugin
@@ -54,9 +54,13 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
54
54
  * - Inject batch span context + metadata into all message attributes for downstream
55
55
  * consumers to reconstruct the trace and understand batch relationships
56
56
  */
57
- const spanLinkData = hasTraceContext
58
- ? messages.slice(1).map(msg => this.#extractSpanLink(msg.attributes)).filter(Boolean)
59
- : []
57
+ const spanLinkData = []
58
+ if (hasTraceContext) {
59
+ for (let i = 1; i < messageCount; i++) {
60
+ const link = this.#extractSpanLink(messages[i].attributes)
61
+ if (link) spanLinkData.push(link)
62
+ }
63
+ }
60
64
 
61
65
  const firstAttrs = messages[0]?.attributes
62
66
  const parentData = firstAttrs?.['x-datadog-trace-id'] && firstAttrs['x-datadog-parent-id']
@@ -107,35 +111,40 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
107
111
  ))
108
112
  }
109
113
 
110
- for (let i = 0; i < messages.length; i++) {
114
+ const messageCountStr = String(messageCount)
115
+ const startTimeStr = String(Math.floor(batchSpan._startTime))
116
+ const dsmEnabled = this.config.dsmEnabled
117
+
118
+ for (let i = 0; i < messageCount; i++) {
111
119
  const msg = messages[i]
112
- msg.attributes ??= {}
120
+ const attributes = msg.attributes ??= {}
113
121
 
114
122
  if (!hasTraceContext) {
115
- this.tracer.inject(batchSpan, 'text_map', msg.attributes)
123
+ this.tracer.inject(batchSpan, 'text_map', attributes)
116
124
  }
117
125
 
118
- Object.assign(msg.attributes, {
119
- '_dd.pubsub_request.trace_id': batchTraceIdHex,
120
- '_dd.pubsub_request.span_id': batchSpanIdHex,
121
- '_dd.batch.size': String(messageCount),
122
- '_dd.batch.index': String(i),
123
- 'gcloud.project_id': projectId,
124
- 'pubsub.topic': topic,
125
- 'x-dd-publish-start-time': String(Math.floor(batchSpan._startTime)),
126
- })
126
+ // Assign keys one-by-one rather than via `Object.assign({...})` so V8
127
+ // keeps the attributes object on its existing hidden class instead of
128
+ // allocating a fresh literal per message.
129
+ attributes['_dd.pubsub_request.trace_id'] = batchTraceIdHex
130
+ attributes['_dd.pubsub_request.span_id'] = batchSpanIdHex
131
+ attributes['_dd.batch.size'] = messageCountStr
132
+ attributes['_dd.batch.index'] = String(i)
133
+ attributes['gcloud.project_id'] = projectId
134
+ attributes['pubsub.topic'] = topic
135
+ attributes['x-dd-publish-start-time'] = startTimeStr
127
136
 
128
137
  if (batchTraceIdUpper) {
129
- msg.attributes['_dd.pubsub_request.p.tid'] = batchTraceIdUpper
138
+ attributes['_dd.pubsub_request.p.tid'] = batchTraceIdUpper
130
139
  }
131
140
 
132
- if (this.config.dsmEnabled) {
141
+ if (dsmEnabled) {
133
142
  const dataStreamsContext = this.tracer.setCheckpoint(
134
143
  ['direction:out', `topic:${topic}`, 'type:google-pubsub'],
135
144
  batchSpan,
136
145
  getHeadersSize(msg)
137
146
  )
138
- DsmPathwayCodec.encode(dataStreamsContext, msg.attributes)
147
+ DsmPathwayCodec.encode(dataStreamsContext, attributes)
139
148
  }
140
149
  }
141
150
 
@@ -1,9 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
4
- const { extractErrorIntoSpanEvent } = require('./utils')
5
-
6
- let tools
4
+ const { extractErrorIntoSpanEvent, getSignature } = require('./utils')
7
5
 
8
6
  class GraphQLExecutePlugin extends TracingPlugin {
9
7
  static id = 'graphql'
@@ -54,35 +52,15 @@ class GraphQLExecutePlugin extends TracingPlugin {
54
52
  // span-related
55
53
 
56
54
  function addVariableTags (config, span, variableValues) {
57
- const tags = {}
55
+ if (!variableValues || !config.variables) return
58
56
 
59
- if (variableValues && config.variables) {
60
- const variables = config.variables(variableValues)
61
- for (const [param, value] of Object.entries(variables)) {
62
- tags[`graphql.variables.${param}`] = value
63
- }
57
+ const tags = {}
58
+ const variables = config.variables(variableValues)
59
+ for (const [param, value] of Object.entries(variables)) {
60
+ tags[`graphql.variables.${param}`] = value
64
61
  }
65
62
 
66
63
  span.addTags(tags)
67
64
  }
68
65
 
69
- function getSignature (document, operationName, operationType, calculate) {
70
- if (calculate !== false && tools !== false) {
71
- try {
72
- try {
73
- tools = tools || require('./tools')
74
- } catch (e) {
75
- tools = false
76
- throw e
77
- }
78
-
79
- return tools.defaultEngineReportingSignature(document, operationName)
80
- } catch {
81
- // safety net
82
- }
83
- }
84
-
85
- return [operationType, operationName].filter(Boolean).join(' ')
86
- }
87
-
88
66
  module.exports = GraphQLExecutePlugin
@@ -12,8 +12,6 @@ class GraphQLResolvePlugin extends TracingPlugin {
12
12
  start (fieldCtx) {
13
13
  const { info, rootCtx, args, path: pathAsArray, pathString } = fieldCtx
14
14
 
15
- const path = getPath(this.config, pathAsArray)
16
-
17
15
  // we need to get the parent span to the field if it exists for correct span parenting
18
16
  // of nested fields
19
17
  const parentField = getParentField(rootCtx, pathString)
@@ -21,8 +19,10 @@ class GraphQLResolvePlugin extends TracingPlugin {
21
19
 
22
20
  fieldCtx.parent = parentField
23
21
 
24
- if (!shouldInstrument(this.config, path)) return
25
- const computedPathString = path.join('.')
22
+ if (!shouldInstrument(this.config, pathAsArray)) return
23
+ const computedPathString = this.config.collapse
24
+ ? buildCollapsedPathString(pathAsArray)
25
+ : pathString
26
26
 
27
27
  if (this.config.collapse) {
28
28
  if (rootCtx.fields[computedPathString]) return
@@ -37,7 +37,7 @@ class GraphQLResolvePlugin extends TracingPlugin {
37
37
  }
38
38
 
39
39
  const document = rootCtx.source
40
- const fieldNode = info.fieldNodes.find(fieldNode => fieldNode.kind === 'Field')
40
+ const fieldNode = info.fieldNodes[0]
41
41
  const loc = this.config.source && document && fieldNode && fieldNode.loc
42
42
  const source = loc && document.slice(loc.start, loc.end)
43
43
 
@@ -78,9 +78,7 @@ class GraphQLResolvePlugin extends TracingPlugin {
78
78
  this.addTraceSub('updateField', (ctx) => {
79
79
  const { field, error, path: pathAsArray } = ctx
80
80
 
81
- const path = getPath(this.config, pathAsArray)
82
-
83
- if (!shouldInstrument(this.config, path)) return
81
+ if (!shouldInstrument(this.config, pathAsArray)) return
84
82
 
85
83
  const span = ctx?.currentStore?.span || this.activeSpan
86
84
  field.finishTime = span._getTime ? span._getTime() : 0
@@ -107,56 +105,53 @@ class GraphQLResolvePlugin extends TracingPlugin {
107
105
 
108
106
  // helpers
109
107
 
110
- function shouldInstrument (config, path) {
108
+ function shouldInstrument (config, pathAsArray) {
109
+ if (config.depth < 0) return true
110
+
111
111
  let depth = 0
112
- for (const item of path) {
113
- if (typeof item === 'string') {
114
- depth += 1
112
+ if (config.collapse) {
113
+ depth = pathAsArray.length
114
+ } else {
115
+ for (const segment of pathAsArray) {
116
+ if (typeof segment === 'string') depth += 1
115
117
  }
116
118
  }
117
119
 
118
- return config.depth < 0 || config.depth >= depth
119
- }
120
-
121
- function getPath (config, pathAsArray) {
122
- return config.collapse
123
- ? withCollapse(pathAsArray)
124
- : pathAsArray
120
+ return config.depth >= depth
125
121
  }
126
122
 
127
- function withCollapse (pathAsArray) {
128
- return pathAsArray.map(segment => typeof segment === 'number' ? '*' : segment)
123
+ function buildCollapsedPathString (pathAsArray) {
124
+ let result = ''
125
+ for (const segment of pathAsArray) {
126
+ if (result.length > 0) result += '.'
127
+ result += typeof segment === 'number' ? '*' : segment
128
+ }
129
+ return result
129
130
  }
130
131
 
131
132
  function getResolverInfo (info, args) {
132
- let resolverInfo = null
133
- const resolverVars = {}
133
+ let resolverVars
134
134
 
135
- if (args) {
136
- Object.assign(resolverVars, args)
135
+ if (args && Object.keys(args).length > 0) {
136
+ resolverVars = { ...args }
137
137
  }
138
138
 
139
- let hasResolvers = false
140
139
  const directives = info.fieldNodes?.[0]?.directives
141
140
  if (Array.isArray(directives)) {
142
141
  for (const directive of directives) {
142
+ if (directive.arguments.length === 0) continue
143
+
143
144
  const argList = {}
144
145
  for (const argument of directive.arguments) {
145
146
  argList[argument.name.value] = argument.value.value
146
147
  }
147
148
 
148
- if (directive.arguments.length > 0) {
149
- hasResolvers = true
150
- resolverVars[directive.name.value] = argList
151
- }
149
+ resolverVars ??= {}
150
+ resolverVars[directive.name.value] = argList
152
151
  }
153
152
  }
154
153
 
155
- if (hasResolvers || args && Object.keys(resolverVars).length) {
156
- resolverInfo = { [info.fieldName]: resolverVars }
157
- }
158
-
159
- return resolverInfo
154
+ return resolverVars === undefined ? null : { [info.fieldName]: resolverVars }
160
155
  }
161
156
 
162
157
  function getParentField (parentCtx, pathToString) {
@@ -1,9 +1,34 @@
1
- // file mostly untouched from apollo-graphql
1
+ 'use strict'
2
2
 
3
- "use strict";
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const transforms_1 = require("./transforms");
6
- function defaultEngineReportingSignature(ast, operationName) {
7
- return transforms_1.printWithReducedWhitespace(transforms_1.sortAST(transforms_1.removeAliases(transforms_1.hideLiterals(transforms_1.dropUnusedDefinitions(ast, operationName)))));
3
+ Object.defineProperty(exports, '__esModule', { value: true })
4
+ const transforms = require('./transforms')
5
+
6
+ // Apollo Server / Yoga / Mercurius hand back the same parsed `DocumentNode`
7
+ // from their own document caches per execute, so memoizing the signature on
8
+ // the document keeps the visit/print pipeline off the hot path. The inner
9
+ // Map keys on operationName since `separateOperations` picks a different
10
+ // sub-document for each operation.
11
+ const cache = new WeakMap()
12
+
13
+ function defaultEngineReportingSignature (ast, operationName) {
14
+ const key = operationName == null ? '' : operationName
15
+ let inner = cache.get(ast)
16
+ if (inner !== undefined) {
17
+ const cached = inner.get(key)
18
+ if (cached !== undefined) {
19
+ return cached
20
+ }
21
+ }
22
+ const signature = transforms.printWithReducedWhitespace(
23
+ transforms.transformForSignature(
24
+ transforms.dropUnusedDefinitions(ast, operationName)
25
+ )
26
+ )
27
+ if (inner === undefined) {
28
+ inner = new Map()
29
+ cache.set(ast, inner)
30
+ }
31
+ inner.set(key, signature)
32
+ return signature
8
33
  }
9
- exports.defaultEngineReportingSignature = defaultEngineReportingSignature;
34
+ exports.defaultEngineReportingSignature = defaultEngineReportingSignature