@sentry/core 10.50.0 → 10.52.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 (347) hide show
  1. package/build/cjs/client.js +33 -5
  2. package/build/cjs/client.js.map +1 -1
  3. package/build/cjs/envelope.js +4 -1
  4. package/build/cjs/envelope.js.map +1 -1
  5. package/build/cjs/fetch.js +7 -4
  6. package/build/cjs/fetch.js.map +1 -1
  7. package/build/cjs/index.js +37 -13
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/instrument/console.js +3 -1
  10. package/build/cjs/instrument/console.js.map +1 -1
  11. package/build/cjs/instrument/fetch.js +6 -2
  12. package/build/cjs/instrument/fetch.js.map +1 -1
  13. package/build/cjs/instrument/handlers.js +11 -1
  14. package/build/cjs/instrument/handlers.js.map +1 -1
  15. package/build/cjs/integrations/console.js +3 -1
  16. package/build/cjs/integrations/console.js.map +1 -1
  17. package/build/cjs/integrations/express/index.js +2 -4
  18. package/build/cjs/integrations/express/index.js.map +1 -1
  19. package/build/cjs/integrations/express/utils.js +0 -7
  20. package/build/cjs/integrations/express/utils.js.map +1 -1
  21. package/build/cjs/integrations/extraerrordata.js +2 -2
  22. package/build/cjs/integrations/extraerrordata.js.map +1 -1
  23. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js +43 -0
  24. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  25. package/build/cjs/integrations/http/client-patch.js +113 -0
  26. package/build/cjs/integrations/http/client-patch.js.map +1 -0
  27. package/build/cjs/integrations/http/client-subscriptions.js +166 -0
  28. package/build/cjs/integrations/http/client-subscriptions.js.map +1 -0
  29. package/build/cjs/integrations/http/constants.js +10 -0
  30. package/build/cjs/integrations/http/constants.js.map +1 -0
  31. package/build/cjs/integrations/http/double-wrap-warning.js +29 -0
  32. package/build/cjs/integrations/http/double-wrap-warning.js.map +1 -0
  33. package/build/cjs/integrations/http/get-outgoing-span-data.js +88 -0
  34. package/build/cjs/integrations/http/get-outgoing-span-data.js.map +1 -0
  35. package/build/cjs/integrations/http/get-request-url.js +54 -0
  36. package/build/cjs/integrations/http/get-request-url.js.map +1 -0
  37. package/build/cjs/integrations/http/inject-trace-propagation-headers.js +81 -0
  38. package/build/cjs/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  39. package/build/cjs/integrations/postgresjs.js +10 -1
  40. package/build/cjs/integrations/postgresjs.js.map +1 -1
  41. package/build/cjs/integrations/requestdata.js +92 -6
  42. package/build/cjs/integrations/requestdata.js.map +1 -1
  43. package/build/cjs/integrations/supabase.js +39 -12
  44. package/build/cjs/integrations/supabase.js.map +1 -1
  45. package/build/cjs/logs/console-integration.js +3 -1
  46. package/build/cjs/logs/console-integration.js.map +1 -1
  47. package/build/cjs/logs/envelope.js +12 -2
  48. package/build/cjs/logs/envelope.js.map +1 -1
  49. package/build/cjs/logs/internal.js +7 -1
  50. package/build/cjs/logs/internal.js.map +1 -1
  51. package/build/cjs/metrics/envelope.js +15 -2
  52. package/build/cjs/metrics/envelope.js.map +1 -1
  53. package/build/cjs/metrics/internal.js +7 -1
  54. package/build/cjs/metrics/internal.js.map +1 -1
  55. package/build/cjs/server-runtime-client.js +20 -2
  56. package/build/cjs/server-runtime-client.js.map +1 -1
  57. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  58. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  59. package/build/cjs/tracing/idleSpan.js +7 -1
  60. package/build/cjs/tracing/idleSpan.js.map +1 -1
  61. package/build/cjs/tracing/langchain/index.js +43 -8
  62. package/build/cjs/tracing/langchain/index.js.map +1 -1
  63. package/build/cjs/tracing/langchain/utils.js +44 -10
  64. package/build/cjs/tracing/langchain/utils.js.map +1 -1
  65. package/build/cjs/tracing/langgraph/index.js +105 -2
  66. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  67. package/build/cjs/tracing/langgraph/utils.js +168 -0
  68. package/build/cjs/tracing/langgraph/utils.js.map +1 -1
  69. package/build/cjs/tracing/spans/captureSpan.js +169 -9
  70. package/build/cjs/tracing/spans/captureSpan.js.map +1 -1
  71. package/build/cjs/tracing/spans/envelope.js +13 -3
  72. package/build/cjs/tracing/spans/envelope.js.map +1 -1
  73. package/build/cjs/tracing/trace.js +2 -0
  74. package/build/cjs/tracing/trace.js.map +1 -1
  75. package/build/cjs/tracing/vercel-ai/constants.js +8 -0
  76. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  77. package/build/cjs/tracing/vercel-ai/index.js +93 -14
  78. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  79. package/build/cjs/trpc.js +2 -3
  80. package/build/cjs/trpc.js.map +1 -1
  81. package/build/cjs/utils/baggage.js +73 -0
  82. package/build/cjs/utils/baggage.js.map +1 -1
  83. package/build/cjs/utils/chain-and-copy-promiselike.js +1 -0
  84. package/build/cjs/utils/chain-and-copy-promiselike.js.map +1 -1
  85. package/build/cjs/utils/get-default-export.js +32 -0
  86. package/build/cjs/utils/get-default-export.js.map +1 -0
  87. package/build/cjs/utils/isSentryRequestUrl.js +9 -1
  88. package/build/cjs/utils/isSentryRequestUrl.js.map +1 -1
  89. package/build/cjs/utils/normalizationHints.js +38 -0
  90. package/build/cjs/utils/normalizationHints.js.map +1 -0
  91. package/build/cjs/utils/normalize.js +7 -11
  92. package/build/cjs/utils/normalize.js.map +1 -1
  93. package/build/cjs/utils/object.js +1 -1
  94. package/build/cjs/utils/object.js.map +1 -1
  95. package/build/cjs/utils/request.js +192 -12
  96. package/build/cjs/utils/request.js.map +1 -1
  97. package/build/cjs/utils/should-ignore-span.js +27 -8
  98. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  99. package/build/cjs/utils/spanUtils.js +1 -1
  100. package/build/cjs/utils/spanUtils.js.map +1 -1
  101. package/build/cjs/utils/version.js +1 -1
  102. package/build/esm/client.js +33 -5
  103. package/build/esm/client.js.map +1 -1
  104. package/build/esm/envelope.js +4 -1
  105. package/build/esm/envelope.js.map +1 -1
  106. package/build/esm/fetch.js +7 -4
  107. package/build/esm/fetch.js.map +1 -1
  108. package/build/esm/index.js +11 -5
  109. package/build/esm/index.js.map +1 -1
  110. package/build/esm/instrument/console.js +3 -1
  111. package/build/esm/instrument/console.js.map +1 -1
  112. package/build/esm/instrument/fetch.js +6 -2
  113. package/build/esm/instrument/fetch.js.map +1 -1
  114. package/build/esm/instrument/handlers.js +11 -1
  115. package/build/esm/instrument/handlers.js.map +1 -1
  116. package/build/esm/integrations/console.js +3 -1
  117. package/build/esm/integrations/console.js.map +1 -1
  118. package/build/esm/integrations/express/index.js +3 -5
  119. package/build/esm/integrations/express/index.js.map +1 -1
  120. package/build/esm/integrations/express/utils.js +1 -7
  121. package/build/esm/integrations/express/utils.js.map +1 -1
  122. package/build/esm/integrations/extraerrordata.js +2 -2
  123. package/build/esm/integrations/extraerrordata.js.map +1 -1
  124. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js +41 -0
  125. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  126. package/build/esm/integrations/http/client-patch.js +111 -0
  127. package/build/esm/integrations/http/client-patch.js.map +1 -0
  128. package/build/esm/integrations/http/client-subscriptions.js +164 -0
  129. package/build/esm/integrations/http/client-subscriptions.js.map +1 -0
  130. package/build/esm/integrations/http/constants.js +6 -0
  131. package/build/esm/integrations/http/constants.js.map +1 -0
  132. package/build/esm/integrations/http/double-wrap-warning.js +26 -0
  133. package/build/esm/integrations/http/double-wrap-warning.js.map +1 -0
  134. package/build/esm/integrations/http/get-outgoing-span-data.js +85 -0
  135. package/build/esm/integrations/http/get-outgoing-span-data.js.map +1 -0
  136. package/build/esm/integrations/http/get-request-url.js +49 -0
  137. package/build/esm/integrations/http/get-request-url.js.map +1 -0
  138. package/build/esm/integrations/http/inject-trace-propagation-headers.js +79 -0
  139. package/build/esm/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  140. package/build/esm/integrations/postgresjs.js +10 -1
  141. package/build/esm/integrations/postgresjs.js.map +1 -1
  142. package/build/esm/integrations/requestdata.js +92 -6
  143. package/build/esm/integrations/requestdata.js.map +1 -1
  144. package/build/esm/integrations/supabase.js +39 -12
  145. package/build/esm/integrations/supabase.js.map +1 -1
  146. package/build/esm/logs/console-integration.js +3 -1
  147. package/build/esm/logs/console-integration.js.map +1 -1
  148. package/build/esm/logs/envelope.js +12 -2
  149. package/build/esm/logs/envelope.js.map +1 -1
  150. package/build/esm/logs/internal.js +7 -1
  151. package/build/esm/logs/internal.js.map +1 -1
  152. package/build/esm/metrics/envelope.js +15 -2
  153. package/build/esm/metrics/envelope.js.map +1 -1
  154. package/build/esm/metrics/internal.js +7 -1
  155. package/build/esm/metrics/internal.js.map +1 -1
  156. package/build/esm/package.json +1 -1
  157. package/build/esm/server-runtime-client.js +20 -2
  158. package/build/esm/server-runtime-client.js.map +1 -1
  159. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  160. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  161. package/build/esm/tracing/idleSpan.js +7 -1
  162. package/build/esm/tracing/idleSpan.js.map +1 -1
  163. package/build/esm/tracing/langchain/index.js +45 -10
  164. package/build/esm/tracing/langchain/index.js.map +1 -1
  165. package/build/esm/tracing/langchain/utils.js +44 -12
  166. package/build/esm/tracing/langchain/utils.js.map +1 -1
  167. package/build/esm/tracing/langgraph/index.js +107 -5
  168. package/build/esm/tracing/langgraph/index.js.map +1 -1
  169. package/build/esm/tracing/langgraph/utils.js +166 -2
  170. package/build/esm/tracing/langgraph/utils.js.map +1 -1
  171. package/build/esm/tracing/spans/captureSpan.js +170 -11
  172. package/build/esm/tracing/spans/captureSpan.js.map +1 -1
  173. package/build/esm/tracing/spans/envelope.js +13 -3
  174. package/build/esm/tracing/spans/envelope.js.map +1 -1
  175. package/build/esm/tracing/trace.js +2 -1
  176. package/build/esm/tracing/trace.js.map +1 -1
  177. package/build/esm/tracing/vercel-ai/constants.js +8 -1
  178. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  179. package/build/esm/tracing/vercel-ai/index.js +95 -17
  180. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  181. package/build/esm/trpc.js +2 -3
  182. package/build/esm/trpc.js.map +1 -1
  183. package/build/esm/utils/baggage.js +73 -1
  184. package/build/esm/utils/baggage.js.map +1 -1
  185. package/build/esm/utils/chain-and-copy-promiselike.js +1 -0
  186. package/build/esm/utils/chain-and-copy-promiselike.js.map +1 -1
  187. package/build/esm/utils/get-default-export.js +30 -0
  188. package/build/esm/utils/get-default-export.js.map +1 -0
  189. package/build/esm/utils/isSentryRequestUrl.js +9 -1
  190. package/build/esm/utils/isSentryRequestUrl.js.map +1 -1
  191. package/build/esm/utils/normalizationHints.js +33 -0
  192. package/build/esm/utils/normalizationHints.js.map +1 -0
  193. package/build/esm/utils/normalize.js +7 -11
  194. package/build/esm/utils/normalize.js.map +1 -1
  195. package/build/esm/utils/object.js +1 -1
  196. package/build/esm/utils/object.js.map +1 -1
  197. package/build/esm/utils/request.js +190 -13
  198. package/build/esm/utils/request.js.map +1 -1
  199. package/build/esm/utils/should-ignore-span.js +27 -8
  200. package/build/esm/utils/should-ignore-span.js.map +1 -1
  201. package/build/esm/utils/spanUtils.js +1 -1
  202. package/build/esm/utils/spanUtils.js.map +1 -1
  203. package/build/esm/utils/version.js +1 -1
  204. package/build/types/client.d.ts +12 -1
  205. package/build/types/client.d.ts.map +1 -1
  206. package/build/types/envelope.d.ts.map +1 -1
  207. package/build/types/fetch.d.ts.map +1 -1
  208. package/build/types/index.d.ts +17 -6
  209. package/build/types/index.d.ts.map +1 -1
  210. package/build/types/instrument/console.d.ts +2 -1
  211. package/build/types/instrument/console.d.ts.map +1 -1
  212. package/build/types/instrument/fetch.d.ts +4 -2
  213. package/build/types/instrument/fetch.d.ts.map +1 -1
  214. package/build/types/instrument/handlers.d.ts +2 -2
  215. package/build/types/instrument/handlers.d.ts.map +1 -1
  216. package/build/types/integrations/console.d.ts.map +1 -1
  217. package/build/types/integrations/express/index.d.ts.map +1 -1
  218. package/build/types/integrations/express/utils.d.ts +1 -5
  219. package/build/types/integrations/express/utils.d.ts.map +1 -1
  220. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  221. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts.map +1 -0
  222. package/build/types/integrations/http/client-patch.d.ts +46 -0
  223. package/build/types/integrations/http/client-patch.d.ts.map +1 -0
  224. package/build/types/integrations/http/client-subscriptions.d.ts +21 -0
  225. package/build/types/integrations/http/client-subscriptions.d.ts.map +1 -0
  226. package/build/types/integrations/http/constants.d.ts +6 -0
  227. package/build/types/integrations/http/constants.d.ts.map +1 -0
  228. package/build/types/integrations/http/double-wrap-warning.d.ts +4 -0
  229. package/build/types/integrations/http/double-wrap-warning.d.ts.map +1 -0
  230. package/build/types/integrations/http/get-outgoing-span-data.d.ts +13 -0
  231. package/build/types/integrations/http/get-outgoing-span-data.d.ts.map +1 -0
  232. package/build/types/integrations/http/get-request-url.d.ts +10 -0
  233. package/build/types/integrations/http/get-request-url.d.ts.map +1 -0
  234. package/build/types/integrations/http/index.d.ts +4 -0
  235. package/build/types/integrations/http/index.d.ts.map +1 -0
  236. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  237. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts.map +1 -0
  238. package/build/types/integrations/http/types.d.ts +249 -0
  239. package/build/types/integrations/http/types.d.ts.map +1 -0
  240. package/build/types/integrations/postgresjs.d.ts.map +1 -1
  241. package/build/types/integrations/requestdata.d.ts.map +1 -1
  242. package/build/types/integrations/supabase.d.ts.map +1 -1
  243. package/build/types/logs/console-integration.d.ts.map +1 -1
  244. package/build/types/logs/envelope.d.ts +5 -2
  245. package/build/types/logs/envelope.d.ts.map +1 -1
  246. package/build/types/logs/internal.d.ts.map +1 -1
  247. package/build/types/metrics/envelope.d.ts +5 -2
  248. package/build/types/metrics/envelope.d.ts.map +1 -1
  249. package/build/types/metrics/internal.d.ts.map +1 -1
  250. package/build/types/server-runtime-client.d.ts +5 -0
  251. package/build/types/server-runtime-client.d.ts.map +1 -1
  252. package/build/types/tracing/idleSpan.d.ts.map +1 -1
  253. package/build/types/tracing/index.d.ts +1 -1
  254. package/build/types/tracing/index.d.ts.map +1 -1
  255. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  256. package/build/types/tracing/langchain/types.d.ts +8 -0
  257. package/build/types/tracing/langchain/types.d.ts.map +1 -1
  258. package/build/types/tracing/langchain/utils.d.ts +2 -0
  259. package/build/types/tracing/langchain/utils.d.ts.map +1 -1
  260. package/build/types/tracing/langgraph/index.d.ts +4 -0
  261. package/build/types/tracing/langgraph/index.d.ts.map +1 -1
  262. package/build/types/tracing/langgraph/utils.d.ts +18 -2
  263. package/build/types/tracing/langgraph/utils.d.ts.map +1 -1
  264. package/build/types/tracing/spans/captureSpan.d.ts +13 -3
  265. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -1
  266. package/build/types/tracing/spans/envelope.d.ts.map +1 -1
  267. package/build/types/tracing/trace.d.ts +1 -0
  268. package/build/types/tracing/trace.d.ts.map +1 -1
  269. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  270. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  271. package/build/types/tracing/vercel-ai/index.d.ts +9 -0
  272. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  273. package/build/types/trpc.d.ts.map +1 -1
  274. package/build/types/types-hoist/feedback/config.d.ts +20 -0
  275. package/build/types/types-hoist/feedback/config.d.ts.map +1 -1
  276. package/build/types/types-hoist/feedback/index.d.ts +2 -2
  277. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  278. package/build/types/types-hoist/feedback/sendFeedback.d.ts +3 -0
  279. package/build/types/types-hoist/feedback/sendFeedback.d.ts.map +1 -1
  280. package/build/types/types-hoist/log.d.ts +5 -0
  281. package/build/types/types-hoist/log.d.ts.map +1 -1
  282. package/build/types/types-hoist/metric.d.ts +5 -0
  283. package/build/types/types-hoist/metric.d.ts.map +1 -1
  284. package/build/types/types-hoist/options.d.ts +37 -2
  285. package/build/types/types-hoist/options.d.ts.map +1 -1
  286. package/build/types/types-hoist/span.d.ts +5 -0
  287. package/build/types/types-hoist/span.d.ts.map +1 -1
  288. package/build/types/types-hoist/webfetchapi.d.ts +2 -0
  289. package/build/types/types-hoist/webfetchapi.d.ts.map +1 -1
  290. package/build/types/utils/baggage.d.ts +13 -0
  291. package/build/types/utils/baggage.d.ts.map +1 -1
  292. package/build/types/utils/get-default-export.d.ts +22 -0
  293. package/build/types/utils/get-default-export.d.ts.map +1 -0
  294. package/build/types/utils/normalizationHints.d.ts +9 -0
  295. package/build/types/utils/normalizationHints.d.ts.map +1 -0
  296. package/build/types/utils/normalize.d.ts.map +1 -1
  297. package/build/types/utils/object.d.ts +1 -1
  298. package/build/types/utils/object.d.ts.map +1 -1
  299. package/build/types/utils/request.d.ts +30 -0
  300. package/build/types/utils/request.d.ts.map +1 -1
  301. package/build/types/utils/should-ignore-span.d.ts +3 -1
  302. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  303. package/build/types/utils/spanUtils.d.ts +1 -1
  304. package/build/types-ts3.8/client.d.ts +12 -1
  305. package/build/types-ts3.8/index.d.ts +17 -6
  306. package/build/types-ts3.8/instrument/console.d.ts +2 -1
  307. package/build/types-ts3.8/instrument/fetch.d.ts +4 -2
  308. package/build/types-ts3.8/instrument/handlers.d.ts +2 -2
  309. package/build/types-ts3.8/integrations/express/utils.d.ts +1 -5
  310. package/build/types-ts3.8/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  311. package/build/types-ts3.8/integrations/http/client-patch.d.ts +46 -0
  312. package/build/types-ts3.8/integrations/http/client-subscriptions.d.ts +21 -0
  313. package/build/types-ts3.8/integrations/http/constants.d.ts +6 -0
  314. package/build/types-ts3.8/integrations/http/double-wrap-warning.d.ts +4 -0
  315. package/build/types-ts3.8/integrations/http/get-outgoing-span-data.d.ts +13 -0
  316. package/build/types-ts3.8/integrations/http/get-request-url.d.ts +10 -0
  317. package/build/types-ts3.8/integrations/http/index.d.ts +4 -0
  318. package/build/types-ts3.8/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  319. package/build/types-ts3.8/integrations/http/types.d.ts +252 -0
  320. package/build/types-ts3.8/logs/envelope.d.ts +5 -2
  321. package/build/types-ts3.8/metrics/envelope.d.ts +5 -2
  322. package/build/types-ts3.8/server-runtime-client.d.ts +5 -0
  323. package/build/types-ts3.8/tracing/index.d.ts +1 -1
  324. package/build/types-ts3.8/tracing/langchain/types.d.ts +8 -0
  325. package/build/types-ts3.8/tracing/langchain/utils.d.ts +2 -0
  326. package/build/types-ts3.8/tracing/langgraph/index.d.ts +4 -0
  327. package/build/types-ts3.8/tracing/langgraph/utils.d.ts +18 -2
  328. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +13 -3
  329. package/build/types-ts3.8/tracing/trace.d.ts +1 -0
  330. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  331. package/build/types-ts3.8/tracing/vercel-ai/index.d.ts +9 -0
  332. package/build/types-ts3.8/types-hoist/feedback/config.d.ts +20 -0
  333. package/build/types-ts3.8/types-hoist/feedback/index.d.ts +2 -2
  334. package/build/types-ts3.8/types-hoist/feedback/sendFeedback.d.ts +3 -0
  335. package/build/types-ts3.8/types-hoist/log.d.ts +5 -0
  336. package/build/types-ts3.8/types-hoist/metric.d.ts +5 -0
  337. package/build/types-ts3.8/types-hoist/options.d.ts +37 -2
  338. package/build/types-ts3.8/types-hoist/span.d.ts +5 -0
  339. package/build/types-ts3.8/types-hoist/webfetchapi.d.ts +2 -0
  340. package/build/types-ts3.8/utils/baggage.d.ts +13 -0
  341. package/build/types-ts3.8/utils/get-default-export.d.ts +22 -0
  342. package/build/types-ts3.8/utils/normalizationHints.d.ts +9 -0
  343. package/build/types-ts3.8/utils/object.d.ts +1 -1
  344. package/build/types-ts3.8/utils/request.d.ts +30 -0
  345. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -1
  346. package/build/types-ts3.8/utils/spanUtils.d.ts +1 -1
  347. package/package.json +1 -1
