@sentry/cloudflare 11.0.0-beta.2 → 11.0.0-rc.1

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 (135) hide show
  1. package/build/cjs/dev/durableobject.js +26 -18
  2. package/build/cjs/dev/durableobject.js.map +1 -1
  3. package/build/cjs/dev/index.js +5 -1
  4. package/build/cjs/dev/index.js.map +1 -1
  5. package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js +6 -0
  6. package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  7. package/build/cjs/dev/instrumentations/worker/instrumentD1.js +19 -17
  8. package/build/cjs/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  9. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js +4 -3
  10. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  11. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js +10 -5
  12. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  13. package/build/cjs/dev/integrations/fetch.js +3 -101
  14. package/build/cjs/dev/integrations/fetch.js.map +1 -1
  15. package/build/cjs/dev/orchestrion-deferred-channels.js +39 -0
  16. package/build/cjs/dev/orchestrion-deferred-channels.js.map +1 -0
  17. package/build/cjs/dev/orchestrion-diagnostics-channel.js +83 -0
  18. package/build/cjs/dev/orchestrion-diagnostics-channel.js.map +1 -0
  19. package/build/cjs/dev/vite/flueRuntime.js +44 -0
  20. package/build/cjs/dev/vite/flueRuntime.js.map +1 -0
  21. package/build/cjs/dev/vite/index.js +8 -1
  22. package/build/cjs/dev/vite/index.js.map +1 -1
  23. package/build/cjs/dev/vite/mastraObservability.js +39 -0
  24. package/build/cjs/dev/vite/mastraObservability.js.map +1 -0
  25. package/build/cjs/dev/wrapMethodWithSentry.js +8 -4
  26. package/build/cjs/dev/wrapMethodWithSentry.js.map +1 -1
  27. package/build/cjs/dev/wrapRequestHandlerWithInit.js +2 -0
  28. package/build/cjs/dev/wrapRequestHandlerWithInit.js.map +1 -1
  29. package/build/cjs/prod/durableobject.js +26 -18
  30. package/build/cjs/prod/durableobject.js.map +1 -1
  31. package/build/cjs/prod/index.js +5 -1
  32. package/build/cjs/prod/index.js.map +1 -1
  33. package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js +6 -0
  34. package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  35. package/build/cjs/prod/instrumentations/worker/instrumentD1.js +19 -17
  36. package/build/cjs/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  37. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js +4 -3
  38. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  39. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js +10 -5
  40. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  41. package/build/cjs/prod/integrations/fetch.js +3 -101
  42. package/build/cjs/prod/integrations/fetch.js.map +1 -1
  43. package/build/cjs/prod/orchestrion-deferred-channels.js +39 -0
  44. package/build/cjs/prod/orchestrion-deferred-channels.js.map +1 -0
  45. package/build/cjs/prod/orchestrion-diagnostics-channel.js +83 -0
  46. package/build/cjs/prod/orchestrion-diagnostics-channel.js.map +1 -0
  47. package/build/cjs/prod/vite/flueRuntime.js +44 -0
  48. package/build/cjs/prod/vite/flueRuntime.js.map +1 -0
  49. package/build/cjs/prod/vite/index.js +8 -1
  50. package/build/cjs/prod/vite/index.js.map +1 -1
  51. package/build/cjs/prod/vite/mastraObservability.js +39 -0
  52. package/build/cjs/prod/vite/mastraObservability.js.map +1 -0
  53. package/build/cjs/prod/wrapMethodWithSentry.js +8 -4
  54. package/build/cjs/prod/wrapMethodWithSentry.js.map +1 -1
  55. package/build/cjs/prod/wrapRequestHandlerWithInit.js +2 -0
  56. package/build/cjs/prod/wrapRequestHandlerWithInit.js.map +1 -1
  57. package/build/esm/dev/durableobject.js +27 -19
  58. package/build/esm/dev/durableobject.js.map +1 -1
  59. package/build/esm/dev/index.js +2 -2
  60. package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js +6 -0
  61. package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  62. package/build/esm/dev/instrumentations/worker/instrumentD1.js +20 -18
  63. package/build/esm/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  64. package/build/esm/dev/instrumentations/worker/instrumentEmail.js +6 -5
  65. package/build/esm/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  66. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js +12 -7
  67. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  68. package/build/esm/dev/integrations/fetch.js +4 -102
  69. package/build/esm/dev/integrations/fetch.js.map +1 -1
  70. package/build/esm/dev/orchestrion-deferred-channels.js +35 -0
  71. package/build/esm/dev/orchestrion-deferred-channels.js.map +1 -0
  72. package/build/esm/dev/orchestrion-diagnostics-channel.js +77 -0
  73. package/build/esm/dev/orchestrion-diagnostics-channel.js.map +1 -0
  74. package/build/esm/dev/package.json +1 -1
  75. package/build/esm/dev/vite/flueRuntime.js +41 -0
  76. package/build/esm/dev/vite/flueRuntime.js.map +1 -0
  77. package/build/esm/dev/vite/index.js +8 -1
  78. package/build/esm/dev/vite/index.js.map +1 -1
  79. package/build/esm/dev/vite/mastraObservability.js +36 -0
  80. package/build/esm/dev/vite/mastraObservability.js.map +1 -0
  81. package/build/esm/dev/wrapMethodWithSentry.js +7 -3
  82. package/build/esm/dev/wrapMethodWithSentry.js.map +1 -1
  83. package/build/esm/dev/wrapRequestHandlerWithInit.js +2 -0
  84. package/build/esm/dev/wrapRequestHandlerWithInit.js.map +1 -1
  85. package/build/esm/prod/durableobject.js +27 -19
  86. package/build/esm/prod/durableobject.js.map +1 -1
  87. package/build/esm/prod/index.js +2 -2
  88. package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js +6 -0
  89. package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  90. package/build/esm/prod/instrumentations/worker/instrumentD1.js +20 -18
  91. package/build/esm/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  92. package/build/esm/prod/instrumentations/worker/instrumentEmail.js +6 -5
  93. package/build/esm/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  94. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js +12 -7
  95. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  96. package/build/esm/prod/integrations/fetch.js +4 -102
  97. package/build/esm/prod/integrations/fetch.js.map +1 -1
  98. package/build/esm/prod/orchestrion-deferred-channels.js +35 -0
  99. package/build/esm/prod/orchestrion-deferred-channels.js.map +1 -0
  100. package/build/esm/prod/orchestrion-diagnostics-channel.js +77 -0
  101. package/build/esm/prod/orchestrion-diagnostics-channel.js.map +1 -0
  102. package/build/esm/prod/package.json +1 -1
  103. package/build/esm/prod/vite/flueRuntime.js +41 -0
  104. package/build/esm/prod/vite/flueRuntime.js.map +1 -0
  105. package/build/esm/prod/vite/index.js +8 -1
  106. package/build/esm/prod/vite/index.js.map +1 -1
  107. package/build/esm/prod/vite/mastraObservability.js +36 -0
  108. package/build/esm/prod/vite/mastraObservability.js.map +1 -0
  109. package/build/esm/prod/wrapMethodWithSentry.js +7 -3
  110. package/build/esm/prod/wrapMethodWithSentry.js.map +1 -1
  111. package/build/esm/prod/wrapRequestHandlerWithInit.js +2 -0
  112. package/build/esm/prod/wrapRequestHandlerWithInit.js.map +1 -1
  113. package/build/types/durableobject.d.ts +3 -2
  114. package/build/types/durableobject.d.ts.map +1 -1
  115. package/build/types/index.d.ts +5 -3
  116. package/build/types/index.d.ts.map +1 -1
  117. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts +1 -0
  118. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts.map +1 -1
  119. package/build/types/instrumentations/worker/instrumentD1.d.ts.map +1 -1
  120. package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
  121. package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
  122. package/build/types/integrations/fetch.d.ts +1 -15
  123. package/build/types/integrations/fetch.d.ts.map +1 -1
  124. package/build/types/orchestrion-deferred-channels.d.ts +26 -0
  125. package/build/types/orchestrion-deferred-channels.d.ts.map +1 -0
  126. package/build/types/orchestrion-diagnostics-channel.d.ts +44 -0
  127. package/build/types/orchestrion-diagnostics-channel.d.ts.map +1 -0
  128. package/build/types/vite/flueRuntime.d.ts +23 -0
  129. package/build/types/vite/flueRuntime.d.ts.map +1 -0
  130. package/build/types/vite/index.d.ts.map +1 -1
  131. package/build/types/vite/mastraObservability.d.ts +27 -0
  132. package/build/types/vite/mastraObservability.d.ts.map +1 -0
  133. package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
  134. package/build/types/wrapRequestHandlerWithInit.d.ts.map +1 -1
  135. package/package.json +10 -5
@@ -105,33 +105,41 @@ function instrumentPrototypeRpcMethods(obj, excludedMethods) {
105
105
  prototype = Object.getPrototypeOf(prototype);
106
106
  }
107
107
  }