@@ -1,7 +1,147 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const _exports = require('../../exports.js');
4
+ const semanticAttributes = require('../../semanticAttributes.js');
5
+ const spanstatus = require('../spanstatus.js');
6
+ const trace = require('../trace.js');
3
7
  const genAiAttributes = require('../ai/gen-ai-attributes.js');
4
8
  const utils = require('../langchain/utils.js');
9
+ const constants = require('./constants.js');
10
+
11
+ /**
12
+ * Extract LLM model object from createReactAgent params
13
+ */
14
+ function extractLLMFromParams(args) {
15
+ const arg = args[0];
16
+ if (typeof arg !== 'object' || !arg || !('llm' in arg) || !arg.llm || typeof arg.llm !== 'object') {
17
+ return null;
18
+ }
19
+ const llm = arg.llm ;
20
+ if (typeof llm.modelName !== 'string' && typeof llm.model !== 'string') {
21
+ return null;
22
+ }
23
+ return llm;
24
+ }
25
+
26
+ /**
27
+ * Extract agent name from createReactAgent params
28
+ */
29
+ function extractAgentNameFromParams(args) {
30
+ const arg = args[0];
31
+ if (typeof arg === 'object' && !!arg && 'name' in arg && typeof arg.name === 'string') {
32
+ return arg.name;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ /**
38
+ * Wraps an array of LangChain tools so each invocation creates a gen_ai.execute_tool span.
39
+ *
40
+ * Wraps each tool's invoke() method in place. A marker prevents double-wrapping.
41
+ */
42
+ function wrapToolsWithSpans(tools, options, agentName) {
43
+ const SENTRY_WRAPPED = '__sentry_tool_wrapped__';
44
+
45
+ for (const tool of tools) {
46
+ if (!tool || typeof tool !== 'object') {
47
+ continue;
48
+ }
49
+
50
+ const t = tool ;
51
+ const originalInvoke = t.invoke;
52
+ if (typeof originalInvoke !== 'function' || Object.prototype.hasOwnProperty.call(t, SENTRY_WRAPPED)) {
53
+ continue;
54
+ }
55
+
56
+ const toolName = typeof t.name === 'string' ? t.name : 'unknown_tool';
57
+ const toolDescription = typeof t.description === 'string' ? t.description : undefined;
58
+
59
+ const wrappedInvoke = new Proxy(originalInvoke , {
60
+ apply(target, thisArg, args) {
61
+ const spanAttributes = {
62
+ [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: constants.LANGGRAPH_ORIGIN,
63
+ [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: genAiAttributes.GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE,
64
+ [genAiAttributes.GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'execute_tool',
65
+ [genAiAttributes.GEN_AI_TOOL_NAME_ATTRIBUTE]: toolName,
66
+ [genAiAttributes.GEN_AI_TOOL_TYPE_ATTRIBUTE]: 'function',
67
+ };
68
+
69
+ // Read agent name from LangChain's propagated config metadata at call time,
70
+ // so shared tools get the correct agent name for each invocation
71
+ const callConfig = args[1] ;
72
+ const callAgentName = (callConfig?.metadata )?.lc_agent_name ?? agentName;
73
+ if (typeof callAgentName === 'string') {
74
+ spanAttributes[genAiAttributes.GEN_AI_AGENT_NAME_ATTRIBUTE] = callAgentName;
75
+ }
76
+
77
+ if (toolDescription) {
78
+ spanAttributes[genAiAttributes.GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE] = toolDescription;
79
+ }
80
+
81
+ // LangGraph ToolNode passes { name, args, id, type: "tool_call" }
82
+ const input = args[0] ;
83
+ if (typeof input === 'object' && !!input) {
84
+ if ('id' in input && typeof input.id === 'string') {
85
+ spanAttributes[genAiAttributes.GEN_AI_TOOL_CALL_ID_ATTRIBUTE] = input.id;
86
+ }
87
+
88
+ if (options.recordInputs) {
89
+ const toolArgs = 'args' in input && typeof input.args === 'object' ? input.args : input;
90
+ try {
91
+ spanAttributes[genAiAttributes.GEN_AI_TOOL_INPUT_ATTRIBUTE] = JSON.stringify(toolArgs);
92
+ } catch {
93
+ // skip if not serializable
94
+ }
95
+ }
96
+ }
97
+
98
+ return trace.startSpan(
99
+ {
100
+ op: genAiAttributes.GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE,
101
+ name: `execute_tool ${toolName}`,
102
+ attributes: spanAttributes,
103
+ },
104
+ async span => {
105
+ try {
106
+ const result = await Reflect.apply(target, thisArg, args);
107
+
108
+ if (options.recordOutputs) {
109
+ try {
110
+ // ToolMessage objects wrap the result in .content
111
+ const resultObj = result ;
112
+ const content =
113
+ resultObj && typeof resultObj === 'object' && 'content' in resultObj ? resultObj.content : result;
114
+ span.setAttribute(
115
+ genAiAttributes.GEN_AI_TOOL_OUTPUT_ATTRIBUTE,
116
+ typeof content === 'string' ? content : JSON.stringify(content),
117
+ );
118
+ } catch {
119
+ // skip if not serializable
120
+ }
121
+ }
122
+
123
+ return result;
124
+ } catch (error) {
125
+ span.setStatus({ code: spanstatus.SPAN_STATUS_ERROR, message: 'internal_error' });
126
+ _exports.captureException(error, {
127
+ mechanism: {
128
+ handled: false,
129
+ type: 'auto.ai.langgraph.error',
130
+ },
131
+ });
132
+ throw error;
133
+ }
134
+ },
135
+ );
136
+ },
137
+ });
138
+
139
+ t.invoke = wrappedInvoke;
140
+ Object.defineProperty(t, SENTRY_WRAPPED, { value: true, enumerable: false });
141
+ }
142
+
143
+ return tools;
144
+ }
5
145
 
6
146
  /**
7
147
  * Extract tool calls from messages
@@ -175,9 +315,37 @@ function setResponseAttributes(span, inputMessages, result) {
175
315
  }
176
316
  }
177
317
 
318
+ /** Merge `sentryHandler` into a langchain `callbacks` value (`BaseCallbackHandler[]` or `BaseCallbackManager`). */
319
+ function mergeSentryCallback(existing, sentryHandler) {
320
+ if (!existing) {
321
+ return [sentryHandler];
322
+ }
323
+
324
+ if (Array.isArray(existing)) {
325
+ if (existing.includes(sentryHandler)) {
326
+ return existing;
327
+ }
328
+ return [...existing, sentryHandler];
329
+ }
330
+
331
+ const manager = existing ;
332
+ if (typeof manager.addHandler === 'function') {
333
+ const alreadyAdded = Array.isArray(manager.handlers) && manager.handlers.includes(sentryHandler);
334
+ if (!alreadyAdded) {
335
+ manager.addHandler(sentryHandler);
336
+ }
337
+ }
338
+
339
+ return existing;
340
+ }
341
+
342
+ exports.extractAgentNameFromParams = extractAgentNameFromParams;
343
+ exports.extractLLMFromParams = extractLLMFromParams;
178
344
  exports.extractModelMetadata = extractModelMetadata;
179
345
  exports.extractTokenUsageFromMessage = extractTokenUsageFromMessage;
180
346
  exports.extractToolCalls = extractToolCalls;
181
347
  exports.extractToolsFromCompiledGraph = extractToolsFromCompiledGraph;
348
+ exports.mergeSentryCallback = mergeSentryCallback;
182
349
  exports.setResponseAttributes = setResponseAttributes;
350
+ exports.wrapToolsWithSpans = wrapToolsWithSpans;
183
351
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../../src/tracing/langgraph/utils.ts"],"sourcesContent":["import type { Span } from '../../types-hoist/span';\nimport {\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { LangChainMessage } from '../langchain/types';\nimport { normalizeLangChainMessages } from '../langchain/utils';\nimport type { CompiledGraph, LangGraphTool } from './types';\n\n/**\n * Extract tool calls from messages\n */\nexport function extractToolCalls(messages: Array<Record<string, unknown>> | null): unknown[] | null {\n if (!messages || messages.length === 0) {\n return null;\n }\n\n const toolCalls: unknown[] = [];\n\n for (const message of messages) {\n if (message && typeof message === 'object') {\n const msgToolCalls = message.tool_calls;\n if (msgToolCalls && Array.isArray(msgToolCalls)) {\n toolCalls.push(...msgToolCalls);\n }\n }\n }\n\n return toolCalls.length > 0 ? toolCalls : null;\n}\n\n/**\n * Extract token usage from a message's usage_metadata or response_metadata\n * Returns token counts without setting span attributes\n */\nexport function extractTokenUsageFromMessage(message: LangChainMessage): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n} {\n const msg = message as Record<string, unknown>;\n let inputTokens = 0;\n let outputTokens = 0;\n let totalTokens = 0;\n\n // Extract from usage_metadata (newer format)\n if (msg.usage_metadata && typeof msg.usage_metadata === 'object') {\n const usage = msg.usage_metadata as Record<string, unknown>;\n if (typeof usage.input_tokens === 'number') {\n inputTokens = usage.input_tokens;\n }\n if (typeof usage.output_tokens === 'number') {\n outputTokens = usage.output_tokens;\n }\n if (typeof usage.total_tokens === 'number') {\n totalTokens = usage.total_tokens;\n }\n return { inputTokens, outputTokens, totalTokens };\n }\n\n // Fallback: Extract from response_metadata.tokenUsage\n if (msg.response_metadata && typeof msg.response_metadata === 'object') {\n const metadata = msg.response_metadata as Record<string, unknown>;\n if (metadata.tokenUsage && typeof metadata.tokenUsage === 'object') {\n const tokenUsage = metadata.tokenUsage as Record<string, unknown>;\n if (typeof tokenUsage.promptTokens === 'number') {\n inputTokens = tokenUsage.promptTokens;\n }\n if (typeof tokenUsage.completionTokens === 'number') {\n outputTokens = tokenUsage.completionTokens;\n }\n if (typeof tokenUsage.totalTokens === 'number') {\n totalTokens = tokenUsage.totalTokens;\n }\n }\n }\n\n return { inputTokens, outputTokens, totalTokens };\n}\n\n/**\n * Extract model and finish reason from a message's response_metadata\n */\nexport function extractModelMetadata(span: Span, message: LangChainMessage): void {\n const msg = message as Record<string, unknown>;\n\n if (msg.response_metadata && typeof msg.response_metadata === 'object') {\n const metadata = msg.response_metadata as Record<string, unknown>;\n\n if (metadata.model_name && typeof metadata.model_name === 'string') {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, metadata.model_name);\n }\n\n if (metadata.finish_reason && typeof metadata.finish_reason === 'string') {\n span.setAttribute(GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, [metadata.finish_reason]);\n }\n }\n}\n\n/**\n * Extract tools from compiled graph structure\n *\n * Tools are stored in: compiledGraph.builder.nodes.tools.runnable.tools\n */\nexport function extractToolsFromCompiledGraph(compiledGraph: CompiledGraph): unknown[] | null {\n if (!compiledGraph.builder?.nodes?.tools?.runnable?.tools) {\n return null;\n }\n\n const tools = compiledGraph.builder?.nodes?.tools?.runnable?.tools;\n\n if (!tools || !Array.isArray(tools) || tools.length === 0) {\n return null;\n }\n\n // Extract name, description, and schema from each tool's lc_kwargs\n return tools.map((tool: LangGraphTool) => ({\n name: tool.lc_kwargs?.name,\n description: tool.lc_kwargs?.description,\n schema: tool.lc_kwargs?.schema,\n }));\n}\n\n/**\n * Set response attributes on the span\n */\nexport function setResponseAttributes(span: Span, inputMessages: LangChainMessage[] | null, result: unknown): void {\n // Extract messages from result\n const resultObj = result as { messages?: LangChainMessage[] } | undefined;\n const outputMessages = resultObj?.messages;\n\n if (!outputMessages || !Array.isArray(outputMessages)) {\n return;\n }\n\n // Get new messages (delta between input and output)\n const inputCount = inputMessages?.length ?? 0;\n const newMessages = outputMessages.length > inputCount ? outputMessages.slice(inputCount) : [];\n\n if (newMessages.length === 0) {\n return;\n }\n\n // Extract and set tool calls from new messages BEFORE normalization\n // (normalization strips tool_calls, so we need to extract them first)\n const toolCalls = extractToolCalls(newMessages as Array<Record<string, unknown>>);\n if (toolCalls) {\n span.setAttribute(GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, JSON.stringify(toolCalls));\n }\n\n // Normalize the new messages\n const normalizedNewMessages = normalizeLangChainMessages(newMessages);\n span.setAttribute(GEN_AI_RESPONSE_TEXT_ATTRIBUTE, JSON.stringify(normalizedNewMessages));\n\n // Accumulate token usage across all messages\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let totalTokens = 0;\n\n // Extract metadata from messages\n for (const message of newMessages) {\n // Accumulate token usage\n const tokens = extractTokenUsageFromMessage(message);\n totalInputTokens += tokens.inputTokens;\n totalOutputTokens += tokens.outputTokens;\n totalTokens += tokens.totalTokens;\n\n // Extract model metadata (last message's metadata wins for model/finish_reason)\n extractModelMetadata(span, message);\n }\n\n // Set accumulated token usage on span\n if (totalInputTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, totalInputTokens);\n }\n if (totalOutputTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, totalOutputTokens);\n }\n if (totalTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, totalTokens);\n }\n}\n"],"names":["GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","normalizeLangChainMessages","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/tracing/langgraph/utils.ts"],"sourcesContent":["import { captureException } from '../../exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span, SpanAttributes } from '../../types-hoist/span';\nimport {\n GEN_AI_AGENT_NAME_ATTRIBUTE,\n GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_TEXT_ATTRIBUTE,\n GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport type { BaseChatModel, LangChainMessage } from '../langchain/types';\nimport { normalizeLangChainMessages } from '../langchain/utils';\nimport { startSpan } from '../trace';\nimport { LANGGRAPH_ORIGIN } from './constants';\nimport type { CompiledGraph, LangGraphOptions, LangGraphTool } from './types';\n\n/**\n * Extract LLM model object from createReactAgent params\n */\nexport function extractLLMFromParams(args: unknown[]): BaseChatModel | null {\n const arg = args[0];\n if (typeof arg !== 'object' || !arg || !('llm' in arg) || !arg.llm || typeof arg.llm !== 'object') {\n return null;\n }\n const llm = arg.llm as BaseChatModel;\n if (typeof llm.modelName !== 'string' && typeof llm.model !== 'string') {\n return null;\n }\n return llm;\n}\n\n/**\n * Extract agent name from createReactAgent params\n */\nexport function extractAgentNameFromParams(args: unknown[]): string | null {\n const arg = args[0];\n if (typeof arg === 'object' && !!arg && 'name' in arg && typeof arg.name === 'string') {\n return arg.name;\n }\n return null;\n}\n\n/**\n * Wraps an array of LangChain tools so each invocation creates a gen_ai.execute_tool span.\n *\n * Wraps each tool's invoke() method in place. A marker prevents double-wrapping.\n */\nexport function wrapToolsWithSpans(tools: unknown[], options: LangGraphOptions, agentName?: string): unknown[] {\n const SENTRY_WRAPPED = '__sentry_tool_wrapped__';\n\n for (const tool of tools) {\n if (!tool || typeof tool !== 'object') {\n continue;\n }\n\n const t = tool as Record<string, unknown>;\n const originalInvoke = t.invoke;\n if (typeof originalInvoke !== 'function' || Object.prototype.hasOwnProperty.call(t, SENTRY_WRAPPED)) {\n continue;\n }\n\n const toolName = typeof t.name === 'string' ? t.name : 'unknown_tool';\n const toolDescription = typeof t.description === 'string' ? t.description : undefined;\n\n const wrappedInvoke = new Proxy(originalInvoke as (...args: unknown[]) => unknown, {\n apply(target, thisArg, args: unknown[]): unknown {\n const spanAttributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: LANGGRAPH_ORIGIN,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE,\n [GEN_AI_OPERATION_NAME_ATTRIBUTE]: 'execute_tool',\n [GEN_AI_TOOL_NAME_ATTRIBUTE]: toolName,\n [GEN_AI_TOOL_TYPE_ATTRIBUTE]: 'function',\n };\n\n // Read agent name from LangChain's propagated config metadata at call time,\n // so shared tools get the correct agent name for each invocation\n const callConfig = args[1] as Record<string, unknown> | undefined;\n const callAgentName = (callConfig?.metadata as Record<string, unknown>)?.lc_agent_name ?? agentName;\n if (typeof callAgentName === 'string') {\n spanAttributes[GEN_AI_AGENT_NAME_ATTRIBUTE] = callAgentName;\n }\n\n if (toolDescription) {\n spanAttributes[GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE] = toolDescription;\n }\n\n // LangGraph ToolNode passes { name, args, id, type: \"tool_call\" }\n const input = args[0] as Record<string, unknown> | undefined;\n if (typeof input === 'object' && !!input) {\n if ('id' in input && typeof input.id === 'string') {\n spanAttributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE] = input.id;\n }\n\n if (options.recordInputs) {\n const toolArgs = 'args' in input && typeof input.args === 'object' ? input.args : input;\n try {\n spanAttributes[GEN_AI_TOOL_INPUT_ATTRIBUTE] = JSON.stringify(toolArgs);\n } catch {\n // skip if not serializable\n }\n }\n }\n\n return startSpan(\n {\n op: GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE,\n name: `execute_tool ${toolName}`,\n attributes: spanAttributes,\n },\n async span => {\n try {\n const result = await Reflect.apply(target, thisArg, args);\n\n if (options.recordOutputs) {\n try {\n // ToolMessage objects wrap the result in .content\n const resultObj = result as Record<string, unknown> | undefined;\n const content =\n resultObj && typeof resultObj === 'object' && 'content' in resultObj ? resultObj.content : result;\n span.setAttribute(\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n typeof content === 'string' ? content : JSON.stringify(content),\n );\n } catch {\n // skip if not serializable\n }\n }\n\n return result;\n } catch (error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureException(error, {\n mechanism: {\n handled: false,\n type: 'auto.ai.langgraph.error',\n },\n });\n throw error;\n }\n },\n );\n },\n });\n\n t.invoke = wrappedInvoke;\n Object.defineProperty(t, SENTRY_WRAPPED, { value: true, enumerable: false });\n }\n\n return tools;\n}\n\n/**\n * Extract tool calls from messages\n */\nexport function extractToolCalls(messages: Array<Record<string, unknown>> | null): unknown[] | null {\n if (!messages || messages.length === 0) {\n return null;\n }\n\n const toolCalls: unknown[] = [];\n\n for (const message of messages) {\n if (message && typeof message === 'object') {\n const msgToolCalls = message.tool_calls;\n if (msgToolCalls && Array.isArray(msgToolCalls)) {\n toolCalls.push(...msgToolCalls);\n }\n }\n }\n\n return toolCalls.length > 0 ? toolCalls : null;\n}\n\n/**\n * Extract token usage from a message's usage_metadata or response_metadata\n * Returns token counts without setting span attributes\n */\nexport function extractTokenUsageFromMessage(message: LangChainMessage): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n} {\n const msg = message as Record<string, unknown>;\n let inputTokens = 0;\n let outputTokens = 0;\n let totalTokens = 0;\n\n // Extract from usage_metadata (newer format)\n if (msg.usage_metadata && typeof msg.usage_metadata === 'object') {\n const usage = msg.usage_metadata as Record<string, unknown>;\n if (typeof usage.input_tokens === 'number') {\n inputTokens = usage.input_tokens;\n }\n if (typeof usage.output_tokens === 'number') {\n outputTokens = usage.output_tokens;\n }\n if (typeof usage.total_tokens === 'number') {\n totalTokens = usage.total_tokens;\n }\n return { inputTokens, outputTokens, totalTokens };\n }\n\n // Fallback: Extract from response_metadata.tokenUsage\n if (msg.response_metadata && typeof msg.response_metadata === 'object') {\n const metadata = msg.response_metadata as Record<string, unknown>;\n if (metadata.tokenUsage && typeof metadata.tokenUsage === 'object') {\n const tokenUsage = metadata.tokenUsage as Record<string, unknown>;\n if (typeof tokenUsage.promptTokens === 'number') {\n inputTokens = tokenUsage.promptTokens;\n }\n if (typeof tokenUsage.completionTokens === 'number') {\n outputTokens = tokenUsage.completionTokens;\n }\n if (typeof tokenUsage.totalTokens === 'number') {\n totalTokens = tokenUsage.totalTokens;\n }\n }\n }\n\n return { inputTokens, outputTokens, totalTokens };\n}\n\n/**\n * Extract model and finish reason from a message's response_metadata\n */\nexport function extractModelMetadata(span: Span, message: LangChainMessage): void {\n const msg = message as Record<string, unknown>;\n\n if (msg.response_metadata && typeof msg.response_metadata === 'object') {\n const metadata = msg.response_metadata as Record<string, unknown>;\n\n if (metadata.model_name && typeof metadata.model_name === 'string') {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, metadata.model_name);\n }\n\n if (metadata.finish_reason && typeof metadata.finish_reason === 'string') {\n span.setAttribute(GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, [metadata.finish_reason]);\n }\n }\n}\n\n/**\n * Extract tools from compiled graph structure\n *\n * Tools are stored in: compiledGraph.builder.nodes.tools.runnable.tools\n */\nexport function extractToolsFromCompiledGraph(compiledGraph: CompiledGraph): unknown[] | null {\n if (!compiledGraph.builder?.nodes?.tools?.runnable?.tools) {\n return null;\n }\n\n const tools = compiledGraph.builder?.nodes?.tools?.runnable?.tools;\n\n if (!tools || !Array.isArray(tools) || tools.length === 0) {\n return null;\n }\n\n // Extract name, description, and schema from each tool's lc_kwargs\n return tools.map((tool: LangGraphTool) => ({\n name: tool.lc_kwargs?.name,\n description: tool.lc_kwargs?.description,\n schema: tool.lc_kwargs?.schema,\n }));\n}\n\n/**\n * Set response attributes on the span\n */\nexport function setResponseAttributes(span: Span, inputMessages: LangChainMessage[] | null, result: unknown): void {\n // Extract messages from result\n const resultObj = result as { messages?: LangChainMessage[] } | undefined;\n const outputMessages = resultObj?.messages;\n\n if (!outputMessages || !Array.isArray(outputMessages)) {\n return;\n }\n\n // Get new messages (delta between input and output)\n const inputCount = inputMessages?.length ?? 0;\n const newMessages = outputMessages.length > inputCount ? outputMessages.slice(inputCount) : [];\n\n if (newMessages.length === 0) {\n return;\n }\n\n // Extract and set tool calls from new messages BEFORE normalization\n // (normalization strips tool_calls, so we need to extract them first)\n const toolCalls = extractToolCalls(newMessages as Array<Record<string, unknown>>);\n if (toolCalls) {\n span.setAttribute(GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, JSON.stringify(toolCalls));\n }\n\n // Normalize the new messages\n const normalizedNewMessages = normalizeLangChainMessages(newMessages);\n span.setAttribute(GEN_AI_RESPONSE_TEXT_ATTRIBUTE, JSON.stringify(normalizedNewMessages));\n\n // Accumulate token usage across all messages\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let totalTokens = 0;\n\n // Extract metadata from messages\n for (const message of newMessages) {\n // Accumulate token usage\n const tokens = extractTokenUsageFromMessage(message);\n totalInputTokens += tokens.inputTokens;\n totalOutputTokens += tokens.outputTokens;\n totalTokens += tokens.totalTokens;\n\n // Extract model metadata (last message's metadata wins for model/finish_reason)\n extractModelMetadata(span, message);\n }\n\n // Set accumulated token usage on span\n if (totalInputTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, totalInputTokens);\n }\n if (totalOutputTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, totalOutputTokens);\n }\n if (totalTokens > 0) {\n span.setAttribute(GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, totalTokens);\n }\n}\n\n/** Merge `sentryHandler` into a langchain `callbacks` value (`BaseCallbackHandler[]` or `BaseCallbackManager`). */\nexport function mergeSentryCallback(existing: unknown, sentryHandler: unknown): unknown {\n if (!existing) {\n return [sentryHandler];\n }\n\n if (Array.isArray(existing)) {\n if (existing.includes(sentryHandler)) {\n return existing;\n }\n return [...existing, sentryHandler];\n }\n\n const manager = existing as { addHandler?: (h: unknown) => void; handlers?: unknown[] };\n if (typeof manager.addHandler === 'function') {\n const alreadyAdded = Array.isArray(manager.handlers) && manager.handlers.includes(sentryHandler);\n if (!alreadyAdded) {\n manager.addHandler(sentryHandler);\n }\n }\n\n return existing;\n}\n"],"names":["SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","LANGGRAPH_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE","GEN_AI_OPERATION_NAME_ATTRIBUTE","GEN_AI_TOOL_NAME_ATTRIBUTE","GEN_AI_TOOL_TYPE_ATTRIBUTE","GEN_AI_AGENT_NAME_ATTRIBUTE","GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE","GEN_AI_TOOL_CALL_ID_ATTRIBUTE","GEN_AI_TOOL_INPUT_ATTRIBUTE","startSpan","GEN_AI_TOOL_OUTPUT_ATTRIBUTE","SPAN_STATUS_ERROR","captureException","GEN_AI_RESPONSE_MODEL_ATTRIBUTE","GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE","GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE","normalizeLangChainMessages","GEN_AI_RESPONSE_TEXT_ATTRIBUTE","GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE","GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE"],"mappings":"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"}
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const semanticAttributes = require('../../semanticAttributes.js');
4
4
  const scopeData = require('../../utils/scopeData.js');
5
+ const url = require('../../utils/url.js');
5
6
  const spanUtils = require('../../utils/spanUtils.js');
6
7
  const utils = require('../utils.js');
7
8
  const beforeSendSpan = require('./beforeSendSpan.js');
@@ -28,6 +29,14 @@ function captureSpan(span, client) {
28
29
 
29
30
  applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData);
30
31
 
32
+ // Backfill span data from OTel semantic conventions when not explicitly set.
33
+ // OTel-originated spans don't have sentry.op, description, etc. — the non-streamed path
34
+ // infers these in the SentrySpanExporter, but streamed spans skip the exporter entirely.
35
+ // Access `kind` via duck-typing — OTel span objects have this property but it's not on Sentry's Span type.
36
+ // This must run before all hooks and beforeSendSpan so that user callbacks can see and override inferred values.
37
+ const spanKind = (span ).kind;
38
+ inferSpanDataFromOtelAttributes(spanJSON, spanKind);
39
+
31
40
  if (spanJSON.is_segment) {
32
41
  // Allow hook subscribers to mutate the segment span JSON
33
42
  // This also invokes the `processSegmentSpan` hook of all integrations
@@ -61,6 +70,23 @@ function captureSpan(span, client) {
61
70
  };
62
71
  }
63
72
 
73
+ /**
74
+ * Safely set attributes on a span JSON.
75
+ * If an attribute already exists, it will not be overwritten.
76
+ */
77
+ function safeSetSpanJSONAttributes(
78
+ spanJSON,
79
+ newAttributes,
80
+ ) {
81
+ const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});
82
+
83
+ Object.entries(newAttributes).forEach(([key, value]) => {
84
+ if (value != null && !(key in originalAttributes)) {
85
+ originalAttributes[key] = value;
86
+ }
87
+ });
88
+ }
89
+
64
90
  function applyCommonSpanAttributes(
65
91
  spanJSON,
66
92
  serializedSegmentSpan,
@@ -105,24 +131,158 @@ function applyBeforeSendSpanCallback(
105
131
  return modifedSpan;
106
132
  }
107
133
 
134
+ // OTel SpanKind values (numeric to avoid importing from @opentelemetry/api)
135
+ const SPAN_KIND_SERVER = 1;
136
+ const SPAN_KIND_CLIENT = 2;
137
+
108
138
  /**
109
- * Safely set attributes on a span JSON.
110
- * If an attribute already exists, it will not be overwritten.
139
+ * Infer and backfill span data from OTel semantic conventions.
140
+ * This mirrors what the `SentrySpanExporter` does for non-streamed spans via `getSpanData`/`inferSpanData`.
141
+ * Streamed spans skip the exporter, so we do the inference here during capture.
142
+ *
143
+ * Backfills: `sentry.op`, `sentry.source`, and `name` (description).
144
+ * Uses `safeSetSpanJSONAttributes` so explicitly set attributes are never overwritten.
111
145
  */
112
- function safeSetSpanJSONAttributes(
146
+ /** Exported only for tests. */
147
+ function inferSpanDataFromOtelAttributes(spanJSON, spanKind) {
148
+ const attributes = spanJSON.attributes;
149
+ if (!attributes) {
150
+ return;
151
+ }
152
+
153
+ const httpMethod = attributes['http.request.method'] || attributes['http.method'];
154
+ if (httpMethod) {
155
+ inferHttpSpanData(spanJSON, attributes, spanKind, httpMethod);
156
+ return;
157
+ }
158
+
159
+ const dbSystem = attributes['db.system.name'] || attributes['db.system'];
160
+ const opIsCache =
161
+ typeof attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'string' &&
162
+ `${attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]}`.startsWith('cache.');
163
+ if (dbSystem && !opIsCache) {
164
+ inferDbSpanData(spanJSON, attributes);
165
+ return;
166
+ }
167
+
168
+ if (attributes['rpc.service']) {
169
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'rpc' });
170
+ return;
171
+ }
172
+
173
+ if (attributes['messaging.system']) {
174
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'message' });
175
+ return;
176
+ }
177
+
178
+ const faasTrigger = attributes['faas.trigger'];
179
+ if (faasTrigger) {
180
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${faasTrigger}` });
181
+ }
182
+ }
183
+
184
+ function inferHttpSpanData(
113
185
  spanJSON,
114
- newAttributes,
186
+ attributes,
187
+ spanKind,
188
+ httpMethod,
115
189
  ) {
116
- const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});
190
+ // Infer op: http.client, http.server, or just http
191
+ const opParts = ['http'];
192
+ if (spanKind === SPAN_KIND_CLIENT) {
193
+ opParts.push('client');
194
+ } else if (spanKind === SPAN_KIND_SERVER) {
195
+ opParts.push('server');
196
+ }
197
+ if (attributes['sentry.http.prefetch']) {
198
+ opParts.push('prefetch');
199
+ }
200
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: opParts.join('.') });
117
201
 
118
- Object.entries(newAttributes).forEach(([key, value]) => {
119
- if (value != null && !(key in originalAttributes)) {
120
- originalAttributes[key] = value;
202
+ // If the user set a custom span name via updateSpanName(), apply it — OTel instrumentation
203
+ // may have overwritten span.name after the user set it, so we restore from the attribute.
204
+ const customName = attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];
205
+ if (typeof customName === 'string') {
206
+ spanJSON.name = customName;
207
+ return;
208
+ }
209
+
210
+ if (attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {
211
+ return;
212
+ }
213
+
214
+ const httpRoute = attributes['http.route'];
215
+ if (typeof httpRoute === 'string') {
216
+ spanJSON.name = `${httpMethod} ${httpRoute}`;
217
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' });
218
+ } else {
219
+ // Infer span name from URL attributes, matching the non-streamed exporter's behavior.
220
+ // Only overwrite the name for OTel spans (known spanKind)
221
+ if (spanKind === SPAN_KIND_CLIENT || spanKind === SPAN_KIND_SERVER) {
222
+ const urlPath = getUrlPath(attributes, spanKind);
223
+ if (urlPath) {
224
+ spanJSON.name = `${httpMethod} ${urlPath}`;
225
+ }
121
226
  }
122
- });
227
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' });
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Extract a URL path from span attributes for use in the span name.
233
+ * Mirrors the logic in the non-streamed exporter's `getSanitizedUrl`.
234
+ */
235
+ function getUrlPath(
236
+ attributes,
237
+ spanKind,
238
+ ) {
239
+ const httpUrl = attributes['http.url'] || attributes['url.full'];
240
+ const httpTarget = attributes['http.target'];
241
+
242
+ const parsedUrl = typeof httpUrl === 'string' ? url.parseUrl(httpUrl) : undefined;
243
+ const sanitizedUrl = parsedUrl ? url.getSanitizedUrlString(parsedUrl) : undefined;
244
+
245
+ // For server spans, prefer the relative target path
246
+ if (spanKind === SPAN_KIND_SERVER && typeof httpTarget === 'string') {
247
+ return url.stripUrlQueryAndFragment(httpTarget);
248
+ }
249
+
250
+ // For client spans (and others), use the full sanitized URL
251
+ if (sanitizedUrl) {
252
+ return sanitizedUrl;
253
+ }
254
+
255
+ // Fall back to target if no full URL is available
256
+ if (typeof httpTarget === 'string') {
257
+ return url.stripUrlQueryAndFragment(httpTarget);
258
+ }
259
+
260
+ return undefined;
261
+ }
262
+
263
+ function inferDbSpanData(spanJSON, attributes) {
264
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' });
265
+
266
+ // If the user set a custom span name via updateSpanName(), apply it.
267
+ const customName = attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];
268
+ if (typeof customName === 'string') {
269
+ spanJSON.name = customName;
270
+ return;
271
+ }
272
+
273
+ if (attributes[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {
274
+ return;
275
+ }
276
+
277
+ const statement = attributes['db.statement'];
278
+ if (statement) {
279
+ spanJSON.name = `${statement}`;
280
+ safeSetSpanJSONAttributes(spanJSON, { [semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' });
281
+ }
123
282
  }
124
283
 
125
284
  exports.applyBeforeSendSpanCallback = applyBeforeSendSpanCallback;
126
285
  exports.captureSpan = captureSpan;
286
+ exports.inferSpanDataFromOtelAttributes = inferSpanDataFromOtelAttributes;
127
287
  exports.safeSetSpanJSONAttributes = safeSetSpanJSONAttributes;
128
288
  //# sourceMappingURL=captureSpan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"captureSpan.js","sources":["../../../../src/tracing/spans/captureSpan.ts"],"sourcesContent":["import type { RawAttributes } from '../../attributes';\nimport type { Client } from '../../client';\nimport type { ScopeData } from '../../scope';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,\n SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SEMANTIC_ATTRIBUTE_USER_EMAIL,\n SEMANTIC_ATTRIBUTE_USER_ID,\n SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,\n SEMANTIC_ATTRIBUTE_USER_USERNAME,\n} from '../../semanticAttributes';\nimport type { SerializedStreamedSpan, Span, StreamedSpanJSON } from '../../types-hoist/span';\nimport { getCombinedScopeData } from '../../utils/scopeData';\nimport {\n INTERNAL_getSegmentSpan,\n showSpanDropWarning,\n spanToStreamedSpanJSON,\n streamedSpanJsonToSerializedSpan,\n} from '../../utils/spanUtils';\nimport { getCapturedScopesOnSpan } from '../utils';\nimport { isStreamedBeforeSendSpanCallback } from './beforeSendSpan';\n\nexport type SerializedStreamedSpanWithSegmentSpan = SerializedStreamedSpan & {\n _segmentSpan: Span;\n};\n\n/**\n * Captures a span and returns a JSON representation to be enqueued for sending.\n *\n * IMPORTANT: This function converts the span to JSON immediately to avoid writing\n * to an already-ended OTel span instance (which is blocked by the OTel Span class).\n *\n * @returns the final serialized span with a reference to its segment span. This reference\n * is needed later on to compute the DSC for the span envelope.\n */\nexport function captureSpan(span: Span, client: Client): SerializedStreamedSpanWithSegmentSpan {\n // Convert to JSON FIRST - we cannot write to an already-ended span\n const spanJSON = spanToStreamedSpanJSON(span);\n\n const segmentSpan = INTERNAL_getSegmentSpan(span);\n const serializedSegmentSpan = spanToStreamedSpanJSON(segmentSpan);\n\n const { isolationScope: spanIsolationScope, scope: spanScope } = getCapturedScopesOnSpan(span);\n\n const finalScopeData = getCombinedScopeData(spanIsolationScope, spanScope);\n\n applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData);\n\n if (spanJSON.is_segment) {\n applyScopeToSegmentSpan(spanJSON, finalScopeData);\n // Allow hook subscribers to mutate the segment span JSON\n // This also invokes the `processSegmentSpan` hook of all integrations\n client.emit('processSegmentSpan', spanJSON);\n }\n\n // This allows hook subscribers to mutate the span JSON\n // This also invokes the `processSpan` hook of all integrations\n client.emit('processSpan', spanJSON);\n\n const { beforeSendSpan } = client.getOptions();\n const processedSpan =\n beforeSendSpan && isStreamedBeforeSendSpanCallback(beforeSendSpan)\n ? applyBeforeSendSpanCallback(spanJSON, beforeSendSpan)\n : spanJSON;\n\n // Backfill sentry.span.source from sentry.source. Only `sentry.span.source` is respected by Sentry.\n // TODO(v11): Remove this backfill once we renamed SEMANTIC_ATTRIBUTE_SENTRY_SOURCE to sentry.span.source\n const spanNameSource = processedSpan.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n if (spanNameSource) {\n safeSetSpanJSONAttributes(processedSpan, {\n // Purposefully not using a constant defined here like in other attributes:\n // This will be the name for SEMANTIC_ATTRIBUTE_SENTRY_SOURCE in v11\n 'sentry.span.source': spanNameSource,\n });\n }\n\n return {\n ...streamedSpanJsonToSerializedSpan(processedSpan),\n _segmentSpan: segmentSpan,\n };\n}\n\nfunction applyScopeToSegmentSpan(_segmentSpanJSON: StreamedSpanJSON, _scopeData: ScopeData): void {\n // TODO: Apply all scope and request data from auto instrumentation (contexts, request) to segment span\n // This will follow in a separate PR\n}\n\nfunction applyCommonSpanAttributes(\n spanJSON: StreamedSpanJSON,\n serializedSegmentSpan: StreamedSpanJSON,\n client: Client,\n scopeData: ScopeData,\n): void {\n const sdk = client.getSdkMetadata();\n const { release, environment, sendDefaultPii } = client.getOptions();\n\n // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation)\n safeSetSpanJSONAttributes(spanJSON, {\n [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release,\n [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: serializedSegmentSpan.span_id,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: sdk?.sdk?.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: sdk?.sdk?.version,\n ...(sendDefaultPii\n ? {\n [SEMANTIC_ATTRIBUTE_USER_ID]: scopeData.user?.id,\n [SEMANTIC_ATTRIBUTE_USER_EMAIL]: scopeData.user?.email,\n [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: scopeData.user?.ip_address,\n [SEMANTIC_ATTRIBUTE_USER_USERNAME]: scopeData.user?.username,\n }\n : {}),\n ...scopeData.attributes,\n });\n}\n\n/**\n * Apply a user-provided beforeSendSpan callback to a span JSON.\n */\nexport function applyBeforeSendSpanCallback(\n span: StreamedSpanJSON,\n beforeSendSpan: (span: StreamedSpanJSON) => StreamedSpanJSON,\n): StreamedSpanJSON {\n const modifedSpan = beforeSendSpan(span);\n if (!modifedSpan) {\n showSpanDropWarning();\n return span;\n }\n return modifedSpan;\n}\n\n/**\n * Safely set attributes on a span JSON.\n * If an attribute already exists, it will not be overwritten.\n */\nexport function safeSetSpanJSONAttributes(\n spanJSON: StreamedSpanJSON,\n newAttributes: RawAttributes<Record<string, unknown>>,\n): void {\n const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});\n\n Object.entries(newAttributes).forEach(([key, value]) => {\n if (value != null && !(key in originalAttributes)) {\n originalAttributes[key] = value;\n }\n });\n}\n"],"names":["spanToStreamedSpanJSON","INTERNAL_getSegmentSpan","getCapturedScopesOnSpan","getCombinedScopeData","beforeSendSpan","isStreamedBeforeSendSpanCallback","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","streamedSpanJsonToSerializedSpan","SEMANTIC_ATTRIBUTE_SENTRY_RELEASE","SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID","SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION","SEMANTIC_ATTRIBUTE_USER_ID","SEMANTIC_ATTRIBUTE_USER_EMAIL","SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS","SEMANTIC_ATTRIBUTE_USER_USERNAME","showSpanDropWarning"],"mappings":"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"}
1
+ {"version":3,"file":"captureSpan.js","sources":["../../../../src/tracing/spans/captureSpan.ts"],"sourcesContent":["import type { RawAttributes } from '../../attributes';\nimport type { Client } from '../../client';\nimport type { ScopeData } from '../../scope';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,\n SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SEMANTIC_ATTRIBUTE_USER_EMAIL,\n SEMANTIC_ATTRIBUTE_USER_ID,\n SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,\n SEMANTIC_ATTRIBUTE_USER_USERNAME,\n} from '../../semanticAttributes';\nimport type { SerializedStreamedSpan, Span, StreamedSpanJSON } from '../../types-hoist/span';\nimport { getCombinedScopeData } from '../../utils/scopeData';\nimport { getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from '../../utils/url';\nimport {\n INTERNAL_getSegmentSpan,\n showSpanDropWarning,\n spanToStreamedSpanJSON,\n streamedSpanJsonToSerializedSpan,\n} from '../../utils/spanUtils';\nimport { getCapturedScopesOnSpan } from '../utils';\nimport { isStreamedBeforeSendSpanCallback } from './beforeSendSpan';\n\nexport type SerializedStreamedSpanWithSegmentSpan = SerializedStreamedSpan & {\n _segmentSpan: Span;\n};\n\n/**\n * Captures a span and returns a JSON representation to be enqueued for sending.\n *\n * IMPORTANT: This function converts the span to JSON immediately to avoid writing\n * to an already-ended OTel span instance (which is blocked by the OTel Span class).\n *\n * @returns the final serialized span with a reference to its segment span. This reference\n * is needed later on to compute the DSC for the span envelope.\n */\nexport function captureSpan(span: Span, client: Client): SerializedStreamedSpanWithSegmentSpan {\n // Convert to JSON FIRST - we cannot write to an already-ended span\n const spanJSON = spanToStreamedSpanJSON(span);\n\n const segmentSpan = INTERNAL_getSegmentSpan(span);\n const serializedSegmentSpan = spanToStreamedSpanJSON(segmentSpan);\n\n const { isolationScope: spanIsolationScope, scope: spanScope } = getCapturedScopesOnSpan(span);\n\n const finalScopeData = getCombinedScopeData(spanIsolationScope, spanScope);\n\n applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData);\n\n // Backfill span data from OTel semantic conventions when not explicitly set.\n // OTel-originated spans don't have sentry.op, description, etc. — the non-streamed path\n // infers these in the SentrySpanExporter, but streamed spans skip the exporter entirely.\n // Access `kind` via duck-typing — OTel span objects have this property but it's not on Sentry's Span type.\n // This must run before all hooks and beforeSendSpan so that user callbacks can see and override inferred values.\n const spanKind = (span as { kind?: number }).kind;\n inferSpanDataFromOtelAttributes(spanJSON, spanKind);\n\n if (spanJSON.is_segment) {\n applyScopeToSegmentSpan(spanJSON, finalScopeData);\n // Allow hook subscribers to mutate the segment span JSON\n // This also invokes the `processSegmentSpan` hook of all integrations\n client.emit('processSegmentSpan', spanJSON);\n }\n\n // This allows hook subscribers to mutate the span JSON\n // This also invokes the `processSpan` hook of all integrations\n client.emit('processSpan', spanJSON);\n\n const { beforeSendSpan } = client.getOptions();\n const processedSpan =\n beforeSendSpan && isStreamedBeforeSendSpanCallback(beforeSendSpan)\n ? applyBeforeSendSpanCallback(spanJSON, beforeSendSpan)\n : spanJSON;\n\n // Backfill sentry.span.source from sentry.source. Only `sentry.span.source` is respected by Sentry.\n // TODO(v11): Remove this backfill once we renamed SEMANTIC_ATTRIBUTE_SENTRY_SOURCE to sentry.span.source\n const spanNameSource = processedSpan.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n if (spanNameSource) {\n safeSetSpanJSONAttributes(processedSpan, {\n // Purposefully not using a constant defined here like in other attributes:\n // This will be the name for SEMANTIC_ATTRIBUTE_SENTRY_SOURCE in v11\n 'sentry.span.source': spanNameSource,\n });\n }\n\n return {\n ...streamedSpanJsonToSerializedSpan(processedSpan),\n _segmentSpan: segmentSpan,\n };\n}\n\nfunction applyScopeToSegmentSpan(_segmentSpanJSON: StreamedSpanJSON, _scopeData: ScopeData): void {\n // TODO: Apply contexts data from auto instrumentation to segment span\n // This will follow in a separate PR\n}\n\n/**\n * Safely set attributes on a span JSON.\n * If an attribute already exists, it will not be overwritten.\n */\nexport function safeSetSpanJSONAttributes(\n spanJSON: StreamedSpanJSON,\n newAttributes: RawAttributes<Record<string, unknown>>,\n): void {\n const originalAttributes = spanJSON.attributes ?? (spanJSON.attributes = {});\n\n Object.entries(newAttributes).forEach(([key, value]) => {\n if (value != null && !(key in originalAttributes)) {\n originalAttributes[key] = value;\n }\n });\n}\n\nfunction applyCommonSpanAttributes(\n spanJSON: StreamedSpanJSON,\n serializedSegmentSpan: StreamedSpanJSON,\n client: Client,\n scopeData: ScopeData,\n): void {\n const sdk = client.getSdkMetadata();\n const { release, environment, sendDefaultPii } = client.getOptions();\n\n // avoid overwriting any previously set attributes (from users or potentially our SDK instrumentation)\n safeSetSpanJSONAttributes(spanJSON, {\n [SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: release,\n [SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: environment,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: serializedSegmentSpan.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: serializedSegmentSpan.span_id,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: sdk?.sdk?.name,\n [SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: sdk?.sdk?.version,\n ...(sendDefaultPii\n ? {\n [SEMANTIC_ATTRIBUTE_USER_ID]: scopeData.user?.id,\n [SEMANTIC_ATTRIBUTE_USER_EMAIL]: scopeData.user?.email,\n [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: scopeData.user?.ip_address,\n [SEMANTIC_ATTRIBUTE_USER_USERNAME]: scopeData.user?.username,\n }\n : {}),\n ...scopeData.attributes,\n });\n}\n\n/**\n * Apply a user-provided beforeSendSpan callback to a span JSON.\n */\nexport function applyBeforeSendSpanCallback(\n span: StreamedSpanJSON,\n beforeSendSpan: (span: StreamedSpanJSON) => StreamedSpanJSON,\n): StreamedSpanJSON {\n const modifedSpan = beforeSendSpan(span);\n if (!modifedSpan) {\n showSpanDropWarning();\n return span;\n }\n return modifedSpan;\n}\n\n// OTel SpanKind values (numeric to avoid importing from @opentelemetry/api)\nconst SPAN_KIND_SERVER = 1;\nconst SPAN_KIND_CLIENT = 2;\n\n/**\n * Infer and backfill span data from OTel semantic conventions.\n * This mirrors what the `SentrySpanExporter` does for non-streamed spans via `getSpanData`/`inferSpanData`.\n * Streamed spans skip the exporter, so we do the inference here during capture.\n *\n * Backfills: `sentry.op`, `sentry.source`, and `name` (description).\n * Uses `safeSetSpanJSONAttributes` so explicitly set attributes are never overwritten.\n */\n/** Exported only for tests. */\nexport function inferSpanDataFromOtelAttributes(spanJSON: StreamedSpanJSON, spanKind?: number): void {\n const attributes = spanJSON.attributes;\n if (!attributes) {\n return;\n }\n\n const httpMethod = attributes['http.request.method'] || attributes['http.method'];\n if (httpMethod) {\n inferHttpSpanData(spanJSON, attributes, spanKind, httpMethod);\n return;\n }\n\n const dbSystem = attributes['db.system.name'] || attributes['db.system'];\n const opIsCache =\n typeof attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === 'string' &&\n `${attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP]}`.startsWith('cache.');\n if (dbSystem && !opIsCache) {\n inferDbSpanData(spanJSON, attributes);\n return;\n }\n\n if (attributes['rpc.service']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'rpc' });\n return;\n }\n\n if (attributes['messaging.system']) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'message' });\n return;\n }\n\n const faasTrigger = attributes['faas.trigger'];\n if (faasTrigger) {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${faasTrigger}` });\n }\n}\n\nfunction inferHttpSpanData(\n spanJSON: StreamedSpanJSON,\n attributes: RawAttributes<Record<string, unknown>>,\n spanKind: number | undefined,\n httpMethod: unknown,\n): void {\n // Infer op: http.client, http.server, or just http\n const opParts = ['http'];\n if (spanKind === SPAN_KIND_CLIENT) {\n opParts.push('client');\n } else if (spanKind === SPAN_KIND_SERVER) {\n opParts.push('server');\n }\n if (attributes['sentry.http.prefetch']) {\n opParts.push('prefetch');\n }\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: opParts.join('.') });\n\n // If the user set a custom span name via updateSpanName(), apply it — OTel instrumentation\n // may have overwritten span.name after the user set it, so we restore from the attribute.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n const httpRoute = attributes['http.route'];\n if (typeof httpRoute === 'string') {\n spanJSON.name = `${httpMethod} ${httpRoute}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' });\n } else {\n // Infer span name from URL attributes, matching the non-streamed exporter's behavior.\n // Only overwrite the name for OTel spans (known spanKind)\n if (spanKind === SPAN_KIND_CLIENT || spanKind === SPAN_KIND_SERVER) {\n const urlPath = getUrlPath(attributes, spanKind);\n if (urlPath) {\n spanJSON.name = `${httpMethod} ${urlPath}`;\n }\n }\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' });\n }\n}\n\n/**\n * Extract a URL path from span attributes for use in the span name.\n * Mirrors the logic in the non-streamed exporter's `getSanitizedUrl`.\n */\nfunction getUrlPath(\n attributes: RawAttributes<Record<string, unknown>>,\n spanKind: number | undefined,\n): string | undefined {\n const httpUrl = attributes['http.url'] || attributes['url.full'];\n const httpTarget = attributes['http.target'];\n\n const parsedUrl = typeof httpUrl === 'string' ? parseUrl(httpUrl) : undefined;\n const sanitizedUrl = parsedUrl ? getSanitizedUrlString(parsedUrl) : undefined;\n\n // For server spans, prefer the relative target path\n if (spanKind === SPAN_KIND_SERVER && typeof httpTarget === 'string') {\n return stripUrlQueryAndFragment(httpTarget);\n }\n\n // For client spans (and others), use the full sanitized URL\n if (sanitizedUrl) {\n return sanitizedUrl;\n }\n\n // Fall back to target if no full URL is available\n if (typeof httpTarget === 'string') {\n return stripUrlQueryAndFragment(httpTarget);\n }\n\n return undefined;\n}\n\nfunction inferDbSpanData(spanJSON: StreamedSpanJSON, attributes: RawAttributes<Record<string, unknown>>): void {\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' });\n\n // If the user set a custom span name via updateSpanName(), apply it.\n const customName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n if (typeof customName === 'string') {\n spanJSON.name = customName;\n return;\n }\n\n if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom') {\n return;\n }\n\n const statement = attributes['db.statement'];\n if (statement) {\n spanJSON.name = `${statement}`;\n safeSetSpanJSONAttributes(spanJSON, { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' });\n }\n}\n"],"names":["spanToStreamedSpanJSON","INTERNAL_getSegmentSpan","getCapturedScopesOnSpan","getCombinedScopeData","beforeSendSpan","isStreamedBeforeSendSpanCallback","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","streamedSpanJsonToSerializedSpan","SEMANTIC_ATTRIBUTE_SENTRY_RELEASE","SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID","SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME","SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION","SEMANTIC_ATTRIBUTE_USER_ID","SEMANTIC_ATTRIBUTE_USER_EMAIL","SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS","SEMANTIC_ATTRIBUTE_USER_USERNAME","showSpanDropWarning","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME","parseUrl","getSanitizedUrlString","stripUrlQueryAndFragment"],"mappings":";;;;;;;;;AAkCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,IAAI,EAAQ,MAAM,EAAiD;AAC/F;AACA,EAAE,MAAM,QAAA,GAAWA,gCAAsB,CAAC,IAAI,CAAC;;AAE/C,EAAE,MAAM,WAAA,GAAcC,iCAAuB,CAAC,IAAI,CAAC;AACnD,EAAE,MAAM,qBAAA,GAAwBD,gCAAsB,CAAC,WAAW,CAAC;;AAEnE,EAAE,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAA,EAAU,GAAIE,6BAAuB,CAAC,IAAI,CAAC;;AAEhG,EAAE,MAAM,iBAAiBC,8BAAoB,CAAC,kBAAkB,EAAE,SAAS,CAAC;;AAE5E,EAAE,yBAAyB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,MAAM,EAAE,cAAc,CAAC;;AAEpF;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,QAAA,GAAW,CAAC,IAAA,GAA2B,IAAI;AACnD,EAAE,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,CAAC;;AAErD,EAAE,IAAI,QAAQ,CAAC,UAAU,EAAE;AAE3B;AACA;AACA,IAAI,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC;AAC/C,EAAE;;AAEF;AACA;AACA,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC;;AAEtC,EAAE,MAAM,kBAAEC,gBAAA,EAAe,GAAI,MAAM,CAAC,UAAU,EAAE;AAChD,EAAE,MAAM,aAAA;AACR,IAAIA,gBAAA,IAAkBC,+CAAgC,CAACD,gBAAc;AACrE,QAAQ,2BAA2B,CAAC,QAAQ,EAAEA,gBAAc;AAC5D,QAAQ,QAAQ;;AAEhB;AACA;AACA,EAAE,MAAM,iBAAiB,aAAa,CAAC,UAAU,GAAGE,mDAAgC,CAAC;AACrF,EAAE,IAAI,cAAc,EAAE;AACtB,IAAI,yBAAyB,CAAC,aAAa,EAAE;AAC7C;AACA;AACA,MAAM,oBAAoB,EAAE,cAAc;AAC1C,KAAK,CAAC;AACN,EAAE;;AAEF,EAAE,OAAO;AACT,IAAI,GAAGC,0CAAgC,CAAC,aAAa,CAAC;AACtD,IAAI,YAAY,EAAE,WAAW;AAC7B,GAAG;AACH;;AAOA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,QAAQ;AACV,EAAE,aAAa;AACf,EAAQ;AACR,EAAE,MAAM,kBAAA,GAAqB,QAAQ,CAAC,UAAA,KAAe,QAAQ,CAAC,UAAA,GAAa,EAAE,CAAC;;AAE9E,EAAE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK;AAC1D,IAAI,IAAI,KAAA,IAAS,IAAA,IAAQ,EAAE,GAAA,IAAO,kBAAkB,CAAC,EAAE;AACvD,MAAM,kBAAkB,CAAC,GAAG,CAAA,GAAI,KAAK;AACrC,IAAI;AACJ,EAAE,CAAC,CAAC;AACJ;;AAEA,SAAS,yBAAyB;AAClC,EAAE,QAAQ;AACV,EAAE,qBAAqB;AACvB,EAAE,MAAM;AACR,EAAE,SAAS;AACX,EAAQ;AACR,EAAE,MAAM,GAAA,GAAM,MAAM,CAAC,cAAc,EAAE;AACrC,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,cAAA,EAAe,GAAI,MAAM,CAAC,UAAU,EAAE;;AAEtE;AACA,EAAE,yBAAyB,CAAC,QAAQ,EAAE;AACtC,IAAI,CAACC,oDAAiC,GAAG,OAAO;AAChD,IAAI,CAACC,wDAAqC,GAAG,WAAW;AACxD,IAAI,CAACC,yDAAsC,GAAG,qBAAqB,CAAC,IAAI;AACxE,IAAI,CAACC,uDAAoC,GAAG,qBAAqB,CAAC,OAAO;AACzE,IAAI,CAACC,qDAAkC,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI;AACxD,IAAI,CAACC,wDAAqC,GAAG,GAAG,EAAE,GAAG,EAAE,OAAO;AAC9D,IAAI,IAAI;AACR,QAAQ;AACR,UAAU,CAACC,6CAA0B,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE;AAC1D,UAAU,CAACC,gDAA6B,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK;AAChE,UAAU,CAACC,qDAAkC,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU;AAC1E,UAAU,CAACC,mDAAgC,GAAG,SAAS,CAAC,IAAI,EAAE,QAAQ;AACtE;AACA,QAAQ,EAAE,CAAC;AACX,IAAI,GAAG,SAAS,CAAC,UAAU;AAC3B,GAAG,CAAC;AACJ;;AAEA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,IAAI;AACN,EAAE,cAAc;AAChB,EAAoB;AACpB,EAAE,MAAM,WAAA,GAAc,cAAc,CAAC,IAAI,CAAC;AAC1C,EAAE,IAAI,CAAC,WAAW,EAAE;AACpB,IAAIC,6BAAmB,EAAE;AACzB,IAAI,OAAO,IAAI;AACf,EAAE;AACF,EAAE,OAAO,WAAW;AACpB;;AAEA;AACA,MAAM,gBAAA,GAAmB,CAAC;AAC1B,MAAM,gBAAA,GAAmB,CAAC;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,+BAA+B,CAAC,QAAQ,EAAoB,QAAQ,EAAiB;AACrG,EAAE,MAAM,UAAA,GAAa,QAAQ,CAAC,UAAU;AACxC,EAAE,IAAI,CAAC,UAAU,EAAE;AACnB,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,UAAA,GAAa,UAAU,CAAC,qBAAqB,CAAA,IAAK,UAAU,CAAC,aAAa,CAAC;AACnF,EAAE,IAAI,UAAU,EAAE;AAClB,IAAI,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC;AACjE,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,QAAA,GAAW,UAAU,CAAC,gBAAgB,CAAA,IAAK,UAAU,CAAC,WAAW,CAAC;AAC1E,EAAE,MAAM,SAAA;AACR,IAAI,OAAO,UAAU,CAACC,+CAA4B,CAAA,KAAM,QAAA;AACxD,IAAI,CAAC,EAAA,UAAA,CAAAA,+CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,QAAA,CAAA;AACA,EAAA,IAAA,QAAA,IAAA,CAAA,SAAA,EAAA;AACA,IAAA,eAAA,CAAA,QAAA,EAAA,UAAA,CAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,IAAA,UAAA,CAAA,aAAA,CAAA,EAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,+CAAA,GAAA,KAAA,EAAA,CAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,IAAA,UAAA,CAAA,kBAAA,CAAA,EAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,+CAAA,GAAA,SAAA,EAAA,CAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,WAAA,GAAA,UAAA,CAAA,cAAA,CAAA;AACA,EAAA,IAAA,WAAA,EAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,+CAAA,GAAA,CAAA,EAAA,WAAA,CAAA,CAAA,EAAA,CAAA;AACA,EAAA;AACA;;AAEA,SAAA,iBAAA;AACA,EAAA,QAAA;AACA,EAAA,UAAA;AACA,EAAA,QAAA;AACA,EAAA,UAAA;AACA,EAAA;AACA;AACA,EAAA,MAAA,OAAA,GAAA,CAAA,MAAA,CAAA;AACA,EAAA,IAAA,QAAA,KAAA,gBAAA,EAAA;AACA,IAAA,OAAA,CAAA,IAAA,CAAA,QAAA,CAAA;AACA,EAAA,CAAA,MAAA,IAAA,QAAA,KAAA,gBAAA,EAAA;AACA,IAAA,OAAA,CAAA,IAAA,CAAA,QAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,UAAA,CAAA,sBAAA,CAAA,EAAA;AACA,IAAA,OAAA,CAAA,IAAA,CAAA,UAAA,CAAA;AACA,EAAA;AACA,EAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,+CAAA,GAAA,OAAA,CAAA,IAAA,CAAA,GAAA,CAAA,EAAA,CAAA;;AAEA;AACA;AACA,EAAA,MAAA,UAAA,GAAA,UAAA,CAAAC,6DAAA,CAAA;AACA,EAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,QAAA,CAAA,IAAA,GAAA,UAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,IAAA,UAAA,CAAAd,mDAAA,CAAA,KAAA,QAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,SAAA,GAAA,UAAA,CAAA,YAAA,CAAA;AACA,EAAA,IAAA,OAAA,SAAA,KAAA,QAAA,EAAA;AACA,IAAA,QAAA,CAAA,IAAA,GAAA,CAAA,EAAA,UAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,mDAAA,GAAA,OAAA,EAAA,CAAA;AACA,EAAA,CAAA,MAAA;AACA;AACA;AACA,IAAA,IAAA,QAAA,KAAA,gBAAA,IAAA,QAAA,KAAA,gBAAA,EAAA;AACA,MAAA,MAAA,OAAA,GAAA,UAAA,CAAA,UAAA,EAAA,QAAA,CAAA;AACA,MAAA,IAAA,OAAA,EAAA;AACA,QAAA,QAAA,CAAA,IAAA,GAAA,CAAA,EAAA,UAAA,CAAA,CAAA,EAAA,OAAA,CAAA,CAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,mDAAA,GAAA,KAAA,EAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,UAAA;AACA,EAAA,UAAA;AACA,EAAA,QAAA;AACA,EAAA;AACA,EAAA,MAAA,OAAA,GAAA,UAAA,CAAA,UAAA,CAAA,IAAA,UAAA,CAAA,UAAA,CAAA;AACA,EAAA,MAAA,UAAA,GAAA,UAAA,CAAA,aAAA,CAAA;;AAEA,EAAA,MAAA,SAAA,GAAA,OAAA,OAAA,KAAA,QAAA,GAAAe,YAAA,CAAA,OAAA,CAAA,GAAA,SAAA;AACA,EAAA,MAAA,YAAA,GAAA,SAAA,GAAAC,yBAAA,CAAA,SAAA,CAAA,GAAA,SAAA;;AAEA;AACA,EAAA,IAAA,QAAA,KAAA,gBAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,OAAAC,4BAAA,CAAA,UAAA,CAAA;AACA,EAAA;;AAEA;AACA,EAAA,IAAA,YAAA,EAAA;AACA,IAAA,OAAA,YAAA;AACA,EAAA;;AAEA;AACA,EAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,OAAAA,4BAAA,CAAA,UAAA,CAAA;AACA,EAAA;;AAEA,EAAA,OAAA,SAAA;AACA;;AAEA,SAAA,eAAA,CAAA,QAAA,EAAA,UAAA,EAAA;AACA,EAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAJ,+CAAA,GAAA,IAAA,EAAA,CAAA;;AAEA;AACA,EAAA,MAAA,UAAA,GAAA,UAAA,CAAAC,6DAAA,CAAA;AACA,EAAA,IAAA,OAAA,UAAA,KAAA,QAAA,EAAA;AACA,IAAA,QAAA,CAAA,IAAA,GAAA,UAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,IAAA,UAAA,CAAAd,mDAAA,CAAA,KAAA,QAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,SAAA,GAAA,UAAA,CAAA,cAAA,CAAA;AACA,EAAA,IAAA,SAAA,EAAA;AACA,IAAA,QAAA,CAAA,IAAA,GAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,IAAA,yBAAA,CAAA,QAAA,EAAA,EAAA,CAAAA,mDAAA,GAAA,MAAA,EAAA,CAAA;AACA,EAAA;AACA;;;;;;;"}
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const dsn = require('../../utils/dsn.js');
4
4
  const envelope = require('../../utils/envelope.js');
5
+ const isBrowser = require('../../utils/isBrowser.js');
5
6
 
6
7
  /**
7
8
  * Creates a span v2 span streaming envelope
@@ -11,9 +12,10 @@ function createStreamedSpanEnvelope(
11
12
  dsc,
12
13
  client,
13
14
  ) {
15
+ const options = client.getOptions();
14
16
  const dsn$1 = client.getDsn();
15
- const tunnel = client.getOptions().tunnel;
16
- const sdk = envelope.getSdkMetadataForEnvelopeHeader(client.getOptions()._metadata);
17
+ const tunnel = options.tunnel;
18
+ const sdk = envelope.getSdkMetadataForEnvelopeHeader(options._metadata);
17
19
 
18
20
  const headers = {
19
21
  sent_at: new Date().toISOString(),
@@ -22,9 +24,17 @@ function createStreamedSpanEnvelope(
22
24
  ...(!!tunnel && dsn$1 && { dsn: dsn.dsnToString(dsn$1) }),
23
25
  };
24
26
 
27
+ const inferSetting = options.sendDefaultPii ? 'auto' : 'never';
28
+
25
29
  const spanContainer = [
26
30
  { type: 'span', item_count: serializedSpans.length, content_type: 'application/vnd.sentry.items.span.v2+json' },
27
- { items: serializedSpans },
31
+ {
32
+ version: 2,
33
+ ...(isBrowser.isBrowser() && {
34
+ ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },
35
+ }),
36
+ items: serializedSpans,
37
+ },
28
38
  ];
29
39
 
30
40
  return envelope.createEnvelope(headers, [spanContainer]);
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.js","sources":["../../../../src/tracing/spans/envelope.ts"],"sourcesContent":["import type { Client } from '../../client';\nimport type { DynamicSamplingContext, SpanContainerItem, StreamedSpanEnvelope } from '../../types-hoist/envelope';\nimport type { SerializedStreamedSpan } from '../../types-hoist/span';\nimport { dsnToString } from '../../utils/dsn';\nimport { createEnvelope, getSdkMetadataForEnvelopeHeader } from '../../utils/envelope';\n\n/**\n * Creates a span v2 span streaming envelope\n */\nexport function createStreamedSpanEnvelope(\n serializedSpans: Array<SerializedStreamedSpan>,\n dsc: Partial<DynamicSamplingContext>,\n client: Client,\n): StreamedSpanEnvelope {\n const dsn = client.getDsn();\n const tunnel = client.getOptions().tunnel;\n const sdk = getSdkMetadataForEnvelopeHeader(client.getOptions()._metadata);\n\n const headers: StreamedSpanEnvelope[0] = {\n sent_at: new Date().toISOString(),\n ...(dscHasRequiredProps(dsc) && { trace: dsc }),\n ...(sdk && { sdk }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n };\n\n const spanContainer: SpanContainerItem = [\n { type: 'span', item_count: serializedSpans.length, content_type: 'application/vnd.sentry.items.span.v2+json' },\n { items: serializedSpans },\n ];\n\n return createEnvelope<StreamedSpanEnvelope>(headers, [spanContainer]);\n}\n\nfunction dscHasRequiredProps(dsc: Partial<DynamicSamplingContext>): dsc is DynamicSamplingContext {\n return !!dsc.trace_id && !!dsc.public_key;\n}\n"],"names":["dsn","getSdkMetadataForEnvelopeHeader","dsnToString","createEnvelope"],"mappings":";;;;;AAMA;AACA;AACA;AACO,SAAS,0BAA0B;AAC1C,EAAE,eAAe;AACjB,EAAE,GAAG;AACL,EAAE,MAAM;AACR,EAAwB;AACxB,EAAE,MAAMA,KAAA,GAAM,MAAM,CAAC,MAAM,EAAE;AAC7B,EAAE,MAAM,SAAS,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM;AAC3C,EAAE,MAAM,GAAA,GAAMC,wCAA+B,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC;;AAE5E,EAAE,MAAM,OAAO,GAA4B;AAC3C,IAAI,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACrC,IAAI,IAAI,mBAAmB,CAAC,GAAG,CAAA,IAAK,EAAE,KAAK,EAAE,GAAA,EAAK,CAAC;AACnD,IAAI,IAAI,GAAA,IAAO,EAAE,GAAA,EAAK,CAAC;AACvB,IAAI,IAAI,CAAC,CAAC,MAAA,IAAUD,KAAA,IAAO,EAAE,GAAG,EAAEE,eAAW,CAACF,KAAG,CAAA,EAAG,CAAC;AACrD,GAAG;;AAEH,EAAE,MAAM,aAAa,GAAsB;AAC3C,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,6CAA6C;AACnH,IAAI,EAAE,KAAK,EAAE,eAAA,EAAiB;AAC9B,GAAG;;AAEH,EAAE,OAAOG,uBAAc,CAAuB,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;AACvE;;AAEA,SAAS,mBAAmB,CAAC,GAAG,EAAkE;AAClG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,QAAA,IAAY,CAAC,CAAC,GAAG,CAAC,UAAU;AAC3C;;;;"}
1
+ {"version":3,"file":"envelope.js","sources":["../../../../src/tracing/spans/envelope.ts"],"sourcesContent":["import type { Client } from '../../client';\nimport type { DynamicSamplingContext, SpanContainerItem, StreamedSpanEnvelope } from '../../types-hoist/envelope';\nimport type { SerializedStreamedSpan } from '../../types-hoist/span';\nimport { dsnToString } from '../../utils/dsn';\nimport { createEnvelope, getSdkMetadataForEnvelopeHeader } from '../../utils/envelope';\nimport { isBrowser } from '../../utils/isBrowser';\n\n/**\n * Creates a span v2 span streaming envelope\n */\nexport function createStreamedSpanEnvelope(\n serializedSpans: Array<SerializedStreamedSpan>,\n dsc: Partial<DynamicSamplingContext>,\n client: Client,\n): StreamedSpanEnvelope {\n const options = client.getOptions();\n const dsn = client.getDsn();\n const tunnel = options.tunnel;\n const sdk = getSdkMetadataForEnvelopeHeader(options._metadata);\n\n const headers: StreamedSpanEnvelope[0] = {\n sent_at: new Date().toISOString(),\n ...(dscHasRequiredProps(dsc) && { trace: dsc }),\n ...(sdk && { sdk }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n };\n\n const inferSetting = options.sendDefaultPii ? 'auto' : 'never';\n\n const spanContainer: SpanContainerItem = [\n { type: 'span', item_count: serializedSpans.length, content_type: 'application/vnd.sentry.items.span.v2+json' },\n {\n version: 2,\n ...(isBrowser() && {\n ingest_settings: { infer_ip: inferSetting, infer_user_agent: inferSetting },\n }),\n items: serializedSpans,\n },\n ];\n\n return createEnvelope<StreamedSpanEnvelope>(headers, [spanContainer]);\n}\n\nfunction dscHasRequiredProps(dsc: Partial<DynamicSamplingContext>): dsc is DynamicSamplingContext {\n return !!dsc.trace_id && !!dsc.public_key;\n}\n"],"names":["dsn","getSdkMetadataForEnvelopeHeader","dsnToString","isBrowser","createEnvelope"],"mappings":";;;;;;AAOA;AACA;AACA;AACO,SAAS,0BAA0B;AAC1C,EAAE,eAAe;AACjB,EAAE,GAAG;AACL,EAAE,MAAM;AACR,EAAwB;AACxB,EAAE,MAAM,OAAA,GAAU,MAAM,CAAC,UAAU,EAAE;AACrC,EAAE,MAAMA,KAAA,GAAM,MAAM,CAAC,MAAM,EAAE;AAC7B,EAAE,MAAM,MAAA,GAAS,OAAO,CAAC,MAAM;AAC/B,EAAE,MAAM,MAAMC,wCAA+B,CAAC,OAAO,CAAC,SAAS,CAAC;;AAEhE,EAAE,MAAM,OAAO,GAA4B;AAC3C,IAAI,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;AACrC,IAAI,IAAI,mBAAmB,CAAC,GAAG,CAAA,IAAK,EAAE,KAAK,EAAE,GAAA,EAAK,CAAC;AACnD,IAAI,IAAI,GAAA,IAAO,EAAE,GAAA,EAAK,CAAC;AACvB,IAAI,IAAI,CAAC,CAAC,MAAA,IAAUD,KAAA,IAAO,EAAE,GAAG,EAAEE,eAAW,CAACF,KAAG,CAAA,EAAG,CAAC;AACrD,GAAG;;AAEH,EAAE,MAAM,eAAe,OAAO,CAAC,cAAA,GAAiB,MAAA,GAAS,OAAO;;AAEhE,EAAE,MAAM,aAAa,GAAsB;AAC3C,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,6CAA6C;AACnH,IAAI;AACJ,MAAM,OAAO,EAAE,CAAC;AAChB,MAAM,IAAIG,mBAAS,MAAM;AACzB,QAAQ,eAAe,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAA,EAAc;AACnF,OAAO,CAAC;AACR,MAAM,KAAK,EAAE,eAAe;AAC5B,KAAK;AACL,GAAG;;AAEH,EAAE,OAAOC,uBAAc,CAAuB,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;AACvE;;AAEA,SAAS,mBAAmB,CAAC,GAAG,EAAkE;AAClG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,QAAA,IAAY,CAAC,CAAC,GAAG,CAAC,UAAU;AAC3C;;;;"}
@@ -598,6 +598,7 @@ function _shouldIgnoreStreamedSpan(client, spanArguments) {
598
598
  {
599
599
  description: spanArguments.name || '',
600
600
  op: spanArguments.attributes?.[semanticAttributes.SEMANTIC_ATTRIBUTE_SENTRY_OP] || spanArguments.op,
601
+ attributes: spanArguments.attributes,
601
602
  },
602
603
  ignoreSpans,
603
604
  );
@@ -611,6 +612,7 @@ function _isTracingSuppressed(scope) {
611
612
  return scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] === true;
612
613
  }
613
614
 
615
+ exports.SUPPRESS_TRACING_KEY = SUPPRESS_TRACING_KEY;
614
616
  exports.continueTrace = continueTrace;
615
617
  exports.startInactiveSpan = startInactiveSpan;
616
618
  exports.startNewTrace = startNewTrace;