108
+ function getInstrumentedRpcMethod(state, methodName, originalMethod) {
109
+ const instrumentedMethods = state.instrumentedMethods ?? (state.instrumentedMethods = /* @__PURE__ */ new Map());
110
+ let instrumented = instrumentedMethods.get(methodName);
111
+ if (!instrumented) {
112
+ instrumented = wrapMethodWithSentry.wrapMethodWithSentry(
113
+ {
114
+ options: state.options,
115
+ context: state.context,
116
+ spanName: (rpcMeta) => rpcMeta ? methodName : void 0,
117
+ spanOp: op.RPC,
118
+ origin: "auto.faas.cloudflare.durable_object"
119
+ },
120
+ originalMethod,
121
+ void 0,
122
+ true
123
+ );
124
+ instrumentedMethods.set(methodName, instrumented);
125
+ }
126
+ return instrumented;
127
+ }
108
128
  function createRpcPrototypeWrapper(methodName, originalMethod) {
109
129
  const wrapper = function(...args) {
110
- if (!rpcMeta.hasRpcMeta(args)) {
130
+ const traced = rpcMeta.hasRpcMeta(args);
131
+ if (!traced && core.getIsolationScope() !== core.getDefaultIsolationScope()) {
111
132
  return Reflect.apply(originalMethod, this, args);
112
133
  }
113
134
  const state = core.isObjectLike(this) ? rpcInstanceStates.get(this) : void 0;
114
135
  if (!state) {
115
136
  return Reflect.apply(originalMethod, this, args);
116
137
  }
117
- const tracedMethods = state.tracedMethods ?? (state.tracedMethods = /* @__PURE__ */ new Map());
118
- let traced = tracedMethods.get(methodName);
119
- if (!traced) {
120
- traced = wrapMethodWithSentry.wrapMethodWithSentry(
121
- {
122
- options: state.options,
123
- context: state.context,
124
- spanName: methodName,
125
- spanOp: op.RPC,
126
- origin: "auto.faas.cloudflare.durable_object"
127
- },
128
- originalMethod,
129
- void 0,
130
- true
131
- );
132
- tracedMethods.set(methodName, traced);
138
+ const instrumented = getInstrumentedRpcMethod(state, methodName, originalMethod);
139
+ if (traced) {
140
+ return Reflect.apply(instrumented, this, args);
133
141
  }
134
- return Reflect.apply(traced, this, args);
142
+ return core.startNewTrace(() => Reflect.apply(instrumented, this, args));
135
143
  };
136
144
  Object.defineProperties(wrapper, {
137
145
  name: { value: originalMethod.name, configurable: true },
@@ -1 +1 @@
1
- {"version":3,"file":"durableobject.js","sources":["../../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/unbound-method */\nimport { RPC } from '@sentry/conventions/op';\nimport { isObjectLike } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';\nimport type { CloudflareOptions } from './client';\nimport { getInstrumented, markAsInstrumented } from './instrument';\nimport { instrumentDurableObjectHandlers } from './instrumentations/instrumentDurableObjectHandlers';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { hasRpcMeta } from './utils/rpcMeta';\nimport { instrumentCloudflareAgent } from './instrumentations/agents';\nimport type { DefaultEnv, ResolveEnv, StrictCloudflareOptions } from './types';\nimport { type UncheckedMethod, wrapMethodWithSentry } from './wrapMethodWithSentry';\n\n/**\n * The instrumented context passed between the shared construction helpers.\n *\n * This is intentionally `any` rather than `ReturnType<typeof instrumentContext<DurableObjectState>>`.\n * A concrete `DurableObjectState` here forces `tsc` to structurally relate its `storage: SqlStorage`\n * graph against the `ExecutionContext | InstrumentedDurableObjectState` parameter of\n * `wrapMethodWithSentry`, while the RPC-branded `DurableObject` from `cloudflare:workers` is also in\n * scope. That union comparison explodes (1296×1296) and hangs the type build. The original inline\n * implementation avoided this only incidentally, because `ctx` reached it as `any` through the Proxy\n * `construct` trap. Keeping the shared context `any` preserves that behavior.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentedDurableObjectContext = any;\n\n/**\n * Constructs a Durable Object instance and instruments its built-in handler methods\n * (`fetch`, `alarm`, `webSocketMessage`, `webSocketClose`, `webSocketError`).\n *\n * This is the shared construction path used by both {@link instrumentDurableObjectWithSentry}\n * and {@link instrumentAgentWithSentry}. It intentionally does NOT apply the RPC prototype-method\n * instrumentation — callers apply that last via {@link finalizeWithRpcInstrumentation}, after any\n * additional per-instance instrumentation has been layered onto the returned object.\n *\n * @internal\n */\nexport function constructInstrumentedDurableObject<E, T extends DurableObject<E>>(\n target: new (state: DurableObjectState, env: E) => T,\n ctx: DurableObjectState,\n env: E,\n newTarget: NewableFunction,\n optionsCallback: (env: E) => CloudflareOptions,\n): {\n obj: T;\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n frameworkManagedMethods: ReadonlySet<string>;\n} {\n setAsyncLocalStorageAsyncContextStrategy();\n const options = getFinalOptions(optionsCallback(env), env);\n // See InstrumentedDurableObjectContext — `ctx` is widened to `any` so the concrete\n // `DurableObjectState` type never enters the checker's relation graph in this module.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const context = instrumentContext(ctx as any);\n const instrumentedEnv = instrumentEnv(env as Record<string, unknown>, options);\n\n const prototype = (newTarget as unknown as { prototype?: object }).prototype ?? target.prototype;\n const cachedFrameworkManagedMethods = frameworkManagedMethodsCache.get(prototype);\n const methodsBeforeConstruction = cachedFrameworkManagedMethods ? undefined : resolvePrototypeMethods(prototype);\n\n // Pass `newTarget` so that subclasses of the instrumented class (e.g. the wrapper classes\n // created by wrangler's local dev tooling or `@cloudflare/vitest-pool-workers`) keep their\n // own prototype — otherwise subclass methods disappear and `instanceof` checks break.\n const obj = Reflect.construct(target, [context, instrumentedEnv], newTarget) as T;\n\n const frameworkManagedMethods = resolveFrameworkManagedMethods(\n prototype,\n obj,\n methodsBeforeConstruction,\n cachedFrameworkManagedMethods,\n );\n\n instrumentDurableObjectHandlers(obj, options, context);\n\n return { obj, options, context, frameworkManagedMethods };\n}\n\nconst frameworkManagedMethodsCache = new WeakMap<object, ReadonlySet<string>>();\n\n/**\n * Collects the methods visible from a prototype, using normal property lookup precedence.\n * Methods inherited from `Object.prototype` are excluded because they cannot be Durable Object RPC methods.\n */\nfunction resolvePrototypeMethods(prototype: object | null): Map<string, unknown> {\n const methods = new Map<string, unknown>();\n\n for (let current = prototype; current && current !== Object.prototype; current = Object.getPrototypeOf(current)) {\n for (const name of Object.getOwnPropertyNames(current)) {\n // The first occurrence wins, mirroring what a property lookup on the instance would find\n if (name === 'constructor' || methods.has(name)) {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(current, name);\n\n if (descriptor && typeof descriptor.value === 'function') {\n methods.set(name, descriptor.value);\n }\n }\n }\n\n return methods;\n}\n\n/**\n * Finds methods that a framework replaced while constructing the first instance.\n *\n * Some frameworks register methods by function identity, so replacing one of their wrappers would\n * break dispatch. The result is cached because frameworks commonly install their wrappers only\n * once; later constructions would no longer reveal which methods they manage.\n */\nfunction resolveFrameworkManagedMethods(\n prototype: object,\n obj: object,\n methodsBeforeConstruction: Map<string, unknown> | undefined,\n cached: ReadonlySet<string> | undefined,\n): ReadonlySet<string> {\n if (cached) {\n return cached;\n }\n\n const methodsAfterConstruction = resolvePrototypeMethods(Object.getPrototypeOf(obj) as object);\n const managed = new Set<string>();\n\n for (const [name, method] of methodsAfterConstruction) {\n const before = methodsBeforeConstruction?.get(name);\n\n if (before && before !== method) {\n managed.add(name);\n }\n }\n\n frameworkManagedMethodsCache.set(prototype, managed);\n\n return managed;\n}\n\ntype RpcInstanceState = {\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n /** Per-instance cache of the traced method wrappers, keyed by method name. Created on first use. */\n tracedMethods?: Map<string, UncheckedMethod>;\n};\n\n/**\n * Method names the runtime never dispatches over RPC, so wrapping them buys no tracing.\n *\n * Mirrors `isReservedName` in workerd (`src/workerd/api/worker-rpc.c++`): the runtime rejects these\n * before any property lookup happens. `fetch`, `alarm` and the `webSocket*` handlers are also\n * instrumented per-instance as own properties, and `constructor` is on every prototype.\n */\nconst RESERVED_RPC_METHOD_NAMES: ReadonlySet<string> = new Set([\n 'constructor',\n 'fetch',\n 'connect',\n 'alarm',\n 'webSocketMessage',\n 'webSocketClose',\n 'webSocketError',\n 'dup',\n]);\n\n// Prototype wrappers are shared by all instances, while SDK options and traced method caches are not.\nconst rpcInstanceStates = new WeakMap<object, RpcInstanceState>();\n\n/**\n * Adds trace propagation to a constructed Durable Object's RPC methods.\n *\n * RPC methods are wrapped on the prototype because Cloudflare dispatches them with the Durable\n * Object instance as the receiver. This preserves native private-field access and keeps the methods\n * visible to Cloudflare's RPC dispatcher. Built-in handlers, Agent handlers, and methods managed by\n * another framework are left untouched.\n *\n * Call this after all per-instance instrumentation has been applied.\n *\n * @param obj The constructed Durable Object instance.\n * @param options The resolved SDK options for this instance.\n * @param context The instrumented execution context for this instance.\n * @param excludedMethods Method names owned by another framework and therefore not safe to wrap.\n * @returns The same Durable Object instance, with eligible prototype methods instrumented.\n * @internal\n */\nexport function finalizeWithRpcInstrumentation<T extends object>(\n obj: T,\n options: CloudflareOptions,\n context: InstrumentedDurableObjectContext,\n excludedMethods?: ReadonlySet<string>,\n): T {\n rpcInstanceStates.set(obj, { options, context });\n\n instrumentPrototypeRpcMethods(obj, excludedMethods);\n\n return obj;\n}\n\n/**\n * Returns a prototype method when it is eligible for RPC instrumentation.\n */\nfunction getRpcMethodDescriptor(\n obj: object,\n prototype: object,\n methodName: string,\n excludedMethods?: ReadonlySet<string>,\n): PropertyDescriptor | undefined {\n if (\n RESERVED_RPC_METHOD_NAMES.has(methodName) ||\n Object.prototype.hasOwnProperty.call(obj, methodName) ||\n excludedMethods?.has(methodName)\n ) {\n return undefined;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);\n\n if (!descriptor || typeof descriptor.value !== 'function' || getInstrumented(descriptor.value)) {\n return undefined;\n }\n\n return descriptor;\n}\n\n/**\n * Wraps eligible methods on the instance's prototype chain once per class.\n */\nfunction instrumentPrototypeRpcMethods(obj: object, excludedMethods?: ReadonlySet<string>): void {\n let prototype: object | null = Object.getPrototypeOf(obj);\n\n while (prototype && prototype !== Object.prototype) {\n for (const methodName of Object.getOwnPropertyNames(prototype)) {\n const descriptor = getRpcMethodDescriptor(obj, prototype, methodName, excludedMethods);\n\n if (!descriptor) {\n continue;\n }\n\n const wrapped = createRpcPrototypeWrapper(methodName, descriptor.value as UncheckedMethod);\n\n try {\n Object.defineProperty(prototype, methodName, { ...descriptor, value: wrapped });\n } catch {}\n\n // Only the wrapper is marked, not the original method: `wrapMethodWithSentry` resolves\n // through the same global map and must not resolve the original to this wrapper,\n // which would recurse.\n markAsInstrumented(wrapped);\n }\n\n prototype = Object.getPrototypeOf(prototype);\n }\n}\n\n/**\n * Creates a prototype wrapper that traces RPC calls carrying Sentry metadata.\n *\n * The wrapper looks up SDK state from its receiver, allowing one prototype function to serve every\n * instance. Calls without RPC metadata or instance state use the original method directly. The\n * original function name and arity are preserved because frameworks may inspect them for dispatch.\n */\nfunction createRpcPrototypeWrapper(methodName: string, originalMethod: UncheckedMethod): UncheckedMethod {\n const wrapper = function (this: unknown, ...args: unknown[]): unknown {\n // Untraced calls are the common case — every internal call the instance makes to one of its\n // own methods lands here too — so check the arguments before touching per-instance state.\n if (!hasRpcMeta(args)) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const state = isObjectLike(this) ? rpcInstanceStates.get(this) : undefined;\n\n if (!state) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const tracedMethods = (state.tracedMethods ??= new Map());\n let traced = tracedMethods.get(methodName);\n\n if (!traced) {\n traced = wrapMethodWithSentry(\n {\n options: state.options,\n context: state.context,\n spanName: methodName,\n spanOp: RPC,\n origin: 'auto.faas.cloudflare.durable_object',\n },\n originalMethod,\n undefined,\n true,\n );\n tracedMethods.set(methodName, traced);\n }\n\n return Reflect.apply(traced, this, args);\n };\n\n Object.defineProperties(wrapper, {\n name: { value: originalMethod.name, configurable: true },\n length: { value: originalMethod.length, configurable: true },\n });\n\n return wrapper as UncheckedMethod;\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods by default:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * RPC methods (prototype methods) are instrumented too, so an incoming trace continues into them.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, DurableObjectClass: C): C {\n const InstrumentedClass = new Proxy(DurableObjectClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n // Recognizable for `_INTERNAL_wrapUnlessInstrumented`, so auto-instrumentation never nests wrappers.\n markAsInstrumented(InstrumentedClass);\n return InstrumentedClass;\n}\n\n/**\n * Instruments a Cloudflare [`agents`](https://www.npmjs.com/package/agents) Agent class with Sentry.\n *\n * An `Agent` is a Durable Object under the hood, so this applies the same instrumentation as\n * {@link instrumentDurableObjectWithSentry} (request transactions, `alarm`, WebSocket handlers, RPC\n * trace propagation, SQL spans) and additionally captures Agent-specific telemetry via\n * `instrumentCloudflareAgent`:\n *\n * - **Callable RPC spans** — a span (op `rpc`) for each `@callable()` method invoked over WebSocket.\n * - **Breadcrumbs** — for every Agent observability event (`rpc`, `state:update`, `connect`,\n * `disconnect`, `schedule:*`, `queue:*`, `workflow:*`, `email:*`, `mcp:*`, ...).\n *\n * Cloudflare Workers cannot auto-instrument, so the Agent class must be wrapped manually.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param AgentClass The Agent class to instrument.\n * @returns The instrumented Agent class.\n *\n * @example\n * ```ts\n * import { Agent, callable, routeAgentRequest } from 'agents';\n * import * as Sentry from '@sentry/cloudflare';\n *\n * class MyAgentBase extends Agent<Env> {\n * @callable()\n * async greet(name: string): Promise<string> {\n * return `Hello, ${name}!`;\n * }\n * }\n *\n * export const MyAgent = Sentry.instrumentAgentWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyAgentBase,\n * );\n * ```\n */\nexport function instrumentAgentWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, AgentClass: C): C {\n const InstrumentedClass = new Proxy(AgentClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n instrumentCloudflareAgent(obj);\n\n // Apply RPC prototype-method instrumentation last, so the Agent-specific own-property\n // handlers we just installed are excluded from RPC method tracing. Methods the Agent\n // framework installed itself are excluded too — `instrumentCloudflareAgent` traces those by\n // wrapping the dispatch instead of the method.\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n markAsInstrumented(InstrumentedClass);\n return InstrumentedClass;\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","options","getFinalOptions","instrumentContext","instrumentEnv","instrumentDurableObjectHandlers","getInstrumented","markAsInstrumented","hasRpcMeta","isObjectLike","wrapMethodWithSentry","RPC","instrumentCloudflareAgent"],"mappings":"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"}
1
+ {"version":3,"file":"durableobject.js","sources":["../../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/unbound-method */\nimport { RPC } from '@sentry/conventions/op';\nimport { getDefaultIsolationScope, getIsolationScope, isObjectLike, startNewTrace } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';\nimport type { CloudflareOptions } from './client';\nimport { getInstrumented, markAsInstrumented } from './instrument';\nimport { instrumentDurableObjectHandlers } from './instrumentations/instrumentDurableObjectHandlers';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { hasRpcMeta } from './utils/rpcMeta';\nimport { instrumentCloudflareAgent } from './instrumentations/agents';\nimport type { DefaultEnv, ResolveEnv, StrictCloudflareOptions } from './types';\nimport { type UncheckedMethod, wrapMethodWithSentry } from './wrapMethodWithSentry';\n\n/**\n * The instrumented context passed between the shared construction helpers.\n *\n * This is intentionally `any` rather than `ReturnType<typeof instrumentContext<DurableObjectState>>`.\n * A concrete `DurableObjectState` here forces `tsc` to structurally relate its `storage: SqlStorage`\n * graph against the `ExecutionContext | InstrumentedDurableObjectState` parameter of\n * `wrapMethodWithSentry`, while the RPC-branded `DurableObject` from `cloudflare:workers` is also in\n * scope. That union comparison explodes (1296×1296) and hangs the type build. The original inline\n * implementation avoided this only incidentally, because `ctx` reached it as `any` through the Proxy\n * `construct` trap. Keeping the shared context `any` preserves that behavior.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentedDurableObjectContext = any;\n\n/**\n * Constructs a Durable Object instance and instruments its built-in handler methods\n * (`fetch`, `alarm`, `webSocketMessage`, `webSocketClose`, `webSocketError`).\n *\n * This is the shared construction path used by both {@link instrumentDurableObjectWithSentry}\n * and {@link instrumentAgentWithSentry}. It intentionally does NOT apply the RPC prototype-method\n * instrumentation — callers apply that last via {@link finalizeWithRpcInstrumentation}, after any\n * additional per-instance instrumentation has been layered onto the returned object.\n *\n * @internal\n */\nexport function constructInstrumentedDurableObject<E, T extends DurableObject<E>>(\n target: new (state: DurableObjectState, env: E) => T,\n ctx: DurableObjectState,\n env: E,\n newTarget: NewableFunction,\n optionsCallback: (env: E) => CloudflareOptions,\n): {\n obj: T;\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n frameworkManagedMethods: ReadonlySet<string>;\n} {\n setAsyncLocalStorageAsyncContextStrategy();\n const options = getFinalOptions(optionsCallback(env), env);\n // See InstrumentedDurableObjectContext — `ctx` is widened to `any` so the concrete\n // `DurableObjectState` type never enters the checker's relation graph in this module.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const context = instrumentContext(ctx as any);\n const instrumentedEnv = instrumentEnv(env as Record<string, unknown>, options);\n\n const prototype = (newTarget as unknown as { prototype?: object }).prototype ?? target.prototype;\n const cachedFrameworkManagedMethods = frameworkManagedMethodsCache.get(prototype);\n const methodsBeforeConstruction = cachedFrameworkManagedMethods ? undefined : resolvePrototypeMethods(prototype);\n\n // Pass `newTarget` so that subclasses of the instrumented class (e.g. the wrapper classes\n // created by wrangler's local dev tooling or `@cloudflare/vitest-pool-workers`) keep their\n // own prototype — otherwise subclass methods disappear and `instanceof` checks break.\n const obj = Reflect.construct(target, [context, instrumentedEnv], newTarget) as T;\n\n const frameworkManagedMethods = resolveFrameworkManagedMethods(\n prototype,\n obj,\n methodsBeforeConstruction,\n cachedFrameworkManagedMethods,\n );\n\n instrumentDurableObjectHandlers(obj, options, context);\n\n return { obj, options, context, frameworkManagedMethods };\n}\n\nconst frameworkManagedMethodsCache = new WeakMap<object, ReadonlySet<string>>();\n\n/**\n * Collects the methods visible from a prototype, using normal property lookup precedence.\n * Methods inherited from `Object.prototype` are excluded because they cannot be Durable Object RPC methods.\n */\nfunction resolvePrototypeMethods(prototype: object | null): Map<string, unknown> {\n const methods = new Map<string, unknown>();\n\n for (let current = prototype; current && current !== Object.prototype; current = Object.getPrototypeOf(current)) {\n for (const name of Object.getOwnPropertyNames(current)) {\n // The first occurrence wins, mirroring what a property lookup on the instance would find\n if (name === 'constructor' || methods.has(name)) {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(current, name);\n\n if (descriptor && typeof descriptor.value === 'function') {\n methods.set(name, descriptor.value);\n }\n }\n }\n\n return methods;\n}\n\n/**\n * Finds methods that a framework replaced while constructing the first instance.\n *\n * Some frameworks register methods by function identity, so replacing one of their wrappers would\n * break dispatch. The result is cached because frameworks commonly install their wrappers only\n * once; later constructions would no longer reveal which methods they manage.\n */\nfunction resolveFrameworkManagedMethods(\n prototype: object,\n obj: object,\n methodsBeforeConstruction: Map<string, unknown> | undefined,\n cached: ReadonlySet<string> | undefined,\n): ReadonlySet<string> {\n if (cached) {\n return cached;\n }\n\n const methodsAfterConstruction = resolvePrototypeMethods(Object.getPrototypeOf(obj) as object);\n const managed = new Set<string>();\n\n for (const [name, method] of methodsAfterConstruction) {\n const before = methodsBeforeConstruction?.get(name);\n\n if (before && before !== method) {\n managed.add(name);\n }\n }\n\n frameworkManagedMethodsCache.set(prototype, managed);\n\n return managed;\n}\n\ntype RpcInstanceState = {\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n /** Per-instance cache of the instrumented method wrappers, keyed by method name. Created on first use. */\n instrumentedMethods?: Map<string, UncheckedMethod>;\n};\n\n/**\n * Method names the runtime never dispatches over RPC, so wrapping them buys no tracing.\n *\n * Mirrors `isReservedName` in workerd (`src/workerd/api/worker-rpc.c++`): the runtime rejects these\n * before any property lookup happens. `fetch`, `alarm` and the `webSocket*` handlers are also\n * instrumented per-instance as own properties, and `constructor` is on every prototype.\n */\nconst RESERVED_RPC_METHOD_NAMES: ReadonlySet<string> = new Set([\n 'constructor',\n 'fetch',\n 'connect',\n 'alarm',\n 'webSocketMessage',\n 'webSocketClose',\n 'webSocketError',\n 'dup',\n]);\n\n// Prototype wrappers are shared by all instances, while SDK options and traced method caches are not.\nconst rpcInstanceStates = new WeakMap<object, RpcInstanceState>();\n\n/**\n * Instruments a constructed Durable Object's RPC methods.\n *\n * RPC methods are wrapped on the prototype because Cloudflare dispatches them with the Durable\n * Object instance as the receiver. This preserves native private-field access and keeps the methods\n * visible to Cloudflare's RPC dispatcher. Built-in handlers, Agent handlers, and methods managed by\n * another framework are left untouched.\n *\n * Call this after all per-instance instrumentation has been applied.\n *\n * @param obj The constructed Durable Object instance.\n * @param options The resolved SDK options for this instance.\n * @param context The instrumented execution context for this instance.\n * @param excludedMethods Method names owned by another framework and therefore not safe to wrap.\n * @returns The same Durable Object instance, with eligible prototype methods instrumented.\n * @internal\n */\nexport function finalizeWithRpcInstrumentation<T extends object>(\n obj: T,\n options: CloudflareOptions,\n context: InstrumentedDurableObjectContext,\n excludedMethods?: ReadonlySet<string>,\n): T {\n rpcInstanceStates.set(obj, { options, context });\n\n instrumentPrototypeRpcMethods(obj, excludedMethods);\n\n return obj;\n}\n\n/**\n * Returns a prototype method when it is eligible for RPC instrumentation.\n */\nfunction getRpcMethodDescriptor(\n obj: object,\n prototype: object,\n methodName: string,\n excludedMethods?: ReadonlySet<string>,\n): PropertyDescriptor | undefined {\n if (\n RESERVED_RPC_METHOD_NAMES.has(methodName) ||\n Object.prototype.hasOwnProperty.call(obj, methodName) ||\n excludedMethods?.has(methodName)\n ) {\n return undefined;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);\n\n if (!descriptor || typeof descriptor.value !== 'function' || getInstrumented(descriptor.value)) {\n return undefined;\n }\n\n return descriptor;\n}\n\n/**\n * Wraps eligible methods on the instance's prototype chain once per class.\n */\nfunction instrumentPrototypeRpcMethods(obj: object, excludedMethods?: ReadonlySet<string>): void {\n let prototype: object | null = Object.getPrototypeOf(obj);\n\n while (prototype && prototype !== Object.prototype) {\n for (const methodName of Object.getOwnPropertyNames(prototype)) {\n const descriptor = getRpcMethodDescriptor(obj, prototype, methodName, excludedMethods);\n\n if (!descriptor) {\n continue;\n }\n\n const wrapped = createRpcPrototypeWrapper(methodName, descriptor.value as UncheckedMethod);\n\n try {\n Object.defineProperty(prototype, methodName, { ...descriptor, value: wrapped });\n } catch {}\n\n // Only the wrapper is marked, not the original method: `wrapMethodWithSentry` resolves\n // through the same global map and must not resolve the original to this wrapper,\n // which would recurse.\n markAsInstrumented(wrapped);\n }\n\n prototype = Object.getPrototypeOf(prototype);\n }\n}\n\n/**\n * Returns the instance's instrumented wrapper for an RPC method, creating it on first use.\n */\nfunction getInstrumentedRpcMethod(\n state: RpcInstanceState,\n methodName: string,\n originalMethod: UncheckedMethod,\n): UncheckedMethod {\n const instrumentedMethods = (state.instrumentedMethods ??= new Map());\n let instrumented = instrumentedMethods.get(methodName);\n\n if (!instrumented) {\n instrumented = wrapMethodWithSentry(\n {\n options: state.options,\n context: state.context,\n spanName: rpcMeta => (rpcMeta ? methodName : undefined),\n spanOp: RPC,\n origin: 'auto.faas.cloudflare.durable_object',\n },\n originalMethod,\n undefined,\n true,\n );\n instrumentedMethods.set(methodName, instrumented);\n }\n\n return instrumented;\n}\n\n/**\n * Creates a prototype wrapper that instruments external RPC calls.\n *\n * The wrapper looks up SDK state from its receiver, allowing one prototype function to serve every\n * instance. A call carrying Sentry metadata continues that trace in an `rpc` span. A call without it\n * still gets a client, so its errors, logs and metrics are captured, but no span. Calls the instance\n * makes to its own methods run the original method directly. The original function name and arity\n * are preserved because frameworks may inspect them for dispatch.\n */\nfunction createRpcPrototypeWrapper(methodName: string, originalMethod: UncheckedMethod): UncheckedMethod {\n const wrapper = function (this: unknown, ...args: unknown[]): unknown {\n const traced = hasRpcMeta(args);\n\n // workerd dispatches an incoming RPC call outside any async context, so a call made while an\n // invocation is already in flight comes from the instance itself (`this.helper()` inside\n // `fetch`, `alarm` or another RPC method). Check that before touching per-instance state.\n if (!traced && getIsolationScope() !== getDefaultIsolationScope()) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const state = isObjectLike(this) ? rpcInstanceStates.get(this) : undefined;\n\n if (!state) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const instrumented = getInstrumentedRpcMethod(state, methodName, originalMethod);\n\n if (traced) {\n return Reflect.apply(instrumented, this, args);\n }\n\n // Unlike a WorkerEntrypoint, a Durable Object instance is long-lived and serves overlapping\n // calls. Without a new trace, every untraced call would share the trace of the default scope.\n return startNewTrace(() => Reflect.apply(instrumented, this, args));\n };\n\n Object.defineProperties(wrapper, {\n name: { value: originalMethod.name, configurable: true },\n length: { value: originalMethod.length, configurable: true },\n });\n\n return wrapper as UncheckedMethod;\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods by default:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * RPC methods (prototype methods) are instrumented too: an incoming trace continues into them, and\n * errors, logs and metrics are captured whether or not the caller propagates a trace.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, DurableObjectClass: C): C {\n const InstrumentedClass = new Proxy(DurableObjectClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n // Recognizable for `_INTERNAL_wrapUnlessInstrumented`, so auto-instrumentation never nests wrappers.\n markAsInstrumented(InstrumentedClass);\n return InstrumentedClass;\n}\n\n/**\n * Instruments a Cloudflare [`agents`](https://www.npmjs.com/package/agents) Agent class with Sentry.\n *\n * An `Agent` is a Durable Object under the hood, so this applies the same instrumentation as\n * {@link instrumentDurableObjectWithSentry} (request transactions, `alarm`, WebSocket handlers, RPC\n * trace propagation, SQL spans) and additionally captures Agent-specific telemetry via\n * `instrumentCloudflareAgent`:\n *\n * - **Callable RPC spans** — a span (op `rpc`) for each `@callable()` method invoked over WebSocket.\n * - **Breadcrumbs** — for every Agent observability event (`rpc`, `state:update`, `connect`,\n * `disconnect`, `schedule:*`, `queue:*`, `workflow:*`, `email:*`, `mcp:*`, ...).\n *\n * Cloudflare Workers cannot auto-instrument, so the Agent class must be wrapped manually.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param AgentClass The Agent class to instrument.\n * @returns The instrumented Agent class.\n *\n * @example\n * ```ts\n * import { Agent, callable, routeAgentRequest } from 'agents';\n * import * as Sentry from '@sentry/cloudflare';\n *\n * class MyAgentBase extends Agent<Env> {\n * @callable()\n * async greet(name: string): Promise<string> {\n * return `Hello, ${name}!`;\n * }\n * }\n *\n * export const MyAgent = Sentry.instrumentAgentWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyAgentBase,\n * );\n * ```\n */\nexport function instrumentAgentWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, AgentClass: C): C {\n const InstrumentedClass = new Proxy(AgentClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n instrumentCloudflareAgent(obj);\n\n // Apply RPC prototype-method instrumentation last, so the Agent-specific own-property\n // handlers we just installed are excluded from RPC method tracing. Methods the Agent\n // framework installed itself are excluded too — `instrumentCloudflareAgent` traces those by\n // wrapping the dispatch instead of the method.\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n markAsInstrumented(InstrumentedClass);\n return InstrumentedClass;\n}\n"],"names":["setAsyncLocalStorageAsyncContextStrategy","options","getFinalOptions","instrumentContext","instrumentEnv","instrumentDurableObjectHandlers","getInstrumented","markAsInstrumented","wrapMethodWithSentry","RPC","hasRpcMeta","getIsolationScope","getDefaultIsolationScope","isObjectLike","startNewTrace","instrumentCloudflareAgent"],"mappings":"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"}
@@ -22,7 +22,6 @@ exports.SDK_VERSION = core.SDK_VERSION;
22
22
  exports.SEMANTIC_ATTRIBUTE_SENTRY_OP = core.SEMANTIC_ATTRIBUTE_SENTRY_OP;
23
23
  exports.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN;
24
24
  exports.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = core.SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE;
25
- exports.SENTRY_SEGMENT_NAME_SOURCE = core.SENTRY_SEGMENT_NAME_SOURCE;
26
25
  exports.Scope = core.Scope;
27
26
  exports.addBreadcrumb = core.addBreadcrumb;
28
27
  exports.addEventProcessor = core.addEventProcessor;
@@ -100,12 +99,17 @@ exports.withStreamedSpan = core.withStreamedSpan;
100
99
  exports.zodErrorsIntegration = core.zodErrorsIntegration;
101
100
  exports.trpcMiddleware = server.trpcMiddleware;
102
101
  exports.wrapMcpServerWithSentry = server.wrapMcpServerWithSentry;
102
+ exports.createFlueInstrumentation = serverUtils.createFlueInstrumentation;
103
103
  exports.createLangChainCallbackHandler = serverUtils.createLangChainCallbackHandler;
104
+ exports.eveConversationHook = serverUtils.eveConversationHook;
105
+ exports.eveIntegration = serverUtils.eveIntegration;
106
+ exports.getInstrumentedModuleNames = serverUtils.getInstrumentedModuleNames;
104
107
  exports.getOtlpTracesEndpoint = serverUtils.getOtlpTracesEndpoint;
105
108
  exports.instrumentAnthropicAiClient = serverUtils.instrumentAnthropicAiClient;
106
109
  exports.instrumentCreateReactAgent = serverUtils.instrumentCreateReactAgent;
107
110
  exports.instrumentGoogleGenAIClient = serverUtils.instrumentGoogleGenAIClient;
108
111
  exports.instrumentLangChainEmbeddings = serverUtils.instrumentLangChainEmbeddings;
112
+ exports.instrumentMistralAiClient = serverUtils.instrumentMistralAiClient;
109
113
  exports.instrumentOpenAiClient = serverUtils.instrumentOpenAiClient;
110
114
  exports.instrumentPostgresJsSql = serverUtils.instrumentPostgresJsSql;
111
115
  exports.instrumentStateGraph = serverUtils.instrumentStateGraph;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -17,6 +17,12 @@ function instrumentDurableObjectNamespace(namespace, propagateRpcTrace = false)
17
17
  return instrumentDurableObjectStub(stub, propagateRpcTrace);
18
18
  };
19
19
  }
20
+ if (prop === "jurisdiction") {
21
+ return function(...args) {
22
+ const subnamespace = Reflect.apply(value, target, args);
23
+ return instrumentDurableObjectNamespace(subnamespace, propagateRpcTrace);
24
+ };
25
+ }
20
26
  return value.bind(target);
21
27
  }
22
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentDurableObjectNamespace.js","sources":["../../../../src/instrumentations/instrumentDurableObjectNamespace.ts"],"sourcesContent":["import type { DurableObjectNamespace, DurableObjectStub } from '@cloudflare/workers-types';\nimport { appendRpcMeta } from '../utils/rpcMeta';\nimport { instrumentFetcher } from './worker/instrumentFetcher';\n\n// Built-in DurableObjectStub methods that are not RPC calls.\nexport const STUB_NON_RPC_METHODS = new Set(['fetch', 'connect', 'dup']);\n\n/**\n * Instruments a DurableObjectNamespace binding to create spans for DO interactions.\n *\n * Wraps:\n * - `namespace.get(id)` / `namespace.getByName(name)` with a span + instruments returned stub\n * - `namespace.idFromName(name)` / `namespace.idFromString(id)` / `namespace.newUniqueId()` with breadcrumbs\n *\n * @param namespace - The DurableObjectNamespace to instrument\n * @param propagateRpcTrace - Whether RPC method calls on the returned stubs carry trace context\n */\nexport function instrumentDurableObjectNamespace(\n namespace: DurableObjectNamespace,\n propagateRpcTrace = false,\n): DurableObjectNamespace {\n return new Proxy(namespace, {\n get(target, prop, _receiver) {\n const value = Reflect.get(target, prop) as unknown;\n\n if (typeof value !== 'function') {\n return value;\n }\n\n if (prop === 'get' || prop === 'getByName') {\n return function (this: unknown, ...args: unknown[]) {\n const stub = Reflect.apply(value, target, args);\n\n return instrumentDurableObjectStub(stub, propagateRpcTrace);\n };\n }\n\n return value.bind(target);\n },\n });\n}\n\n/**\n * Instruments a DurableObjectStub to create spans for outgoing fetch calls\n * and propagate trace context across RPC calls.\n *\n * @param stub - The DurableObjectStub to instrument\n * @param propagateRpcTrace - Whether RPC method calls carry trace context\n */\nfunction instrumentDurableObjectStub(stub: DurableObjectStub, propagateRpcTrace: boolean): DurableObjectStub {\n return new Proxy(stub, {\n get(target, prop) {\n const value = Reflect.get(target, prop);\n\n if (prop === 'fetch' && typeof value === 'function') {\n return instrumentFetcher((...args) => Reflect.apply(value, target, args));\n }\n\n if (\n propagateRpcTrace &&\n typeof value === 'function' &&\n typeof prop === 'string' &&\n !STUB_NON_RPC_METHODS.has(prop)\n ) {\n return (...args: unknown[]) => Reflect.apply(value, target, appendRpcMeta(args));\n }\n\n return value;\n },\n });\n}\n"],"names":["instrumentFetcher","appendRpcMeta"],"mappings":";;;;;AAKO,MAAM,uCAAuB,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,SAAA,EAAW,KAAK,CAAC;AAYhE,SAAS,gCAAA,CACd,SAAA,EACA,iBAAA,GAAoB,KAAA,EACI;AACxB,EAAA,OAAO,IAAI,MAAM,SAAA,EAAW;AAAA,IAC1B,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW;AAC3B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAEtC,MAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,IAAI,IAAA,KAAS,KAAA,IAAS,IAAA,KAAS,WAAA,EAAa;AAC1C,QAAA,OAAO,YAA4B,IAAA,EAAiB;AAClD,UAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,QAAQ,IAAI,CAAA;AAE9C,UAAA,OAAO,2BAAA,CAA4B,MAAM,iBAAiB,CAAA;AAAA,QAC5D,CAAA;AAAA,MACF;AAEA,MAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,IAC1B;AAAA,GACD,CAAA;AACH;AASA,SAAS,2BAAA,CAA4B,MAAyB,iBAAA,EAA+C;AAC3G,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAEtC,MAAA,IAAI,IAAA,KAAS,OAAA,IAAW,OAAO,KAAA,KAAU,UAAA,EAAY;AACnD,QAAA,OAAOA,mCAAA,CAAkB,IAAI,IAAA,KAAS,OAAA,CAAQ,MAAM,KAAA,EAAO,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,MAC1E;AAEA,MAAA,IACE,iBAAA,IACA,OAAO,KAAA,KAAU,UAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,CAAC,oBAAA,CAAqB,GAAA,CAAI,IAAI,CAAA,EAC9B;AACA,QAAA,OAAO,CAAA,GAAI,SAAoB,OAAA,CAAQ,KAAA,CAAM,OAAO,MAAA,EAAQC,qBAAA,CAAc,IAAI,CAAC,CAAA;AAAA,MACjF;AAEA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACD,CAAA;AACH;;;;;"}
1
+ {"version":3,"file":"instrumentDurableObjectNamespace.js","sources":["../../../../src/instrumentations/instrumentDurableObjectNamespace.ts"],"sourcesContent":["import type { DurableObjectNamespace, DurableObjectStub } from '@cloudflare/workers-types';\nimport { appendRpcMeta } from '../utils/rpcMeta';\nimport { instrumentFetcher } from './worker/instrumentFetcher';\n\n// Built-in DurableObjectStub methods that are not RPC calls.\nexport const STUB_NON_RPC_METHODS = new Set(['fetch', 'connect', 'dup']);\n\n/**\n * Instruments a DurableObjectNamespace binding to create spans for DO interactions.\n *\n * Wraps:\n * - `namespace.get(id)` / `namespace.getByName(name)` with a span + instruments returned stub\n * - `namespace.jurisdiction(name)` by instrumenting the returned namespace the same way\n * - `namespace.idFromName(name)` / `namespace.idFromString(id)` / `namespace.newUniqueId()` with breadcrumbs\n *\n * @param namespace - The DurableObjectNamespace to instrument\n * @param propagateRpcTrace - Whether RPC method calls on the returned stubs carry trace context\n */\nexport function instrumentDurableObjectNamespace(\n namespace: DurableObjectNamespace,\n propagateRpcTrace = false,\n): DurableObjectNamespace {\n return new Proxy(namespace, {\n get(target, prop, _receiver) {\n const value = Reflect.get(target, prop) as unknown;\n\n if (typeof value !== 'function') {\n return value;\n }\n\n if (prop === 'get' || prop === 'getByName') {\n return function (this: unknown, ...args: unknown[]) {\n const stub = Reflect.apply(value, target, args);\n\n return instrumentDurableObjectStub(stub, propagateRpcTrace);\n };\n }\n\n if (prop === 'jurisdiction') {\n return function (this: unknown, ...args: unknown[]) {\n const subnamespace = Reflect.apply(value, target, args);\n\n return instrumentDurableObjectNamespace(subnamespace, propagateRpcTrace);\n };\n }\n\n return value.bind(target);\n },\n });\n}\n\n/**\n * Instruments a DurableObjectStub to create spans for outgoing fetch calls\n * and propagate trace context across RPC calls.\n *\n * @param stub - The DurableObjectStub to instrument\n * @param propagateRpcTrace - Whether RPC method calls carry trace context\n */\nfunction instrumentDurableObjectStub(stub: DurableObjectStub, propagateRpcTrace: boolean): DurableObjectStub {\n return new Proxy(stub, {\n get(target, prop) {\n const value = Reflect.get(target, prop);\n\n if (prop === 'fetch' && typeof value === 'function') {\n return instrumentFetcher((...args) => Reflect.apply(value, target, args));\n }\n\n if (\n propagateRpcTrace &&\n typeof value === 'function' &&\n typeof prop === 'string' &&\n !STUB_NON_RPC_METHODS.has(prop)\n ) {\n return (...args: unknown[]) => Reflect.apply(value, target, appendRpcMeta(args));\n }\n\n return value;\n },\n });\n}\n"],"names":["instrumentFetcher","appendRpcMeta"],"mappings":";;;;;AAKO,MAAM,uCAAuB,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,SAAA,EAAW,KAAK,CAAC;AAahE,SAAS,gCAAA,CACd,SAAA,EACA,iBAAA,GAAoB,KAAA,EACI;AACxB,EAAA,OAAO,IAAI,MAAM,SAAA,EAAW;AAAA,IAC1B,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW;AAC3B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAEtC,MAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,IAAI,IAAA,KAAS,KAAA,IAAS,IAAA,KAAS,WAAA,EAAa;AAC1C,QAAA,OAAO,YAA4B,IAAA,EAAiB;AAClD,UAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,QAAQ,IAAI,CAAA;AAE9C,UAAA,OAAO,2BAAA,CAA4B,MAAM,iBAAiB,CAAA;AAAA,QAC5D,CAAA;AAAA,MACF;AAEA,MAAA,IAAI,SAAS,cAAA,EAAgB;AAC3B,QAAA,OAAO,YAA4B,IAAA,EAAiB;AAClD,UAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,QAAQ,IAAI,CAAA;AAEtD,UAAA,OAAO,gCAAA,CAAiC,cAAc,iBAAiB,CAAA;AAAA,QACzE,CAAA;AAAA,MACF;AAEA,MAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,IAC1B;AAAA,GACD,CAAA;AACH;AASA,SAAS,2BAAA,CAA4B,MAAyB,iBAAA,EAA+C;AAC3G,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAEtC,MAAA,IAAI,IAAA,KAAS,OAAA,IAAW,OAAO,KAAA,KAAU,UAAA,EAAY;AACnD,QAAA,OAAOA,mCAAA,CAAkB,IAAI,IAAA,KAAS,OAAA,CAAQ,MAAM,KAAA,EAAO,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,MAC1E;AAEA,MAAA,IACE,iBAAA,IACA,OAAO,KAAA,KAAU,UAAA,IACjB,OAAO,IAAA,KAAS,QAAA,IAChB,CAAC,oBAAA,CAAqB,GAAA,CAAI,IAAI,CAAA,EAC9B;AACA,QAAA,OAAO,CAAA,GAAI,SAAoB,OAAA,CAAQ,KAAA,CAAM,OAAO,MAAA,EAAQC,qBAAA,CAAc,IAAI,CAAC,CAAA;AAAA,MACjF;AAEA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACD,CAAA;AACH;;;;;"}
@@ -11,40 +11,41 @@ function instrumentD1PreparedStatementQueries(statement, query) {
11
11
  if (patchedStatement.has(statement)) {
12
12
  return statement;
13
13
  }
14
+ const queryText = query ? serverUtils.sanitizeSqlQuery(query) : void 0;
14
15
  statement.first = new Proxy(statement.first, {
15
16
  apply(target, thisArg, args) {
16
- return core.startSpan(createStartSpanOptions(query, "first"), async () => {
17
+ return core.startSpan(createStartSpanOptions(queryText, "first"), async () => {
17
18
  const res = await Reflect.apply(target, thisArg, args);
18
- createD1Breadcrumb(query, "first");
19
+ createD1Breadcrumb(queryText, "first");
19
20
  return res;
20
21
  });
21
22
  }
22
23
  });
23
24
  statement.run = new Proxy(statement.run, {
24
25
  apply(target, thisArg, args) {
25
- return core.startSpan(createStartSpanOptions(query, "run"), async (span) => {
26
+ return core.startSpan(createStartSpanOptions(queryText, "run"), async (span) => {
26
27
  const d1Response = await Reflect.apply(target, thisArg, args);
27
28
  applyD1ReturnObjectToSpan(span, d1Response);
28
- createD1Breadcrumb(query, "run", d1Response);
29
+ createD1Breadcrumb(queryText, "run", d1Response);
29
30
  return d1Response;
30
31
  });
31
32
  }
32
33
  });
33
34
  statement.all = new Proxy(statement.all, {
34
35
  apply(target, thisArg, args) {
35
- return core.startSpan(createStartSpanOptions(query, "all"), async (span) => {
36
+ return core.startSpan(createStartSpanOptions(queryText, "all"), async (span) => {
36
37
  const d1Result = await Reflect.apply(target, thisArg, args);
37
38
  applyD1ReturnObjectToSpan(span, d1Result);
38
- createD1Breadcrumb(query, "all", d1Result);
39
+ createD1Breadcrumb(queryText, "all", d1Result);
39
40
  return d1Result;
40
41
  });
41
42
  }
42
43
  });
43
44
  statement.raw = new Proxy(statement.raw, {
44
45
  apply(target, thisArg, args) {
45
- return core.startSpan(createStartSpanOptions(query, "raw"), async () => {
46
+ return core.startSpan(createStartSpanOptions(queryText, "raw"), async () => {
46
47
  const res = await Reflect.apply(target, thisArg, args);
47
- createD1Breadcrumb(query, "raw");
48
+ createD1Breadcrumb(queryText, "raw");
48
49
  return res;
49
50
  });
50
51
  }
@@ -73,27 +74,27 @@ function getAttributesFromD1Response(d1Result) {
73
74
  "cloudflare.d1.rows_written": d1Result.meta.rows_written
74
75
  };
75
76
  }
76
- function createD1Breadcrumb(query, type, d1Result) {
77
+ function createD1Breadcrumb(message, type, d1Result) {
77
78
  core.addBreadcrumb({
78
79
  category: "query",
79
- message: query,
80
+ message,
80
81
  data: {
81
82
  ...d1Result ? getAttributesFromD1Response(d1Result) : {},
82
83
  "db.operation.name": type
83
84
  }
84
85
  });
85
86
  }
86
- function createStartSpanOptions(query, type) {
87
- const querySummary = query ? serverUtils.getSqlQuerySummary(serverUtils.sanitizeSqlQuery(query)) : void 0;
87
+ function createStartSpanOptions(queryText, type) {
88
+ const querySummary = queryText ? serverUtils.getSqlQuerySummary(queryText) : void 0;
88
89
  const client = core.getClient();
89
- const name = client && core.hasSpanStreamingEnabled(client) ? querySummary || "cloudflare-d1" : query;
90
+ const name = client && core.hasSpanStreamingEnabled(client) ? querySummary || "cloudflare-d1" : queryText ?? "cloudflare-d1";
90
91
  return {
91
92
  name,
92
93
  attributes: {
93
94
  [attributes.SENTRY_OP]: op.DB_QUERY,
94
95
  "db.system.name": "cloudflare-d1",
95
96
  "db.operation.name": type,
96
- "db.query.text": query,
97
+ "db.query.text": queryText,
97
98
  "db.query.summary": querySummary,
98
99
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.db.cloudflare.d1"
99
100
  }
@@ -111,7 +112,7 @@ function instrumentBatch(batch) {
111
112
  return new Proxy(batch, {
112
113
  apply(target, thisArg, args) {
113
114
  const statements = args[0];
114
- const queryText = statements.map((statement) => statement.statement ?? "").filter(Boolean).join("\n");
115
+ const queryText = statements.map((statement) => statement.statement ?? "").filter(Boolean).map((statement) => serverUtils.sanitizeSqlQuery(statement)).join("\n");
115
116
  return core.startSpan(
116
117
  {
117
118
  name: "D1 batch",
@@ -144,9 +145,10 @@ function _instrumentD1(db) {
144
145
  db.exec = new Proxy(db.exec, {
145
146
  apply(target, thisArg, args) {
146
147
  const [query] = args;
147
- return core.startSpan(createStartSpanOptions(query, "exec"), async () => {
148
+ const queryText = query ? serverUtils.sanitizeSqlQuery(query) : void 0;
149
+ return core.startSpan(createStartSpanOptions(queryText, "exec"), async () => {
148
150
  const res = await Reflect.apply(target, thisArg, args);
149
- createD1Breadcrumb(query, "exec");
151
+ createD1Breadcrumb(queryText, "exec");
150
152
  return res;
151
153
  });
152
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentD1.js","sources":["../../../../../src/instrumentations/worker/instrumentD1.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport type { D1Database, D1DatabaseSession, D1PreparedStatement, D1Response } from '@cloudflare/workers-types';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { DB_QUERY } from '@sentry/conventions/op';\nimport type { Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n hasSpanStreamingEnabled,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { getSqlQuerySummary, sanitizeSqlQuery } from '@sentry/server-utils';\nimport { ensureInstrumented } from '../../instrument';\n\n// Patching is based on internal Cloudflare D1 API\n// https://github.com/cloudflare/workerd/blob/cd5279e7b305003f1d9c851e73efa9d67e4b68b2/src/cloudflare/internal/d1-api.ts\n\nconst patchedStatement = new WeakSet<D1PreparedStatement>();\n\n/**\n * Patches the query methods of a Cloudflare D1 prepared statement with Sentry.\n */\nfunction instrumentD1PreparedStatementQueries(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n if (patchedStatement.has(statement)) {\n return statement;\n }\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.first = new Proxy(statement.first, {\n apply(target, thisArg, args: Parameters<typeof statement.first>) {\n return startSpan(createStartSpanOptions(query, 'first'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'first');\n return res;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.run = new Proxy(statement.run, {\n apply(target, thisArg, args: Parameters<typeof statement.run>) {\n return startSpan(createStartSpanOptions(query, 'run'), async span => {\n const d1Response = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Response);\n createD1Breadcrumb(query, 'run', d1Response);\n return d1Response;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.all = new Proxy(statement.all, {\n apply(target, thisArg, args: Parameters<typeof statement.all>) {\n return startSpan(createStartSpanOptions(query, 'all'), async span => {\n const d1Result = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Result);\n createD1Breadcrumb(query, 'all', d1Result);\n return d1Result;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.raw = new Proxy(statement.raw, {\n apply(target, thisArg, args: Parameters<typeof statement.raw>) {\n return startSpan(createStartSpanOptions(query, 'raw'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'raw');\n return res;\n });\n },\n });\n\n patchedStatement.add(statement);\n\n return statement;\n}\n\n/**\n * Instruments a Cloudflare D1 prepared statement with Sentry.\n *\n * This is meant to be used as a top-level call, under the hood it calls `instrumentD1PreparedStatementQueries`\n * to patch the query methods. The reason for this abstraction is to ensure that the `bind` method is also patched.\n */\nfunction instrumentD1PreparedStatement(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n // statement.bind() returns a new instance of D1PreparedStatement, so we have to patch it as well.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.bind = new Proxy(statement.bind, {\n apply(target, thisArg, args: Parameters<typeof statement.bind>) {\n return instrumentD1PreparedStatementQueries(Reflect.apply(target, thisArg, args), query);\n },\n });\n\n return instrumentD1PreparedStatementQueries(statement, query);\n}\n\n/**\n * Add D1Response meta information to a span.\n *\n * See: https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#return-object\n */\nfunction applyD1ReturnObjectToSpan(span: Span, d1Result: D1Response): void {\n if (!d1Result.success) {\n span.setStatus({ code: SPAN_STATUS_ERROR });\n }\n\n span.setAttributes(getAttributesFromD1Response(d1Result));\n}\n\nfunction getAttributesFromD1Response(d1Result: D1Response): SpanAttributes {\n return {\n 'cloudflare.d1.duration': d1Result.meta.duration,\n 'cloudflare.d1.rows_read': d1Result.meta.rows_read,\n 'cloudflare.d1.rows_written': d1Result.meta.rows_written,\n };\n}\n\ntype D1QueryType = 'first' | 'run' | 'all' | 'raw' | 'batch' | 'exec';\n\nfunction createD1Breadcrumb(query: string, type: D1QueryType, d1Result?: D1Response): void {\n addBreadcrumb({\n category: 'query',\n message: query,\n data: {\n ...(d1Result ? getAttributesFromD1Response(d1Result) : {}),\n 'db.operation.name': type,\n },\n });\n}\n\nfunction createStartSpanOptions(query: string, type: D1QueryType): StartSpanOptions {\n const querySummary = query ? getSqlQuerySummary(sanitizeSqlQuery(query)) : undefined;\n\n const client = getClient();\n const name = client && hasSpanStreamingEnabled(client) ? querySummary || 'cloudflare-d1' : query;\n\n return {\n name,\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': type,\n 'db.query.text': query,\n 'db.query.summary': querySummary,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n };\n}\n\nfunction instrumentPrepare(\n prepare: D1Database['prepare'] | D1DatabaseSession['prepare'],\n): D1Database['prepare'] | D1DatabaseSession['prepare'] {\n return new Proxy(prepare, {\n apply(target, thisArg, args: Parameters<typeof prepare>) {\n const [query] = args;\n return instrumentD1PreparedStatement(Reflect.apply(target, thisArg, args), query);\n },\n });\n}\n\nfunction instrumentBatch(\n batch: D1Database['batch'] | D1DatabaseSession['batch'],\n): D1Database['batch'] | D1DatabaseSession['batch'] {\n return new Proxy(batch, {\n apply(target, thisArg, args: Parameters<typeof batch>) {\n const statements = args[0];\n // D1PreparedStatement exposes a `statement` property at runtime, but it's not in @cloudflare/workers-types.\n // https://github.com/cloudflare/workerd/blob/dc12d7650b4f5d4f9ba6a47aa45fad769cdf8db4/src/cloudflare/internal/d1-api.ts#L210\n const queryText = statements\n .map(statement => (statement as unknown as { statement?: string }).statement ?? '')\n .filter(Boolean)\n .join('\\n');\n\n return startSpan(\n {\n name: 'D1 batch',\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': 'batch',\n 'db.query.text': queryText || undefined,\n 'db.operation.batch.size': statements.length,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n },\n async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb('D1 batch', 'batch');\n return res;\n },\n );\n },\n });\n}\n\nfunction instrumentD1Session(session: D1DatabaseSession): D1DatabaseSession {\n session.prepare = instrumentPrepare(session.prepare);\n session.batch = instrumentBatch(session.batch);\n return session;\n}\n\nfunction _instrumentD1(db: D1Database): D1Database {\n db.prepare = instrumentPrepare(db.prepare);\n db.batch = instrumentBatch(db.batch);\n\n db.exec = new Proxy(db.exec, {\n apply(target, thisArg, args: Parameters<typeof db.exec>) {\n const [query] = args;\n return startSpan(createStartSpanOptions(query, 'exec'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'exec');\n return res;\n });\n },\n });\n\n if ('withSession' in db && typeof db.withSession === 'function') {\n db.withSession = new Proxy(db.withSession, {\n apply(target, thisArg, args: [unknown]) {\n return instrumentD1Session(Reflect.apply(target, thisArg, args) as D1DatabaseSession);\n },\n });\n }\n\n return db;\n}\n\nexport function instrumentD1(db: D1Database): D1Database {\n return ensureInstrumented(db, _instrumentD1);\n}\n"],"names":["startSpan","SPAN_STATUS_ERROR","addBreadcrumb","getSqlQuerySummary","sanitizeSqlQuery","getClient","hasSpanStreamingEnabled","SENTRY_OP","DB_QUERY","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","ensureInstrumented"],"mappings":"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"}
1
+ {"version":3,"file":"instrumentD1.js","sources":["../../../../../src/instrumentations/worker/instrumentD1.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport type { D1Database, D1DatabaseSession, D1PreparedStatement, D1Response } from '@cloudflare/workers-types';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { DB_QUERY } from '@sentry/conventions/op';\nimport type { Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n hasSpanStreamingEnabled,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { getSqlQuerySummary, sanitizeSqlQuery } from '@sentry/server-utils';\nimport { ensureInstrumented } from '../../instrument';\n\n// Patching is based on internal Cloudflare D1 API\n// https://github.com/cloudflare/workerd/blob/cd5279e7b305003f1d9c851e73efa9d67e4b68b2/src/cloudflare/internal/d1-api.ts\n\nconst patchedStatement = new WeakSet<D1PreparedStatement>();\n\n/**\n * Patches the query methods of a Cloudflare D1 prepared statement with Sentry.\n */\nfunction instrumentD1PreparedStatementQueries(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n if (patchedStatement.has(statement)) {\n return statement;\n }\n\n const queryText = query ? sanitizeSqlQuery(query) : undefined;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.first = new Proxy(statement.first, {\n apply(target, thisArg, args: Parameters<typeof statement.first>) {\n return startSpan(createStartSpanOptions(queryText, 'first'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'first');\n return res;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.run = new Proxy(statement.run, {\n apply(target, thisArg, args: Parameters<typeof statement.run>) {\n return startSpan(createStartSpanOptions(queryText, 'run'), async span => {\n const d1Response = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Response);\n createD1Breadcrumb(queryText, 'run', d1Response);\n return d1Response;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.all = new Proxy(statement.all, {\n apply(target, thisArg, args: Parameters<typeof statement.all>) {\n return startSpan(createStartSpanOptions(queryText, 'all'), async span => {\n const d1Result = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Result);\n createD1Breadcrumb(queryText, 'all', d1Result);\n return d1Result;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.raw = new Proxy(statement.raw, {\n apply(target, thisArg, args: Parameters<typeof statement.raw>) {\n return startSpan(createStartSpanOptions(queryText, 'raw'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'raw');\n return res;\n });\n },\n });\n\n patchedStatement.add(statement);\n\n return statement;\n}\n\n/**\n * Instruments a Cloudflare D1 prepared statement with Sentry.\n *\n * This is meant to be used as a top-level call, under the hood it calls `instrumentD1PreparedStatementQueries`\n * to patch the query methods. The reason for this abstraction is to ensure that the `bind` method is also patched.\n */\nfunction instrumentD1PreparedStatement(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n // statement.bind() returns a new instance of D1PreparedStatement, so we have to patch it as well.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.bind = new Proxy(statement.bind, {\n apply(target, thisArg, args: Parameters<typeof statement.bind>) {\n return instrumentD1PreparedStatementQueries(Reflect.apply(target, thisArg, args), query);\n },\n });\n\n return instrumentD1PreparedStatementQueries(statement, query);\n}\n\n/**\n * Add D1Response meta information to a span.\n *\n * See: https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#return-object\n */\nfunction applyD1ReturnObjectToSpan(span: Span, d1Result: D1Response): void {\n if (!d1Result.success) {\n span.setStatus({ code: SPAN_STATUS_ERROR });\n }\n\n span.setAttributes(getAttributesFromD1Response(d1Result));\n}\n\nfunction getAttributesFromD1Response(d1Result: D1Response): SpanAttributes {\n return {\n 'cloudflare.d1.duration': d1Result.meta.duration,\n 'cloudflare.d1.rows_read': d1Result.meta.rows_read,\n 'cloudflare.d1.rows_written': d1Result.meta.rows_written,\n };\n}\n\ntype D1QueryType = 'first' | 'run' | 'all' | 'raw' | 'batch' | 'exec';\n\n/** The message is the span's query text (already sanitized) or a static label such as `D1 batch`. */\nfunction createD1Breadcrumb(message: string | undefined, type: D1QueryType, d1Result?: D1Response): void {\n addBreadcrumb({\n category: 'query',\n message,\n data: {\n ...(d1Result ? getAttributesFromD1Response(d1Result) : {}),\n 'db.operation.name': type,\n },\n });\n}\n\nfunction createStartSpanOptions(queryText: string | undefined, type: D1QueryType): StartSpanOptions {\n const querySummary = queryText ? getSqlQuerySummary(queryText) : undefined;\n\n const client = getClient();\n const name =\n client && hasSpanStreamingEnabled(client) ? querySummary || 'cloudflare-d1' : (queryText ?? 'cloudflare-d1');\n\n return {\n name,\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': type,\n 'db.query.text': queryText,\n 'db.query.summary': querySummary,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n };\n}\n\nfunction instrumentPrepare(\n prepare: D1Database['prepare'] | D1DatabaseSession['prepare'],\n): D1Database['prepare'] | D1DatabaseSession['prepare'] {\n return new Proxy(prepare, {\n apply(target, thisArg, args: Parameters<typeof prepare>) {\n const [query] = args;\n return instrumentD1PreparedStatement(Reflect.apply(target, thisArg, args), query);\n },\n });\n}\n\nfunction instrumentBatch(\n batch: D1Database['batch'] | D1DatabaseSession['batch'],\n): D1Database['batch'] | D1DatabaseSession['batch'] {\n return new Proxy(batch, {\n apply(target, thisArg, args: Parameters<typeof batch>) {\n const statements = args[0];\n // D1PreparedStatement exposes a `statement` property at runtime, but it's not in @cloudflare/workers-types.\n // https://github.com/cloudflare/workerd/blob/dc12d7650b4f5d4f9ba6a47aa45fad769cdf8db4/src/cloudflare/internal/d1-api.ts#L210\n const queryText = statements\n .map(statement => (statement as unknown as { statement?: string }).statement ?? '')\n .filter(Boolean)\n .map(statement => sanitizeSqlQuery(statement))\n .join('\\n');\n\n return startSpan(\n {\n name: 'D1 batch',\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': 'batch',\n 'db.query.text': queryText || undefined,\n 'db.operation.batch.size': statements.length,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n },\n async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb('D1 batch', 'batch');\n return res;\n },\n );\n },\n });\n}\n\nfunction instrumentD1Session(session: D1DatabaseSession): D1DatabaseSession {\n session.prepare = instrumentPrepare(session.prepare);\n session.batch = instrumentBatch(session.batch);\n return session;\n}\n\nfunction _instrumentD1(db: D1Database): D1Database {\n db.prepare = instrumentPrepare(db.prepare);\n db.batch = instrumentBatch(db.batch);\n\n db.exec = new Proxy(db.exec, {\n apply(target, thisArg, args: Parameters<typeof db.exec>) {\n const [query] = args;\n const queryText = query ? sanitizeSqlQuery(query) : undefined;\n return startSpan(createStartSpanOptions(queryText, 'exec'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'exec');\n return res;\n });\n },\n });\n\n if ('withSession' in db && typeof db.withSession === 'function') {\n db.withSession = new Proxy(db.withSession, {\n apply(target, thisArg, args: [unknown]) {\n return instrumentD1Session(Reflect.apply(target, thisArg, args) as D1DatabaseSession);\n },\n });\n }\n\n return db;\n}\n\nexport function instrumentD1(db: D1Database): D1Database {\n return ensureInstrumented(db, _instrumentD1);\n}\n"],"names":["sanitizeSqlQuery","startSpan","SPAN_STATUS_ERROR","addBreadcrumb","getSqlQuerySummary","getClient","hasSpanStreamingEnabled","SENTRY_OP","DB_QUERY","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","ensureInstrumented"],"mappings":";;;;;;;;AAmBA,MAAM,gBAAA,uBAAuB,OAAA,EAA6B;AAK1D,SAAS,oCAAA,CAAqC,WAAgC,KAAA,EAAoC;AAChH,EAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,SAAS,CAAA,EAAG;AACnC,IAAA,OAAO,SAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAY,KAAA,GAAQA,4BAAA,CAAiB,KAAK,CAAA,GAAI,MAAA;AAGpD,EAAA,SAAA,CAAU,KAAA,GAAQ,IAAI,KAAA,CAAM,SAAA,CAAU,KAAA,EAAO;AAAA,IAC3C,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAA0C;AAC/D,MAAA,OAAOC,cAAA,CAAU,sBAAA,CAAuB,SAAA,EAAW,OAAO,GAAG,YAAY;AACvE,QAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AACrD,QAAA,kBAAA,CAAmB,WAAW,OAAO,CAAA;AACrC,QAAA,OAAO,GAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAGD,EAAA,SAAA,CAAU,GAAA,GAAM,IAAI,KAAA,CAAM,SAAA,CAAU,GAAA,EAAK;AAAA,IACvC,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAwC;AAC7D,MAAA,OAAOA,eAAU,sBAAA,CAAuB,SAAA,EAAW,KAAK,CAAA,EAAG,OAAM,IAAA,KAAQ;AACvE,QAAA,MAAM,aAAa,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AAC5D,QAAA,yBAAA,CAA0B,MAAM,UAAU,CAAA;AAC1C,QAAA,kBAAA,CAAmB,SAAA,EAAW,OAAO,UAAU,CAAA;AAC/C,QAAA,OAAO,UAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAGD,EAAA,SAAA,CAAU,GAAA,GAAM,IAAI,KAAA,CAAM,SAAA,CAAU,GAAA,EAAK;AAAA,IACvC,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAwC;AAC7D,MAAA,OAAOA,eAAU,sBAAA,CAAuB,SAAA,EAAW,KAAK,CAAA,EAAG,OAAM,IAAA,KAAQ;AACvE,QAAA,MAAM,WAAW,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AAC1D,QAAA,yBAAA,CAA0B,MAAM,QAAQ,CAAA;AACxC,QAAA,kBAAA,CAAmB,SAAA,EAAW,OAAO,QAAQ,CAAA;AAC7C,QAAA,OAAO,QAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAGD,EAAA,SAAA,CAAU,GAAA,GAAM,IAAI,KAAA,CAAM,SAAA,CAAU,GAAA,EAAK;AAAA,IACvC,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAwC;AAC7D,MAAA,OAAOA,cAAA,CAAU,sBAAA,CAAuB,SAAA,EAAW,KAAK,GAAG,YAAY;AACrE,QAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AACrD,QAAA,kBAAA,CAAmB,WAAW,KAAK,CAAA;AACnC,QAAA,OAAO,GAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAED,EAAA,gBAAA,CAAiB,IAAI,SAAS,CAAA;AAE9B,EAAA,OAAO,SAAA;AACT;AAQA,SAAS,6BAAA,CAA8B,WAAgC,KAAA,EAAoC;AAGzG,EAAA,SAAA,CAAU,IAAA,GAAO,IAAI,KAAA,CAAM,SAAA,CAAU,IAAA,EAAM;AAAA,IACzC,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAyC;AAC9D,MAAA,OAAO,qCAAqC,OAAA,CAAQ,KAAA,CAAM,QAAQ,OAAA,EAAS,IAAI,GAAG,KAAK,CAAA;AAAA,IACzF;AAAA,GACD,CAAA;AAED,EAAA,OAAO,oCAAA,CAAqC,WAAW,KAAK,CAAA;AAC9D;AAOA,SAAS,yBAAA,CAA0B,MAAY,QAAA,EAA4B;AACzE,EAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,IAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAMC,sBAAA,EAAmB,CAAA;AAAA,EAC5C;AAEA,EAAA,IAAA,CAAK,aAAA,CAAc,2BAAA,CAA4B,QAAQ,CAAC,CAAA;AAC1D;AAEA,SAAS,4BAA4B,QAAA,EAAsC;AACzE,EAAA,OAAO;AAAA,IACL,wBAAA,EAA0B,SAAS,IAAA,CAAK,QAAA;AAAA,IACxC,yBAAA,EAA2B,SAAS,IAAA,CAAK,SAAA;AAAA,IACzC,4BAAA,EAA8B,SAAS,IAAA,CAAK;AAAA,GAC9C;AACF;AAKA,SAAS,kBAAA,CAAmB,OAAA,EAA6B,IAAA,EAAmB,QAAA,EAA6B;AACvG,EAAAC,kBAAA,CAAc;AAAA,IACZ,QAAA,EAAU,OAAA;AAAA,IACV,OAAA;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,GAAI,QAAA,GAAW,2BAAA,CAA4B,QAAQ,IAAI,EAAC;AAAA,MACxD,mBAAA,EAAqB;AAAA;AACvB,GACD,CAAA;AACH;AAEA,SAAS,sBAAA,CAAuB,WAA+B,IAAA,EAAqC;AAClG,EAAA,MAAM,YAAA,GAAe,SAAA,GAAYC,8BAAA,CAAmB,SAAS,CAAA,GAAI,MAAA;AAEjE,EAAA,MAAM,SAASC,cAAA,EAAU;AACzB,EAAA,MAAM,OACJ,MAAA,IAAUC,4BAAA,CAAwB,MAAM,CAAA,GAAI,YAAA,IAAgB,kBAAmB,SAAA,IAAa,eAAA;AAE9F,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,CAACC,oBAAS,GAAGC,WAAA;AAAA,MACb,gBAAA,EAAkB,eAAA;AAAA,MAClB,mBAAA,EAAqB,IAAA;AAAA,MACrB,eAAA,EAAiB,SAAA;AAAA,MACjB,kBAAA,EAAoB,YAAA;AAAA,MACpB,CAACC,qCAAgC,GAAG;AAAA;AACtC,GACF;AACF;AAEA,SAAS,kBACP,OAAA,EACsD;AACtD,EAAA,OAAO,IAAI,MAAM,OAAA,EAAS;AAAA,IACxB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAkC;AACvD,MAAA,MAAM,CAAC,KAAK,CAAA,GAAI,IAAA;AAChB,MAAA,OAAO,8BAA8B,OAAA,CAAQ,KAAA,CAAM,QAAQ,OAAA,EAAS,IAAI,GAAG,KAAK,CAAA;AAAA,IAClF;AAAA,GACD,CAAA;AACH;AAEA,SAAS,gBACP,KAAA,EACkD;AAClD,EAAA,OAAO,IAAI,MAAM,KAAA,EAAO;AAAA,IACtB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAgC;AACrD,MAAA,MAAM,UAAA,GAAa,KAAK,CAAC,CAAA;AAGzB,MAAA,MAAM,YAAY,UAAA,CACf,GAAA,CAAI,eAAc,SAAA,CAAgD,SAAA,IAAa,EAAE,CAAA,CACjF,MAAA,CAAO,OAAO,CAAA,CACd,IAAI,CAAA,SAAA,KAAaT,4BAAA,CAAiB,SAAS,CAAC,CAAA,CAC5C,KAAK,IAAI,CAAA;AAEZ,MAAA,OAAOC,cAAA;AAAA,QACL;AAAA,UACE,IAAA,EAAM,UAAA;AAAA,UACN,UAAA,EAAY;AAAA,YACV,CAACM,oBAAS,GAAGC,WAAA;AAAA,YACb,gBAAA,EAAkB,eAAA;AAAA,YAClB,mBAAA,EAAqB,OAAA;AAAA,YACrB,iBAAiB,SAAA,IAAa,MAAA;AAAA,YAC9B,2BAA2B,UAAA,CAAW,MAAA;AAAA,YACtC,CAACC,qCAAgC,GAAG;AAAA;AACtC,SACF;AAAA,QACA,YAAY;AACV,UAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AACrD,UAAA,kBAAA,CAAmB,YAAY,OAAO,CAAA;AACtC,UAAA,OAAO,GAAA;AAAA,QACT;AAAA,OACF;AAAA,IACF;AAAA,GACD,CAAA;AACH;AAEA,SAAS,oBAAoB,OAAA,EAA+C;AAC1E,EAAA,OAAA,CAAQ,OAAA,GAAU,iBAAA,CAAkB,OAAA,CAAQ,OAAO,CAAA;AACnD,EAAA,OAAA,CAAQ,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,KAAK,CAAA;AAC7C,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,cAAc,EAAA,EAA4B;AACjD,EAAA,EAAA,CAAG,OAAA,GAAU,iBAAA,CAAkB,EAAA,CAAG,OAAO,CAAA;AACzC,EAAA,EAAA,CAAG,KAAA,GAAQ,eAAA,CAAgB,EAAA,CAAG,KAAK,CAAA;AAEnC,EAAA,EAAA,CAAG,IAAA,GAAO,IAAI,KAAA,CAAM,EAAA,CAAG,IAAA,EAAM;AAAA,IAC3B,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAkC;AACvD,MAAA,MAAM,CAAC,KAAK,CAAA,GAAI,IAAA;AAChB,MAAA,MAAM,SAAA,GAAY,KAAA,GAAQT,4BAAA,CAAiB,KAAK,CAAA,GAAI,MAAA;AACpD,MAAA,OAAOC,cAAA,CAAU,sBAAA,CAAuB,SAAA,EAAW,MAAM,GAAG,YAAY;AACtE,QAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,IAAI,CAAA;AACrD,QAAA,kBAAA,CAAmB,WAAW,MAAM,CAAA;AACpC,QAAA,OAAO,GAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAED,EAAA,IAAI,aAAA,IAAiB,EAAA,IAAM,OAAO,EAAA,CAAG,gBAAgB,UAAA,EAAY;AAC/D,IAAA,EAAA,CAAG,WAAA,GAAc,IAAI,KAAA,CAAM,EAAA,CAAG,WAAA,EAAa;AAAA,MACzC,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAiB;AACtC,QAAA,OAAO,oBAAoB,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAI,CAAsB,CAAA;AAAA,MACtF;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,EAAA;AACT;AAEO,SAAS,aAAa,EAAA,EAA4B;AACvD,EAAA,OAAOS,6BAAA,CAAmB,IAAI,aAAa,CAAA;AAC7C;;;;"}
@@ -21,11 +21,12 @@ function wrapEmailHandler(emailMessage, options, context, fn) {
21
21
  scopeUtils.addCloudResourceContext(isolationScope);
22
22
  return core.startSpan(
23
23
  {
24
- name: `Handle Email ${emailMessage.to}`,
24
+ name: "email",
25
25
  attributes: {
26
26
  [attributes.SENTRY_OP]: op.FUNCTION,
27
- "faas.trigger": "email",
28
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.faas.cloudflare.email",
27
+ [attributes.CODE_FUNCTION_NAME]: "email",
28
+ [attributes.FAAS_TRIGGER]: "email",
29
+ [attributes.SENTRY_ORIGIN]: "auto.faas.cloudflare.email",
29
30
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "task"
30
31
  }
31
32
  },
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentEmail.js","sources":["../../../../../src/instrumentations/worker/instrumentEmail.ts"],"sourcesContent":["import type { EmailMessage } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv } from 'cloudflare:workers';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP } from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core email handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapEmailHandler(\n emailMessage: EmailMessage,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: `Handle Email ${emailMessage.to}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n 'faas.trigger': 'email',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments an email handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerEmail<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('email' in handler) || typeof handler.email !== 'function') {\n return;\n }\n\n handler.email = ensureInstrumented(\n handler.email,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['email']>>) {\n const [emailMessage, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapEmailHandler(emailMessage, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAS,gBAAA,CACP,YAAA,EACA,OAAA,EACA,OAAA,EACA,EAAA,EACS;AACT,EAAA,OAAOA,wBAAmB,CAAA,cAAA,KAAkB;AAC1C,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAEhD,IAAAC,oCAAA,CAAmB,cAAA,EAAgB,EAAE,GAAA,EAAK,OAAA,EAAS,CAAA;AAEnD,IAAA,MAAM,SAASC,QAAA,CAAK,EAAE,GAAG,OAAA,EAAS,GAAA,EAAK,SAAS,CAAA;AAChD,IAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAE/B,IAAAC,kCAAA,CAAwB,cAAc,CAAA;AAEtC,IAAA,OAAOC,cAAA;AAAA,MACL;AAAA,QACE,IAAA,EAAM,CAAA,aAAA,EAAgB,YAAA,CAAa,EAAE,CAAA,CAAA;AAAA,QACrC,UAAA,EAAY;AAAA,UACV,CAACC,oBAAS,GAAGC,WAAA;AAAA,UACb,cAAA,EAAgB,OAAA;AAAA,UAChB,CAACC,qCAAgC,GAAG,4BAAA;AAAA,UACpC,CAACC,qCAA0B,GAAG;AAAA;AAChC,OACF;AAAA,MACA,YAAY;AACV,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,EAAA,EAAG;AAAA,QAClB,SAAS,CAAA,EAAG;AACV,UAAAC,qBAAA,CAAiB,CAAA,EAAG,EAAE,SAAA,EAAW,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,4BAAA,EAA6B,EAAG,CAAA;AACzF,UAAA,MAAM,CAAA;AAAA,QACR,CAAA,SAAE;AACA,UAAA,SAAA,CAAUC,qBAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,QACnC;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,8BAAA,CACd,SACA,eAAA,EACM;AACN,EAAA,IAAI,EAAE,OAAA,IAAW,OAAA,CAAA,IAAY,OAAO,OAAA,CAAQ,UAAU,UAAA,EAAY;AAChE,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,KAAA,GAAQC,6BAAA;AAAA,IACd,OAAA,CAAQ,KAAA;AAAA,IACR,CAAA,QAAA,KACE,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,MAClB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAA2C;AAChE,QAAA,MAAM,CAAC,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA,GAAI,IAAA;AACjC,QAAA,MAAM,OAAA,GAAUC,oCAAkB,GAAG,CAAA;AACrC,QAAA,MAAMC,SAAA,GAAUC,uBAAA,CAAgB,eAAA,CAAgB,GAAG,GAAG,GAAG,CAAA;AACzD,QAAA,IAAA,CAAK,CAAC,CAAA,GAAIC,2BAAA,CAAc,GAAA,EAAKF,SAAO,CAAA;AACpC,QAAA,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA;AAEV,QAAA,OAAO,gBAAA,CAAiB,cAAcA,SAAA,EAAS,OAAA,EAAS,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,MAC3F;AAAA,KACD;AAAA,GACL;AACF;;;;"}
1
+ {"version":3,"file":"instrumentEmail.js","sources":["../../../../../src/instrumentations/worker/instrumentEmail.ts"],"sourcesContent":["import type { EmailMessage } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv } from 'cloudflare:workers';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n FAAS_TRIGGER,\n SENTRY_ORIGIN,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core email handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapEmailHandler(\n emailMessage: EmailMessage,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: 'email',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'email',\n [FAAS_TRIGGER]: 'email',\n [SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments an email handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerEmail<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('email' in handler) || typeof handler.email !== 'function') {\n return;\n }\n\n handler.email = ensureInstrumented(\n handler.email,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['email']>>) {\n const [emailMessage, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapEmailHandler(emailMessage, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","CODE_FUNCTION_NAME","FAAS_TRIGGER","SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAS,gBAAA,CACP,YAAA,EACA,OAAA,EACA,OAAA,EACA,EAAA,EACS;AACT,EAAA,OAAOA,wBAAmB,CAAA,cAAA,KAAkB;AAC1C,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAEhD,IAAAC,oCAAA,CAAmB,cAAA,EAAgB,EAAE,GAAA,EAAK,OAAA,EAAS,CAAA;AAEnD,IAAA,MAAM,SAASC,QAAA,CAAK,EAAE,GAAG,OAAA,EAAS,GAAA,EAAK,SAAS,CAAA;AAChD,IAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAE/B,IAAAC,kCAAA,CAAwB,cAAc,CAAA;AAEtC,IAAA,OAAOC,cAAA;AAAA,MACL;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,CAACC,oBAAS,GAAGC,WAAA;AAAA,UACb,CAACC,6BAAkB,GAAG,OAAA;AAAA,UACtB,CAACC,uBAAY,GAAG,OAAA;AAAA,UAChB,CAACC,wBAAa,GAAG,4BAAA;AAAA,UACjB,CAACC,qCAA0B,GAAG;AAAA;AAChC,OACF;AAAA,MACA,YAAY;AACV,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,EAAA,EAAG;AAAA,QAClB,SAAS,CAAA,EAAG;AACV,UAAAC,qBAAA,CAAiB,CAAA,EAAG,EAAE,SAAA,EAAW,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,4BAAA,EAA6B,EAAG,CAAA;AACzF,UAAA,MAAM,CAAA;AAAA,QACR,CAAA,SAAE;AACA,UAAA,SAAA,CAAUC,qBAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,QACnC;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,8BAAA,CACd,SACA,eAAA,EACM;AACN,EAAA,IAAI,EAAE,OAAA,IAAW,OAAA,CAAA,IAAY,OAAO,OAAA,CAAQ,UAAU,UAAA,EAAY;AAChE,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,KAAA,GAAQC,6BAAA;AAAA,IACd,OAAA,CAAQ,KAAA;AAAA,IACR,CAAA,QAAA,KACE,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,MAClB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAA2C;AAChE,QAAA,MAAM,CAAC,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA,GAAI,IAAA;AACjC,QAAA,MAAM,OAAA,GAAUC,oCAAkB,GAAG,CAAA;AACrC,QAAA,MAAMC,SAAA,GAAUC,uBAAA,CAAgB,eAAA,CAAgB,GAAG,GAAG,GAAG,CAAA;AACzD,QAAA,IAAA,CAAK,CAAC,CAAA,GAAIC,2BAAA,CAAc,GAAA,EAAKF,SAAO,CAAA;AACpC,QAAA,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA;AAEV,QAAA,OAAO,gBAAA,CAAiB,cAAcA,SAAA,EAAS,OAAA,EAAS,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,MAC3F;AAAA,KACD;AAAA,GACL;AACF;;;;"}
@@ -19,15 +19,20 @@ function wrapScheduledHandler(controller, options, context, fn) {
19
19
  const client = sdk.init({ ...options, ctx: context });
20
20
  isolationScope.setClient(client);
21
21
  scopeUtils.addCloudResourceContext(isolationScope);
22
+ const description = `Scheduled Cron ${controller.cron}`;
22
23
  return core.startSpan(
23
24
  {
24
- name: `Scheduled Cron ${controller.cron}`,
25
+ name: client && core.hasSpanStreamingEnabled(client) ? "scheduled" : description,
25
26
  attributes: {
26
27
  [attributes.SENTRY_OP]: op.FUNCTION,
27
- "faas.cron": controller.cron,
28
- "faas.time": new Date(controller.scheduledTime).toISOString(),
29
- "faas.trigger": "timer",
30
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.faas.cloudflare.scheduled",
28
+ // override description inference by Relay to preserve the original (transaction-based) description.
29
+ // sentry-conventions can't map the special case for the "Scheduled Cron" prefix and the chron string.
30
+ [attributes.SENTRY_DESCRIPTION]: description,
31
+ [attributes.CODE_FUNCTION_NAME]: "scheduled",
32
+ [attributes.FAAS_CRON]: controller.cron,
33
+ [attributes.FAAS_TIME]: new Date(controller.scheduledTime).toISOString(),
34
+ [attributes.FAAS_TRIGGER]: "timer",
35
+ [attributes.SENTRY_ORIGIN]: "auto.faas.cloudflare.scheduled",
31
36
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "task"
32
37
  }
33
38
  },
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP } from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: `Scheduled Cron ${controller.cron}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n 'faas.cron': controller.cron,\n 'faas.time': new Date(controller.scheduledTime).toISOString(),\n 'faas.trigger': 'timer',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerScheduled<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function') {\n return;\n }\n\n handler.scheduled = ensureInstrumented(\n handler.scheduled,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a scheduled method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointScheduled<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.scheduled) {\n return;\n }\n\n const original = instance.scheduled.bind(instance);\n instance.scheduled = new Proxy(original, {\n apply(target, thisArg, args: [ScheduledController]) {\n const [controller] = args;\n\n return wrapScheduledHandler(controller, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":"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"}
1
+ {"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n FAAS_CRON,\n FAAS_TIME,\n FAAS_TRIGGER,\n SENTRY_DESCRIPTION,\n SENTRY_ORIGIN,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, hasSpanStreamingEnabled, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n const description = `Scheduled Cron ${controller.cron}`;\n\n return startSpan(\n {\n name: client && hasSpanStreamingEnabled(client) ? 'scheduled' : description,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n // override description inference by Relay to preserve the original (transaction-based) description.\n // sentry-conventions can't map the special case for the \"Scheduled Cron\" prefix and the chron string.\n [SENTRY_DESCRIPTION]: description,\n [CODE_FUNCTION_NAME]: 'scheduled',\n [FAAS_CRON]: controller.cron,\n [FAAS_TIME]: new Date(controller.scheduledTime).toISOString(),\n [FAAS_TRIGGER]: 'timer',\n [SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerScheduled<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function') {\n return;\n }\n\n handler.scheduled = ensureInstrumented(\n handler.scheduled,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a scheduled method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointScheduled<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.scheduled) {\n return;\n }\n\n const original = instance.scheduled.bind(instance);\n instance.scheduled = new Proxy(original, {\n apply(target, thisArg, args: [ScheduledController]) {\n const [controller] = args;\n\n return wrapScheduledHandler(controller, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","hasSpanStreamingEnabled","SENTRY_OP","FUNCTION","SENTRY_DESCRIPTION","CODE_FUNCTION_NAME","FAAS_CRON","FAAS_TIME","FAAS_TRIGGER","SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":"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"}