@sentry/cloudflare 10.50.0 → 10.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/build/cjs/durableobject.js +68 -130
  2. package/build/cjs/durableobject.js.map +1 -1
  3. package/build/cjs/index.js +3 -0
  4. package/build/cjs/index.js.map +1 -1
  5. package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js +14 -4
  6. package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  7. package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js +12 -1
  8. package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  9. package/build/cjs/instrumentations/worker/instrumentEnv.js +23 -11
  10. package/build/cjs/instrumentations/worker/instrumentEnv.js.map +1 -1
  11. package/build/cjs/instrumentations/worker/instrumentQueue.js +2 -0
  12. package/build/cjs/instrumentations/worker/instrumentQueue.js.map +1 -1
  13. package/build/cjs/instrumentations/worker/instrumentQueueProducer.js +106 -0
  14. package/build/cjs/instrumentations/worker/instrumentQueueProducer.js.map +1 -0
  15. package/build/cjs/integrations/httpServer.js +68 -0
  16. package/build/cjs/integrations/httpServer.js.map +1 -0
  17. package/build/cjs/request.js +5 -0
  18. package/build/cjs/request.js.map +1 -1
  19. package/build/cjs/sdk.js +2 -0
  20. package/build/cjs/sdk.js.map +1 -1
  21. package/build/cjs/utils/isBinding.js +9 -0
  22. package/build/cjs/utils/isBinding.js.map +1 -1
  23. package/build/cjs/utils/rpcMeta.js +60 -0
  24. package/build/cjs/utils/rpcMeta.js.map +1 -0
  25. package/build/cjs/utils/rpcOptions.js +1 -36
  26. package/build/cjs/utils/rpcOptions.js.map +1 -1
  27. package/build/cjs/wrapMethodWithSentry.js +21 -1
  28. package/build/cjs/wrapMethodWithSentry.js.map +1 -1
  29. package/build/esm/durableobject.js +70 -132
  30. package/build/esm/durableobject.js.map +1 -1
  31. package/build/esm/index.js +2 -1
  32. package/build/esm/index.js.map +1 -1
  33. package/build/esm/instrumentations/instrumentDurableObjectNamespace.js +14 -5
  34. package/build/esm/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  35. package/build/esm/instrumentations/instrumentWorkerEntrypoint.js +12 -1
  36. package/build/esm/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  37. package/build/esm/instrumentations/worker/instrumentEnv.js +25 -13
  38. package/build/esm/instrumentations/worker/instrumentEnv.js.map +1 -1
  39. package/build/esm/instrumentations/worker/instrumentQueue.js +2 -0
  40. package/build/esm/instrumentations/worker/instrumentQueue.js.map +1 -1
  41. package/build/esm/instrumentations/worker/instrumentQueueProducer.js +104 -0
  42. package/build/esm/instrumentations/worker/instrumentQueueProducer.js.map +1 -0
  43. package/build/esm/integrations/httpServer.js +65 -0
  44. package/build/esm/integrations/httpServer.js.map +1 -0
  45. package/build/esm/package.json +1 -1
  46. package/build/esm/request.js +5 -0
  47. package/build/esm/request.js.map +1 -1
  48. package/build/esm/sdk.js +2 -0
  49. package/build/esm/sdk.js.map +1 -1
  50. package/build/esm/utils/isBinding.js +9 -1
  51. package/build/esm/utils/isBinding.js.map +1 -1
  52. package/build/esm/utils/rpcMeta.js +57 -0
  53. package/build/esm/utils/rpcMeta.js.map +1 -0
  54. package/build/esm/utils/rpcOptions.js +2 -36
  55. package/build/esm/utils/rpcOptions.js.map +1 -1
  56. package/build/esm/wrapMethodWithSentry.js +22 -2
  57. package/build/esm/wrapMethodWithSentry.js.map +1 -1
  58. package/build/types/durableobject.d.ts +2 -2
  59. package/build/types/durableobject.d.ts.map +1 -1
  60. package/build/types/index.d.ts +2 -1
  61. package/build/types/index.d.ts.map +1 -1
  62. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts +1 -0
  63. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts.map +1 -1
  64. package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts.map +1 -1
  65. package/build/types/instrumentations/worker/instrumentEnv.d.ts +3 -2
  66. package/build/types/instrumentations/worker/instrumentEnv.d.ts.map +1 -1
  67. package/build/types/instrumentations/worker/instrumentQueue.d.ts.map +1 -1
  68. package/build/types/instrumentations/worker/instrumentQueueProducer.d.ts +10 -0
  69. package/build/types/instrumentations/worker/instrumentQueueProducer.d.ts.map +1 -0
  70. package/build/types/integrations/httpServer.d.ts +61 -0
  71. package/build/types/integrations/httpServer.d.ts.map +1 -0
  72. package/build/types/request.d.ts.map +1 -1
  73. package/build/types/sdk.d.ts.map +1 -1
  74. package/build/types/utils/isBinding.d.ts +6 -1
  75. package/build/types/utils/isBinding.d.ts.map +1 -1
  76. package/build/types/utils/rpcMeta.d.ts +15 -0
  77. package/build/types/utils/rpcMeta.d.ts.map +1 -0
  78. package/build/types/utils/rpcOptions.d.ts +1 -12
  79. package/build/types/utils/rpcOptions.d.ts.map +1 -1
  80. package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
  81. package/build/types-ts3.8/durableobject.d.ts +2 -2
  82. package/build/types-ts3.8/index.d.ts +2 -1
  83. package/build/types-ts3.8/instrumentations/instrumentDurableObjectNamespace.d.ts +1 -0
  84. package/build/types-ts3.8/instrumentations/worker/instrumentEnv.d.ts +3 -2
  85. package/build/types-ts3.8/instrumentations/worker/instrumentQueueProducer.d.ts +10 -0
  86. package/build/types-ts3.8/integrations/httpServer.d.ts +61 -0
  87. package/build/types-ts3.8/utils/isBinding.d.ts +6 -1
  88. package/build/types-ts3.8/utils/rpcMeta.d.ts +15 -0
  89. package/build/types-ts3.8/utils/rpcOptions.d.ts +1 -12
  90. package/package.json +2 -2
@@ -1,26 +1,35 @@
1
1
  import { captureException } from '@sentry/core';
2
2
  import { setAsyncLocalStorageAsyncContextStrategy } from './async.js';
3
- import { ensureInstrumented, getInstrumented, markAsInstrumented } from './instrument.js';
3
+ import { ensureInstrumented } from './instrument.js';
4
4
  import { instrumentEnv } from './instrumentations/worker/instrumentEnv.js';
5
5
  import { getFinalOptions } from './options.js';
6
6
  import { wrapRequestHandler } from './request.js';
7
7
  import { instrumentContext } from './utils/instrumentContext.js';
8
- import { getPrototypeMethodFilter } from './utils/rpcOptions.js';
8
+ import { getEffectiveRpcPropagation } from './utils/rpcOptions.js';
9
9
  import { wrapMethodWithSentry } from './wrapMethodWithSentry.js';
10
10
 
11
11
  /* eslint-disable @typescript-eslint/unbound-method */
12
12
 
13
+ const BUILT_IN_DO_METHODS = new Set([
14
+ 'constructor',
15
+ 'fetch',
16
+ 'alarm',
17
+ 'webSocketError',
18
+ 'webSocketClose',
19
+ 'webSocketMessage',
20
+ ]);
21
+
13
22
  /**
14
23
  * Instruments a Durable Object class to capture errors and performance data.
15
24
  *
16
- * Instruments the following methods:
25
+ * Instruments the following methods by default:
17
26
  * - fetch
18
27
  * - alarm
19
28
  * - webSocketMessage
20
29
  * - webSocketClose
21
30
  * - webSocketError
22
31
  *
23
- * as well as any other public RPC methods on the Durable Object instance.
32
+ * To instrument RPC methods (prototype methods), enable the `enableRpcTracePropagation` option.
24
33
  *
25
34
  * @param optionsCallback Function that returns the options for the SDK initialization.
26
35
  * @param DurableObjectClass The Durable Object class to instrument.
@@ -112,140 +121,69 @@ function instrumentDurableObjectWithSentry
112
121
  );
113
122
  }
114
123
 
115
- for (const method of Object.getOwnPropertyNames(obj)) {
116
- if (
117
- method === 'fetch' ||
118
- method === 'alarm' ||
119
- method === 'webSocketError' ||
120
- method === 'webSocketClose' ||
121
- method === 'webSocketMessage'
122
- ) {
123
- continue;
124
- }
125
-
126
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
127
- const value = (obj )[method] ;
128
- if (typeof value === 'function') {
129
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
130
- (obj )[method] = wrapMethodWithSentry(
131
- { options, context, spanName: method, spanOp: 'rpc' },
132
- value ,
133
- );
134
- }
135
- }
136
-
137
- // Store context and options on the instance for prototype methods to access
138
- Object.defineProperty(obj, '__SENTRY_CONTEXT__', {
139
- value: context,
140
- enumerable: false,
141
- writable: false,
142
- configurable: false,
143
- });
144
-
145
- Object.defineProperty(obj, '__SENTRY_OPTIONS__', {
146
- value: options,
147
- enumerable: false,
148
- writable: false,
149
- configurable: false,
150
- });
151
-
152
- const methodFilter = getPrototypeMethodFilter(options);
124
+ // Get effective RPC propagation setting (handles deprecation of instrumentPrototypeMethods)
125
+ const rpcPropagation = getEffectiveRpcPropagation(options);
153
126
 
154
- if (methodFilter) {
155
- instrumentPrototype(target, methodFilter);
127
+ // Skip RPC instrumentation if not enabled
128
+ if (!rpcPropagation) {
129
+ return obj;
156
130
  }
157
131
 
158
- return obj;
159
- },
160
- });
161
- }
162
-
163
- function instrumentPrototype(target, methodsToInstrument) {
164
- const proto = target.prototype;
165
-
166
- // Get all methods from the prototype chain
167
- const methodNames = new Set();
168
- let current = proto;
169
-
170
- while (current && current !== Object.prototype) {
171
- Object.getOwnPropertyNames(current).forEach(name => {
172
- if (name !== 'constructor' && typeof (current )[name] === 'function') {
173
- methodNames.add(name);
174
- }
175
- });
176
- current = Object.getPrototypeOf(current);
177
- }
178
-
179
- // Create a set for efficient lookups when methodsToInstrument is an array
180
- const methodsToInstrumentSet = Array.isArray(methodsToInstrument) ? new Set(methodsToInstrument) : null;
181
-
182
- // Instrument each method on the prototype
183
- methodNames.forEach(methodName => {
184
- const originalMethod = (proto )[methodName];
185
-
186
- if (!originalMethod) {
187
- return;
188
- }
189
-
190
- const existingInstrumented = getInstrumented(originalMethod);
191
- if (existingInstrumented) {
192
- Object.defineProperty(proto, methodName, {
193
- value: existingInstrumented,
194
- enumerable: false,
195
- writable: true,
196
- configurable: true,
197
- });
198
- return;
199
- }
200
-
201
- // If methodsToInstrument is an array, only instrument methods in that set
202
- if (methodsToInstrumentSet && !methodsToInstrumentSet.has(methodName)) {
203
- return;
204
- }
205
-
206
- // Create a wrapper that gets context/options from the instance at runtime
207
- const wrappedMethod = function ( ...args) {
208
- const thisWithSentry = this
209
-
210
- ;
211
- const instanceContext = thisWithSentry.__SENTRY_CONTEXT__;
212
- const instanceOptions = thisWithSentry.__SENTRY_OPTIONS__;
132
+ // If `instrumentPrototypeMethods` was passed as an array (deprecated),
133
+ // only the listed method names should be instrumented.
134
+ const instrumentPrototypeMethods = Array.isArray(options.instrumentPrototypeMethods)
135
+ ? options.instrumentPrototypeMethods
136
+ : undefined;
137
+ const allowSet = instrumentPrototypeMethods ? new Set(instrumentPrototypeMethods) : null;
138
+
139
+ // Return a Proxy that lazily wraps prototype methods on access.
140
+ // This avoids iterating the prototype chain at construction time —
141
+ // we only check if a property is an RPC method when it's accessed.
142
+ const rpcMethodCache = new Map();
143
+
144
+ return new Proxy(obj, {
145
+ get(proxyTarget, prop, receiver) {
146
+ const value = Reflect.get(proxyTarget, prop, receiver);
147
+
148
+ if (typeof prop !== 'string' || BUILT_IN_DO_METHODS.has(prop)) {
149
+ return value;
150
+ }
151
+
152
+ const cached = rpcMethodCache.get(prop);
153
+
154
+ if (cached) {
155
+ return cached;
156
+ }
157
+
158
+ if (
159
+ typeof value !== 'function' ||
160
+ Object.prototype.hasOwnProperty.call(proxyTarget, prop) ||
161
+ (allowSet && !allowSet.has(prop)) ||
162
+ // Exclude inherited Object.prototype methods (toString, valueOf, etc.)
163
+ // These are not RPC methods and should not create spans
164
+ prop in Object.prototype
165
+ ) {
166
+ return value;
167
+ }
168
+
169
+ // Bind the method to the original object to ensure private fields work correctly.
170
+ // When called via the Proxy, `this` would be the Proxy, but private fields require
171
+ // the original object. Bound functions ignore the thisArg passed via Reflect.apply.
172
+ const boundValue = (value ).bind(proxyTarget);
173
+
174
+ const wrapped = wrapMethodWithSentry(
175
+ { options, context, spanName: prop, spanOp: 'rpc' },
176
+ boundValue,
177
+ undefined,
178
+ true,
179
+ );
213
180
 
214
- if (!instanceOptions) {
215
- // Fallback to original method if no Sentry data found
216
- return (originalMethod ).apply(this, args);
217
- }
181
+ rpcMethodCache.set(prop, wrapped);
218
182
 
219
- // Use the existing wrapper but with instance-specific context/options
220
- const wrapper = wrapMethodWithSentry(
221
- {
222
- options: instanceOptions,
223
- context: instanceContext,
224
- spanName: methodName,
225
- spanOp: 'rpc',
183
+ return wrapped;
226
184
  },
227
- originalMethod ,
228
- undefined,
229
- true, // noMark = true since we'll mark the prototype method
230
- );
231
-
232
- return wrapper.apply(this, args);
233
- };
234
-
235
- // Only mark wrappedMethod as instrumented (not originalMethod → wrappedMethod).
236
- // originalMethod must stay unmapped because wrappedMethod calls
237
- // wrapMethodWithSentry(options, originalMethod) on each invocation to create
238
- // a per-instance proxy. If originalMethod mapped to wrappedMethod, that call
239
- // would return wrappedMethod itself, causing infinite recursion.
240
- markAsInstrumented(wrappedMethod);
241
-
242
- // Replace the prototype method
243
- Object.defineProperty(proto, methodName, {
244
- value: wrappedMethod,
245
- enumerable: false,
246
- writable: true,
247
- configurable: true,
248
- });
185
+ });
186
+ },
249
187
  });
250
188
  }
251
189
 
@@ -1 +1 @@
1
- {"version":3,"file":"durableobject.js","sources":["../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport { captureException } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { ensureInstrumented, getInstrumented, markAsInstrumented } from './instrument';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { getPrototypeMethodFilter } from './utils/rpcOptions';\nimport type { UncheckedMethod } from './wrapMethodWithSentry';\nimport { wrapMethodWithSentry } from './wrapMethodWithSentry';\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * as well as any other public RPC methods on the Durable Object instance.\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 E,\n T extends DurableObject<E>,\n C extends new (state: DurableObjectState, env: E) => T,\n>(optionsCallback: (env: E) => CloudflareOptions, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [ctx, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n const instrumentedEnv = instrumentEnv(env, options);\n\n const obj = new target(context, instrumentedEnv);\n\n // These are the methods that are available on a Durable Object\n // ref: https://developers.cloudflare.com/durable-objects/api/base/\n // obj.alarm\n // obj.fetch\n // obj.webSocketError\n // obj.webSocketClose\n // obj.webSocketMessage\n\n // Any other public methods on the Durable Object instance are RPC calls.\n\n if (obj.fetch && typeof obj.fetch === 'function') {\n obj.fetch = ensureInstrumented(\n obj.fetch,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args) {\n return wrapRequestHandler({ options, request: args[0], context }, () => {\n return Reflect.apply(target, thisArg, args);\n });\n },\n }),\n );\n }\n\n if (obj.alarm && typeof obj.alarm === 'function') {\n // Alarms are independent invocations, so we start a new trace and link to the previous alarm\n obj.alarm = wrapMethodWithSentry(\n { options, context, spanName: 'alarm', spanOp: 'function', startNewTrace: true },\n obj.alarm,\n );\n }\n\n if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {\n obj.webSocketMessage = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketMessage' },\n obj.webSocketMessage,\n );\n }\n\n if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {\n obj.webSocketClose = wrapMethodWithSentry({ options, context, spanName: 'webSocketClose' }, obj.webSocketClose);\n }\n\n if (obj.webSocketError && typeof obj.webSocketError === 'function') {\n obj.webSocketError = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketError' },\n obj.webSocketError,\n (_, error) =>\n captureException(error, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object_websocket',\n handled: false,\n },\n }),\n );\n }\n\n for (const method of Object.getOwnPropertyNames(obj)) {\n if (\n method === 'fetch' ||\n method === 'alarm' ||\n method === 'webSocketError' ||\n method === 'webSocketClose' ||\n method === 'webSocketMessage'\n ) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const value = (obj as any)[method] as unknown;\n if (typeof value === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (obj as any)[method] = wrapMethodWithSentry(\n { options, context, spanName: method, spanOp: 'rpc' },\n value as UncheckedMethod,\n );\n }\n }\n\n // Store context and options on the instance for prototype methods to access\n Object.defineProperty(obj, '__SENTRY_CONTEXT__', {\n value: context,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(obj, '__SENTRY_OPTIONS__', {\n value: options,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n const methodFilter = getPrototypeMethodFilter(options);\n\n if (methodFilter) {\n instrumentPrototype(target, methodFilter);\n }\n\n return obj;\n },\n });\n}\n\nfunction instrumentPrototype<T extends NewableFunction>(target: T, methodsToInstrument: boolean | string[]): void {\n const proto = target.prototype;\n\n // Get all methods from the prototype chain\n const methodNames = new Set<string>();\n let current = proto;\n\n while (current && current !== Object.prototype) {\n Object.getOwnPropertyNames(current).forEach(name => {\n if (name !== 'constructor' && typeof (current as Record<string, unknown>)[name] === 'function') {\n methodNames.add(name);\n }\n });\n current = Object.getPrototypeOf(current);\n }\n\n // Create a set for efficient lookups when methodsToInstrument is an array\n const methodsToInstrumentSet = Array.isArray(methodsToInstrument) ? new Set(methodsToInstrument) : null;\n\n // Instrument each method on the prototype\n methodNames.forEach(methodName => {\n const originalMethod = (proto as Record<string, unknown>)[methodName];\n\n if (!originalMethod) {\n return;\n }\n\n const existingInstrumented = getInstrumented(originalMethod);\n if (existingInstrumented) {\n Object.defineProperty(proto, methodName, {\n value: existingInstrumented,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n return;\n }\n\n // If methodsToInstrument is an array, only instrument methods in that set\n if (methodsToInstrumentSet && !methodsToInstrumentSet.has(methodName)) {\n return;\n }\n\n // Create a wrapper that gets context/options from the instance at runtime\n const wrappedMethod = function (this: unknown, ...args: unknown[]): unknown {\n const thisWithSentry = this as {\n __SENTRY_CONTEXT__: DurableObjectState;\n __SENTRY_OPTIONS__: CloudflareOptions;\n };\n const instanceContext = thisWithSentry.__SENTRY_CONTEXT__;\n const instanceOptions = thisWithSentry.__SENTRY_OPTIONS__;\n\n if (!instanceOptions) {\n // Fallback to original method if no Sentry data found\n return (originalMethod as UncheckedMethod).apply(this, args);\n }\n\n // Use the existing wrapper but with instance-specific context/options\n const wrapper = wrapMethodWithSentry(\n {\n options: instanceOptions,\n context: instanceContext,\n spanName: methodName,\n spanOp: 'rpc',\n },\n originalMethod as UncheckedMethod,\n undefined,\n true, // noMark = true since we'll mark the prototype method\n );\n\n return wrapper.apply(this, args);\n };\n\n // Only mark wrappedMethod as instrumented (not originalMethod → wrappedMethod).\n // originalMethod must stay unmapped because wrappedMethod calls\n // wrapMethodWithSentry(options, originalMethod) on each invocation to create\n // a per-instance proxy. If originalMethod mapped to wrappedMethod, that call\n // would return wrappedMethod itself, causing infinite recursion.\n markAsInstrumented(wrappedMethod);\n\n // Replace the prototype method\n Object.defineProperty(proto, methodName, {\n value: wrappedMethod,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"durableobject.js","sources":["../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport { captureException } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from './async';\nimport type { CloudflareOptions } from './client';\nimport { ensureInstrumented } from './instrument';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandler } from './request';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { getEffectiveRpcPropagation } from './utils/rpcOptions';\nimport { type UncheckedMethod, wrapMethodWithSentry } from './wrapMethodWithSentry';\n\nconst BUILT_IN_DO_METHODS = new Set([\n 'constructor',\n 'fetch',\n 'alarm',\n 'webSocketError',\n 'webSocketClose',\n 'webSocketMessage',\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 * To instrument RPC methods (prototype methods), enable the `enableRpcTracePropagation` option.\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 E,\n T extends DurableObject<E>,\n C extends new (state: DurableObjectState, env: E) => T,\n>(optionsCallback: (env: E) => CloudflareOptions, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [ctx, env]) {\n setAsyncLocalStorageAsyncContextStrategy();\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n const instrumentedEnv = instrumentEnv(env, options);\n\n const obj = new target(context, instrumentedEnv);\n\n // These are the methods that are available on a Durable Object\n // ref: https://developers.cloudflare.com/durable-objects/api/base/\n // obj.alarm\n // obj.fetch\n // obj.webSocketError\n // obj.webSocketClose\n // obj.webSocketMessage\n\n // Any other public methods on the Durable Object instance are RPC calls.\n\n if (obj.fetch && typeof obj.fetch === 'function') {\n obj.fetch = ensureInstrumented(\n obj.fetch,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args) {\n return wrapRequestHandler({ options, request: args[0], context }, () => {\n return Reflect.apply(target, thisArg, args);\n });\n },\n }),\n );\n }\n\n if (obj.alarm && typeof obj.alarm === 'function') {\n // Alarms are independent invocations, so we start a new trace and link to the previous alarm\n obj.alarm = wrapMethodWithSentry(\n { options, context, spanName: 'alarm', spanOp: 'function', startNewTrace: true },\n obj.alarm,\n );\n }\n\n if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {\n obj.webSocketMessage = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketMessage' },\n obj.webSocketMessage,\n );\n }\n\n if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {\n obj.webSocketClose = wrapMethodWithSentry({ options, context, spanName: 'webSocketClose' }, obj.webSocketClose);\n }\n\n if (obj.webSocketError && typeof obj.webSocketError === 'function') {\n obj.webSocketError = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketError' },\n obj.webSocketError,\n (_, error) =>\n captureException(error, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object_websocket',\n handled: false,\n },\n }),\n );\n }\n\n // Get effective RPC propagation setting (handles deprecation of instrumentPrototypeMethods)\n const rpcPropagation = getEffectiveRpcPropagation(options);\n\n // Skip RPC instrumentation if not enabled\n if (!rpcPropagation) {\n return obj;\n }\n\n // If `instrumentPrototypeMethods` was passed as an array (deprecated),\n // only the listed method names should be instrumented.\n const instrumentPrototypeMethods = Array.isArray(options.instrumentPrototypeMethods)\n ? options.instrumentPrototypeMethods\n : undefined;\n const allowSet = instrumentPrototypeMethods ? new Set(instrumentPrototypeMethods) : null;\n\n // Return a Proxy that lazily wraps prototype methods on access.\n // This avoids iterating the prototype chain at construction time —\n // we only check if a property is an RPC method when it's accessed.\n const rpcMethodCache = new Map<string, UncheckedMethod>();\n\n return new Proxy(obj, {\n get(proxyTarget, prop, receiver) {\n const value = Reflect.get(proxyTarget, prop, receiver);\n\n if (typeof prop !== 'string' || BUILT_IN_DO_METHODS.has(prop)) {\n return value;\n }\n\n const cached = rpcMethodCache.get(prop);\n\n if (cached) {\n return cached;\n }\n\n if (\n typeof value !== 'function' ||\n Object.prototype.hasOwnProperty.call(proxyTarget, prop) ||\n (allowSet && !allowSet.has(prop)) ||\n // Exclude inherited Object.prototype methods (toString, valueOf, etc.)\n // These are not RPC methods and should not create spans\n prop in Object.prototype\n ) {\n return value;\n }\n\n // Bind the method to the original object to ensure private fields work correctly.\n // When called via the Proxy, `this` would be the Proxy, but private fields require\n // the original object. Bound functions ignore the thisArg passed via Reflect.apply.\n const boundValue = (value as UncheckedMethod).bind(proxyTarget);\n\n const wrapped = wrapMethodWithSentry(\n { options, context, spanName: prop, spanOp: 'rpc' },\n boundValue,\n undefined,\n true,\n );\n\n rpcMethodCache.set(prop, wrapped);\n\n return wrapped;\n },\n });\n },\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createLangChainCallbackHandler, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, inboundFiltersIntegration, instrumentAnthropicAiClient, instrumentGoogleGenAIClient, instrumentLangChainEmbeddings, instrumentLangGraph, instrumentOpenAiClient, instrumentPostgresJsSql, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanStreamingIntegration, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, withStreamedSpan, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
1
+ export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createLangChainCallbackHandler, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, inboundFiltersIntegration, instrumentAnthropicAiClient, instrumentCreateReactAgent, instrumentGoogleGenAIClient, instrumentLangChainEmbeddings, instrumentLangGraph, instrumentOpenAiClient, instrumentPostgresJsSql, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanStreamingIntegration, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, withStreamedSpan, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
2
2
  export { withSentry } from './withSentry.js';
3
3
  export { instrumentDurableObjectWithSentry } from './durableobject.js';
4
4
  export { sentryPagesPlugin } from './pages-plugin.js';
5
5
  export { wrapRequestHandler } from './request.js';
6
6
  export { CloudflareClient } from './client.js';
7
7
  export { getDefaultIntegrations } from './sdk.js';
8
+ export { httpServerIntegration } from './integrations/httpServer.js';
8
9
  export { fetchIntegration } from './integrations/fetch.js';
9
10
  export { vercelAIIntegration } from './integrations/tracing/vercelai.js';
10
11
  export { honoIntegration } from './integrations/hono.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -1,5 +1,9 @@
1
+ import { appendRpcMeta } from '../utils/rpcMeta.js';
1
2
  import { instrumentFetcher } from './worker/instrumentFetcher.js';
2
3
 
4
+ // Built-in DurableObjectStub methods that are not RPC calls.
5
+ const STUB_NON_RPC_METHODS = new Set(['fetch', 'connect', 'dup']);
6
+
3
7
  /**
4
8
  * Instruments a DurableObjectNamespace binding to create spans for DO interactions.
5
9
  *
@@ -32,17 +36,22 @@ function instrumentDurableObjectNamespace(namespace) {
32
36
  }
33
37
 
34
38
  /**
35
- * Instruments a DurableObjectStub to propagate trace context across fetch calls.
39
+ * Instruments a DurableObjectStub to create spans for outgoing fetch calls
40
+ * and propagate trace context across RPC calls.
36
41
  *
37
42
  * @param stub - The DurableObjectStub to instrument
38
43
  */
39
44
  function instrumentDurableObjectStub(stub) {
40
45
  return new Proxy(stub, {
41
- get(target, prop, receiver) {
42
- const value = Reflect.get(target, prop, receiver);
46
+ get(target, prop) {
47
+ const value = Reflect.get(target, prop);
43
48
 
44
49
  if (prop === 'fetch' && typeof value === 'function') {
45
- return instrumentFetcher((input, init) => Reflect.apply(value, target, [input, init]));
50
+ return instrumentFetcher((...args) => Reflect.apply(value, target, args));
51
+ }
52
+
53
+ if (typeof value === 'function' && typeof prop === 'string' && !STUB_NON_RPC_METHODS.has(prop)) {
54
+ return (...args) => Reflect.apply(value, target, appendRpcMeta(args));
46
55
  }
47
56
 
48
57
  return value;
@@ -50,5 +59,5 @@ function instrumentDurableObjectStub(stub) {
50
59
  });
51
60
  }
52
61
 
53
- export { instrumentDurableObjectNamespace };
62
+ export { STUB_NON_RPC_METHODS, instrumentDurableObjectNamespace };
54
63
  //# sourceMappingURL=instrumentDurableObjectNamespace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentDurableObjectNamespace.js","sources":["../../../src/instrumentations/instrumentDurableObjectNamespace.ts"],"sourcesContent":["import type { DurableObjectNamespace, DurableObjectStub } from '@cloudflare/workers-types';\nimport { instrumentFetcher } from './worker/instrumentFetcher';\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 */\nexport function instrumentDurableObjectNamespace(namespace: DurableObjectNamespace): 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);\n };\n }\n\n return value.bind(target);\n },\n });\n}\n\n/**\n * Instruments a DurableObjectStub to propagate trace context across fetch calls.\n *\n * @param stub - The DurableObjectStub to instrument\n */\nfunction instrumentDurableObjectStub(stub: DurableObjectStub): DurableObjectStub {\n return new Proxy(stub, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n\n if (prop === 'fetch' && typeof value === 'function') {\n return instrumentFetcher((input, init) => Reflect.apply(value, target, [input, init]));\n }\n\n return value;\n },\n });\n}\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gCAAgC,CAAC,SAAS,EAAkD;AAC5G,EAAE,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE;AAC9B,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;AACjC,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAA;;AAE5C,MAAM,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACvC,QAAQ,OAAO,KAAK;AACpB,MAAM;;AAEN,MAAM,IAAI,IAAA,KAAS,SAAS,IAAA,KAAS,WAAW,EAAE;AAClD,QAAQ,OAAO,WAAyB,GAAG,IAAI,EAAa;AAC5D,UAAU,MAAM,IAAA,GAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;;AAEzD,UAAU,OAAO,2BAA2B,CAAC,IAAI,CAAC;AAClD,QAAQ,CAAC;AACT,MAAM;;AAEN,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/B,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,2BAA2B,CAAC,IAAI,EAAwC;AACjF,EAAE,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;AACzB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;AAChC,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;;AAEvD,MAAM,IAAI,IAAA,KAAS,OAAA,IAAW,OAAO,KAAA,KAAU,UAAU,EAAE;AAC3D,QAAQ,OAAO,iBAAiB,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9F,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
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 */\nexport function instrumentDurableObjectNamespace(namespace: DurableObjectNamespace): 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);\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 */\nfunction instrumentDurableObjectStub(stub: DurableObjectStub): 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 (typeof value === 'function' && typeof prop === 'string' && !STUB_NON_RPC_METHODS.has(prop)) {\n return (...args: unknown[]) => Reflect.apply(value, target, appendRpcMeta(args));\n }\n\n return value;\n },\n });\n}\n"],"names":[],"mappings":";;;AAIA;AACO,MAAM,oBAAA,GAAuB,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gCAAgC,CAAC,SAAS,EAAkD;AAC5G,EAAE,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE;AAC9B,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;AACjC,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAA;;AAE5C,MAAM,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACvC,QAAQ,OAAO,KAAK;AACpB,MAAM;;AAEN,MAAM,IAAI,IAAA,KAAS,SAAS,IAAA,KAAS,WAAW,EAAE;AAClD,QAAQ,OAAO,WAAyB,GAAG,IAAI,EAAa;AAC5D,UAAU,MAAM,IAAA,GAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;;AAEzD,UAAU,OAAO,2BAA2B,CAAC,IAAI,CAAC;AAClD,QAAQ,CAAC;AACT,MAAM;;AAEN,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/B,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,2BAA2B,CAAC,IAAI,EAAwC;AACjF,EAAE,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;AACzB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE;AACtB,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC;;AAE7C,MAAM,IAAI,IAAA,KAAS,OAAA,IAAW,OAAO,KAAA,KAAU,UAAU,EAAE;AAC3D,QAAQ,OAAO,iBAAiB,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACjF,MAAM;;AAEN,MAAM,IAAI,OAAO,UAAU,UAAA,IAAc,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACtG,QAAQ,OAAO,CAAC,GAAG,IAAI,KAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;AACxF,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
@@ -5,6 +5,7 @@ import { instrumentWorkerEntrypointScheduled } from './worker/instrumentSchedule
5
5
  import { instrumentWorkerEntrypointTail } from './worker/instrumentTail.js';
6
6
  import { getFinalOptions } from '../options.js';
7
7
  import { instrumentContext } from '../utils/instrumentContext.js';
8
+ import { instrumentEnv } from './worker/instrumentEnv.js';
8
9
 
9
10
  /**
10
11
  * Instruments a WorkerEntrypoint class to capture errors and performance data.
@@ -56,7 +57,8 @@ function instrumentWorkerEntrypoint(
56
57
  construct(target, [ctx, env]) {
57
58
  const context = instrumentContext(ctx);
58
59
  const options = getFinalOptions(optionsCallback(env), env);
59
- const obj = new target(context, env);
60
+ const instrumentedEnv = instrumentEnv(env, options);
61
+ const obj = new target(context, instrumentedEnv);
60
62
 
61
63
  // Override this.ctx to ensure the instrumented context is used
62
64
  // This is necessary because the base WorkerEntrypoint class sets this.ctx
@@ -71,6 +73,15 @@ function instrumentWorkerEntrypoint(
71
73
  });
72
74
  }
73
75
 
76
+ if ('env' in obj) {
77
+ Object.defineProperty(obj, 'env', {
78
+ value: instrumentedEnv,
79
+ writable: true,
80
+ enumerable: true,
81
+ configurable: true,
82
+ });
83
+ }
84
+
74
85
  Object.defineProperty(obj, '__SENTRY_CONTEXT__', {
75
86
  value: context,
76
87
  enumerable: false,
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentWorkerEntrypoint.js","sources":["../../../src/instrumentations/instrumentWorkerEntrypoint.ts"],"sourcesContent":["import { setAsyncLocalStorageAsyncContextStrategy } from '../async';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport type { CloudflareOptions } from '../client';\nimport { instrumentWorkerEntrypointFetch } from './worker/instrumentFetch';\nimport { instrumentWorkerEntrypointQueue } from './worker/instrumentQueue';\nimport { instrumentWorkerEntrypointScheduled } from './worker/instrumentScheduled';\nimport { instrumentWorkerEntrypointTail } from './worker/instrumentTail';\nimport { getFinalOptions } from '../options';\nimport { instrumentContext } from '../utils/instrumentContext';\n\nexport type WorkerEntrypointConstructor<Env = typeof cloudflareEnv, Props = {}> = new (\n ctx: ExecutionContext,\n env: typeof cloudflareEnv,\n) => InstanceType<typeof WorkerEntrypoint<Env, Props>>;\n\n/**\n * Instruments a WorkerEntrypoint class to capture errors and performance data.\n *\n * Instruments the following methods (same as `withSentry` for ExportedHandler):\n * - fetch (HTTP requests)\n * - scheduled (cron triggers)\n * - queue (queue consumers)\n * - email (email handlers)\n * - tail (tail workers)\n *\n * as well as any other public RPC methods on the WorkerEntrypoint instance.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param WorkerEntrypointClass The WorkerEntrypoint class to instrument.\n * @returns The instrumented WorkerEntrypoint class.\n *\n * @example\n * ```ts\n * class MyWorkerBase extends WorkerEntrypoint<Env> {\n * async fetch(request: Request): Promise<Response> {\n * return new Response('Hello World!');\n * }\n *\n * async myRpcMethod(arg: string): Promise<string> {\n * return `Hello ${arg}!`;\n * }\n * }\n *\n * export default instrumentWorkerEntrypoint(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyWorkerBase,\n * );\n * ```\n */\nexport function instrumentWorkerEntrypoint<T extends WorkerEntrypointConstructor>(\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n WorkerEntrypointClass: T,\n): T {\n // Set up AsyncLocalStorage strategy ONCE at instrumentation time, not per-request\n // This is critical - calling this per-request would create a new AsyncLocalStorage\n // each time, breaking scope isolation for concurrent requests\n setAsyncLocalStorageAsyncContextStrategy();\n\n return new Proxy(WorkerEntrypointClass, {\n construct(target, [ctx, env]) {\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n const obj = new target(context, env);\n\n // Override this.ctx to ensure the instrumented context is used\n // This is necessary because the base WorkerEntrypoint class sets this.ctx\n // from the constructor parameter, but we want users accessing this.ctx\n // to get the instrumented version\n if ('ctx' in obj) {\n Object.defineProperty(obj, 'ctx', {\n value: context,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n Object.defineProperty(obj, '__SENTRY_CONTEXT__', {\n value: context,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(obj, '__SENTRY_OPTIONS__', {\n value: options,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n instrumentWorkerEntrypointFetch(obj, options, context);\n instrumentWorkerEntrypointScheduled(obj, options, context);\n instrumentWorkerEntrypointQueue(obj, options, context);\n instrumentWorkerEntrypointTail(obj, options, context);\n\n return obj;\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,0BAA0B;AAC1C,EAAE,eAAe;AACjB,EAAE,qBAAqB;AACvB,EAAK;AACL;AACA;AACA;AACA,EAAE,wCAAwC,EAAE;;AAE5C,EAAE,OAAO,IAAI,KAAK,CAAC,qBAAqB,EAAE;AAC1C,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;AAClC,MAAM,MAAM,OAAA,GAAU,iBAAiB,CAAC,GAAG,CAAC;AAC5C,MAAM,MAAM,OAAA,GAAU,eAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;AAChE,MAAM,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;;AAE1C;AACA;AACA;AACA;AACA,MAAM,IAAI,KAAA,IAAS,GAAG,EAAE;AACxB,QAAQ,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE;AAC1C,UAAU,KAAK,EAAE,OAAO;AACxB,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,UAAU,EAAE,IAAI;AAC1B,UAAU,YAAY,EAAE,IAAI;AAC5B,SAAS,CAAC;AACV,MAAM;;AAEN,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,+BAA+B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAC5D,MAAM,mCAAmC,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAChE,MAAM,+BAA+B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAC5D,MAAM,8BAA8B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;;AAE3D,MAAM,OAAO,GAAG;AAChB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"instrumentWorkerEntrypoint.js","sources":["../../../src/instrumentations/instrumentWorkerEntrypoint.ts"],"sourcesContent":["import { setAsyncLocalStorageAsyncContextStrategy } from '../async';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport type { CloudflareOptions } from '../client';\nimport { instrumentWorkerEntrypointFetch } from './worker/instrumentFetch';\nimport { instrumentWorkerEntrypointQueue } from './worker/instrumentQueue';\nimport { instrumentWorkerEntrypointScheduled } from './worker/instrumentScheduled';\nimport { instrumentWorkerEntrypointTail } from './worker/instrumentTail';\nimport { getFinalOptions } from '../options';\nimport { instrumentContext } from '../utils/instrumentContext';\nimport { instrumentEnv } from './worker/instrumentEnv';\n\nexport type WorkerEntrypointConstructor<Env = typeof cloudflareEnv, Props = {}> = new (\n ctx: ExecutionContext,\n env: typeof cloudflareEnv,\n) => InstanceType<typeof WorkerEntrypoint<Env, Props>>;\n\n/**\n * Instruments a WorkerEntrypoint class to capture errors and performance data.\n *\n * Instruments the following methods (same as `withSentry` for ExportedHandler):\n * - fetch (HTTP requests)\n * - scheduled (cron triggers)\n * - queue (queue consumers)\n * - email (email handlers)\n * - tail (tail workers)\n *\n * as well as any other public RPC methods on the WorkerEntrypoint instance.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param WorkerEntrypointClass The WorkerEntrypoint class to instrument.\n * @returns The instrumented WorkerEntrypoint class.\n *\n * @example\n * ```ts\n * class MyWorkerBase extends WorkerEntrypoint<Env> {\n * async fetch(request: Request): Promise<Response> {\n * return new Response('Hello World!');\n * }\n *\n * async myRpcMethod(arg: string): Promise<string> {\n * return `Hello ${arg}!`;\n * }\n * }\n *\n * export default instrumentWorkerEntrypoint(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyWorkerBase,\n * );\n * ```\n */\nexport function instrumentWorkerEntrypoint<T extends WorkerEntrypointConstructor>(\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n WorkerEntrypointClass: T,\n): T {\n // Set up AsyncLocalStorage strategy ONCE at instrumentation time, not per-request\n // This is critical - calling this per-request would create a new AsyncLocalStorage\n // each time, breaking scope isolation for concurrent requests\n setAsyncLocalStorageAsyncContextStrategy();\n\n return new Proxy(WorkerEntrypointClass, {\n construct(target, [ctx, env]) {\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n const instrumentedEnv = instrumentEnv(env, options);\n const obj = new target(context, instrumentedEnv);\n\n // Override this.ctx to ensure the instrumented context is used\n // This is necessary because the base WorkerEntrypoint class sets this.ctx\n // from the constructor parameter, but we want users accessing this.ctx\n // to get the instrumented version\n if ('ctx' in obj) {\n Object.defineProperty(obj, 'ctx', {\n value: context,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n if ('env' in obj) {\n Object.defineProperty(obj, 'env', {\n value: instrumentedEnv,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n Object.defineProperty(obj, '__SENTRY_CONTEXT__', {\n value: context,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n Object.defineProperty(obj, '__SENTRY_OPTIONS__', {\n value: options,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n\n instrumentWorkerEntrypointFetch(obj, options, context);\n instrumentWorkerEntrypointScheduled(obj, options, context);\n instrumentWorkerEntrypointQueue(obj, options, context);\n instrumentWorkerEntrypointTail(obj, options, context);\n\n return obj;\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,0BAA0B;AAC1C,EAAE,eAAe;AACjB,EAAE,qBAAqB;AACvB,EAAK;AACL;AACA;AACA;AACA,EAAE,wCAAwC,EAAE;;AAE5C,EAAE,OAAO,IAAI,KAAK,CAAC,qBAAqB,EAAE;AAC1C,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;AAClC,MAAM,MAAM,OAAA,GAAU,iBAAiB,CAAC,GAAG,CAAC;AAC5C,MAAM,MAAM,OAAA,GAAU,eAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;AAChE,MAAM,MAAM,kBAAkB,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC;AACzD,MAAM,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC;;AAEtD;AACA;AACA;AACA;AACA,MAAM,IAAI,KAAA,IAAS,GAAG,EAAE;AACxB,QAAQ,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE;AAC1C,UAAU,KAAK,EAAE,OAAO;AACxB,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,UAAU,EAAE,IAAI;AAC1B,UAAU,YAAY,EAAE,IAAI;AAC5B,SAAS,CAAC;AACV,MAAM;;AAEN,MAAM,IAAI,KAAA,IAAS,GAAG,EAAE;AACxB,QAAQ,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE;AAC1C,UAAU,KAAK,EAAE,eAAe;AAChC,UAAU,QAAQ,EAAE,IAAI;AACxB,UAAU,UAAU,EAAE,IAAI;AAC1B,UAAU,YAAY,EAAE,IAAI;AAC5B,SAAS,CAAC;AACV,MAAM;;AAEN,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAoB,EAAE;AACvD,QAAQ,KAAK,EAAE,OAAO;AACtB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE,KAAK;AAC3B,OAAO,CAAC;;AAER,MAAM,+BAA+B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAC5D,MAAM,mCAAmC,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAChE,MAAM,+BAA+B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;AAC5D,MAAM,8BAA8B,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC;;AAE3D,MAAM,OAAO,GAAG;AAChB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
@@ -1,7 +1,9 @@
1
- import { isDurableObjectNamespace, isJSRPC } from '../../utils/isBinding.js';
1
+ import { isQueue, isDurableObjectNamespace, isJSRPC } from '../../utils/isBinding.js';
2
+ import { appendRpcMeta } from '../../utils/rpcMeta.js';
2
3
  import { getEffectiveRpcPropagation } from '../../utils/rpcOptions.js';
3
- import { instrumentDurableObjectNamespace } from '../instrumentDurableObjectNamespace.js';
4
+ import { instrumentDurableObjectNamespace, STUB_NON_RPC_METHODS } from '../instrumentDurableObjectNamespace.js';
4
5
  import { instrumentFetcher } from './instrumentFetcher.js';
6
+ import { instrumentQueueProducer } from './instrumentQueueProducer.js';
5
7
 
6
8
  function isProxyable(item) {
7
9
  return item !== null && (typeof item === 'object' || typeof item === 'function');
@@ -15,9 +17,10 @@ const instrumentedBindings = new WeakMap();
15
17
  *
16
18
  * Currently detects:
17
19
  * - DurableObjectNamespace (via `idFromName` duck-typing)
18
- * - Service bindings / JSRPC proxies (wraps `fetch` for trace propagation)
20
+ * - Service bindings / JSRPC proxies
21
+ * - Queue producers (via `send` + `sendBatch` duck-typing)
19
22
  *
20
- * Extensible for future binding types (KV, D1, Queue, etc.).
23
+ * Extensible for future binding types (KV, D1, etc.).
21
24
  *
22
25
  * @param env - The Cloudflare env object to instrument
23
26
  * @param options - Optional CloudflareOptions to control RPC trace propagation
@@ -29,12 +32,6 @@ function instrumentEnv(env, options) {
29
32
 
30
33
  const rpcPropagation = options ? getEffectiveRpcPropagation(options) : false;
31
34
 
32
- // As of now only trace propagation is used for the instrumentEnv
33
- // so this is an optimization to avoid wrapping the env in a proxy if trace propagation is disabled
34
- if (!rpcPropagation) {
35
- return env;
36
- }
37
-
38
35
  return new Proxy(env, {
39
36
  get(target, prop, receiver) {
40
37
  const item = Reflect.get(target, prop, receiver);
@@ -49,6 +46,17 @@ function instrumentEnv(env, options) {
49
46
  return cached;
50
47
  }
51
48
 
49
+ if (isQueue(item)) {
50
+ const bindingName = typeof prop === 'string' ? prop : String(prop);
51
+ const instrumented = instrumentQueueProducer(item, bindingName);
52
+ instrumentedBindings.set(item, instrumented);
53
+ return instrumented;
54
+ }
55
+
56
+ if (!rpcPropagation) {
57
+ return item;
58
+ }
59
+
52
60
  if (isDurableObjectNamespace(item)) {
53
61
  const instrumented = instrumentDurableObjectNamespace(item);
54
62
  instrumentedBindings.set(item, instrumented);
@@ -57,11 +65,15 @@ function instrumentEnv(env, options) {
57
65
 
58
66
  if (isJSRPC(item)) {
59
67
  const instrumented = new Proxy(item, {
60
- get(target, p, rcv) {
61
- const value = Reflect.get(target, p, rcv);
68
+ get(target, p) {
69
+ const value = Reflect.get(target, p);
62
70
 
63
71
  if (p === 'fetch' && typeof value === 'function') {
64
- return instrumentFetcher(value.bind(target));
72
+ return instrumentFetcher((...args) => Reflect.apply(value, target, args));
73
+ }
74
+
75
+ if (typeof value === 'function' && typeof p === 'string' && !STUB_NON_RPC_METHODS.has(p)) {
76
+ return (...args) => Reflect.apply(value, target, appendRpcMeta(args));
65
77
  }
66
78
 
67
79
  return value;
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentEnv.js","sources":["../../../../src/instrumentations/worker/instrumentEnv.ts"],"sourcesContent":["import type { CloudflareOptions } from '../../client';\nimport { isDurableObjectNamespace, isJSRPC } from '../../utils/isBinding';\nimport { getEffectiveRpcPropagation } from '../../utils/rpcOptions';\nimport { instrumentDurableObjectNamespace } from '../instrumentDurableObjectNamespace';\nimport { instrumentFetcher } from './instrumentFetcher';\n\nfunction isProxyable(item: unknown): item is object {\n return item !== null && (typeof item === 'object' || typeof item === 'function');\n}\n\nconst instrumentedBindings = new WeakMap<object, unknown>();\n\n/**\n * Wraps the Cloudflare `env` object in a Proxy that detects binding types\n * on property access and returns instrumented versions.\n *\n * Currently detects:\n * - DurableObjectNamespace (via `idFromName` duck-typing)\n * - Service bindings / JSRPC proxies (wraps `fetch` for trace propagation)\n *\n * Extensible for future binding types (KV, D1, Queue, etc.).\n *\n * @param env - The Cloudflare env object to instrument\n * @param options - Optional CloudflareOptions to control RPC trace propagation\n */\nexport function instrumentEnv<Env extends Record<string, unknown>>(env: Env, options?: CloudflareOptions): Env {\n if (!env || typeof env !== 'object') {\n return env;\n }\n\n const rpcPropagation = options ? getEffectiveRpcPropagation(options) : false;\n\n // As of now only trace propagation is used for the instrumentEnv\n // so this is an optimization to avoid wrapping the env in a proxy if trace propagation is disabled\n if (!rpcPropagation) {\n return env;\n }\n\n return new Proxy(env, {\n get(target, prop, receiver) {\n const item = Reflect.get(target, prop, receiver);\n\n if (!isProxyable(item)) {\n return item;\n }\n\n const cached = instrumentedBindings.get(item);\n\n if (cached) {\n return cached;\n }\n\n if (isDurableObjectNamespace(item)) {\n const instrumented = instrumentDurableObjectNamespace(item);\n instrumentedBindings.set(item, instrumented);\n return instrumented;\n }\n\n if (isJSRPC(item)) {\n const instrumented = new Proxy(item, {\n get(target, p, rcv) {\n const value = Reflect.get(target, p, rcv);\n\n if (p === 'fetch' && typeof value === 'function') {\n return instrumentFetcher(value.bind(target));\n }\n\n return value;\n },\n });\n\n instrumentedBindings.set(item, instrumented);\n return instrumented;\n }\n\n return item;\n },\n });\n}\n"],"names":[],"mappings":";;;;;AAMA,SAAS,WAAW,CAAC,IAAI,EAA2B;AACpD,EAAE,OAAO,IAAA,KAAS,IAAA,KAAS,OAAO,IAAA,KAAS,YAAY,OAAO,IAAA,KAAS,UAAU,CAAC;AAClF;;AAEA,MAAM,oBAAA,GAAuB,IAAI,OAAO,EAAmB;;AAE3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAsC,GAAG,EAAO,OAAO,EAA2B;AAC/G,EAAE,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAQ,EAAE;AACvC,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF,EAAE,MAAM,cAAA,GAAiB,OAAA,GAAU,0BAA0B,CAAC,OAAO,CAAA,GAAI,KAAK;;AAE9E;AACA;AACA,EAAE,IAAI,CAAC,cAAc,EAAE;AACvB,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE;AACxB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;AAChC,MAAM,MAAM,IAAA,GAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;;AAEtD,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;AAC9B,QAAQ,OAAO,IAAI;AACnB,MAAM;;AAEN,MAAM,MAAM,SAAS,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;;AAEnD,MAAM,IAAI,MAAM,EAAE;AAClB,QAAQ,OAAO,MAAM;AACrB,MAAM;;AAEN,MAAM,IAAI,wBAAwB,CAAC,IAAI,CAAC,EAAE;AAC1C,QAAQ,MAAM,YAAA,GAAe,gCAAgC,CAAC,IAAI,CAAC;AACnE,QAAQ,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;AACpD,QAAQ,OAAO,YAAY;AAC3B,MAAM;;AAEN,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;AACzB,QAAQ,MAAM,YAAA,GAAe,IAAI,KAAK,CAAC,IAAI,EAAE;AAC7C,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;AAC9B,YAAY,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC;;AAErD,YAAY,IAAI,CAAA,KAAM,OAAA,IAAW,OAAO,KAAA,KAAU,UAAU,EAAE;AAC9D,cAAc,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1D,YAAY;;AAEZ,YAAY,OAAO,KAAK;AACxB,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV,QAAQ,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;AACpD,QAAQ,OAAO,YAAY;AAC3B,MAAM;;AAEN,MAAM,OAAO,IAAI;AACjB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"instrumentEnv.js","sources":["../../../../src/instrumentations/worker/instrumentEnv.ts"],"sourcesContent":["import type { CloudflareOptions } from '../../client';\nimport { isDurableObjectNamespace, isJSRPC, isQueue } from '../../utils/isBinding';\nimport { appendRpcMeta } from '../../utils/rpcMeta';\nimport { getEffectiveRpcPropagation } from '../../utils/rpcOptions';\nimport { instrumentDurableObjectNamespace, STUB_NON_RPC_METHODS } from '../instrumentDurableObjectNamespace';\nimport { instrumentFetcher } from './instrumentFetcher';\nimport { instrumentQueueProducer } from './instrumentQueueProducer';\n\nfunction isProxyable(item: unknown): item is object {\n return item !== null && (typeof item === 'object' || typeof item === 'function');\n}\n\nconst instrumentedBindings = new WeakMap<object, unknown>();\n\n/**\n * Wraps the Cloudflare `env` object in a Proxy that detects binding types\n * on property access and returns instrumented versions.\n *\n * Currently detects:\n * - DurableObjectNamespace (via `idFromName` duck-typing)\n * - Service bindings / JSRPC proxies\n * - Queue producers (via `send` + `sendBatch` duck-typing)\n *\n * Extensible for future binding types (KV, D1, etc.).\n *\n * @param env - The Cloudflare env object to instrument\n * @param options - Optional CloudflareOptions to control RPC trace propagation\n */\nexport function instrumentEnv<Env extends Record<string, unknown>>(env: Env, options?: CloudflareOptions): Env {\n if (!env || typeof env !== 'object') {\n return env;\n }\n\n const rpcPropagation = options ? getEffectiveRpcPropagation(options) : false;\n\n return new Proxy(env, {\n get(target, prop, receiver) {\n const item = Reflect.get(target, prop, receiver);\n\n if (!isProxyable(item)) {\n return item;\n }\n\n const cached = instrumentedBindings.get(item);\n\n if (cached) {\n return cached;\n }\n\n if (isQueue(item)) {\n const bindingName = typeof prop === 'string' ? prop : String(prop);\n const instrumented = instrumentQueueProducer(item, bindingName);\n instrumentedBindings.set(item, instrumented);\n return instrumented;\n }\n\n if (!rpcPropagation) {\n return item;\n }\n\n if (isDurableObjectNamespace(item)) {\n const instrumented = instrumentDurableObjectNamespace(item);\n instrumentedBindings.set(item, instrumented);\n return instrumented;\n }\n\n if (isJSRPC(item)) {\n const instrumented = new Proxy(item, {\n get(target, p) {\n const value = Reflect.get(target, p);\n\n if (p === 'fetch' && typeof value === 'function') {\n return instrumentFetcher((...args) => Reflect.apply(value, target, args));\n }\n\n if (typeof value === 'function' && typeof p === 'string' && !STUB_NON_RPC_METHODS.has(p)) {\n return (...args: unknown[]) => Reflect.apply(value, target, appendRpcMeta(args));\n }\n\n return value;\n },\n });\n\n instrumentedBindings.set(item, instrumented);\n return instrumented;\n }\n\n return item;\n },\n });\n}\n"],"names":[],"mappings":";;;;;;;AAQA,SAAS,WAAW,CAAC,IAAI,EAA2B;AACpD,EAAE,OAAO,IAAA,KAAS,IAAA,KAAS,OAAO,IAAA,KAAS,YAAY,OAAO,IAAA,KAAS,UAAU,CAAC;AAClF;;AAEA,MAAM,oBAAA,GAAuB,IAAI,OAAO,EAAmB;;AAE3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAsC,GAAG,EAAO,OAAO,EAA2B;AAC/G,EAAE,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAQ,EAAE;AACvC,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF,EAAE,MAAM,cAAA,GAAiB,OAAA,GAAU,0BAA0B,CAAC,OAAO,CAAA,GAAI,KAAK;;AAE9E,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE;AACxB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;AAChC,MAAM,MAAM,IAAA,GAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;;AAEtD,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;AAC9B,QAAQ,OAAO,IAAI;AACnB,MAAM;;AAEN,MAAM,MAAM,SAAS,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;;AAEnD,MAAM,IAAI,MAAM,EAAE;AAClB,QAAQ,OAAO,MAAM;AACrB,MAAM;;AAEN,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;AACzB,QAAQ,MAAM,WAAA,GAAc,OAAO,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,MAAM,CAAC,IAAI,CAAC;AAC1E,QAAQ,MAAM,eAAe,uBAAuB,CAAC,IAAI,EAAE,WAAW,CAAC;AACvE,QAAQ,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;AACpD,QAAQ,OAAO,YAAY;AAC3B,MAAM;;AAEN,MAAM,IAAI,CAAC,cAAc,EAAE;AAC3B,QAAQ,OAAO,IAAI;AACnB,MAAM;;AAEN,MAAM,IAAI,wBAAwB,CAAC,IAAI,CAAC,EAAE;AAC1C,QAAQ,MAAM,YAAA,GAAe,gCAAgC,CAAC,IAAI,CAAC;AACnE,QAAQ,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;AACpD,QAAQ,OAAO,YAAY;AAC3B,MAAM;;AAEN,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;AACzB,QAAQ,MAAM,YAAA,GAAe,IAAI,KAAK,CAAC,IAAI,EAAE;AAC7C,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;AACzB,YAAY,MAAM,KAAA,GAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;;AAEhD,YAAY,IAAI,CAAA,KAAM,OAAA,IAAW,OAAO,KAAA,KAAU,UAAU,EAAE;AAC9D,cAAc,OAAO,iBAAiB,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACvF,YAAY;;AAEZ,YAAY,IAAI,OAAO,UAAU,UAAA,IAAc,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACtG,cAAc,OAAO,CAAC,GAAG,IAAI,KAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;AAC9F,YAAY;;AAEZ,YAAY,OAAO,KAAK;AACxB,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV,QAAQ,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC;AACpD,QAAQ,OAAO,YAAY;AAC3B,MAAM;;AAEN,MAAM,OAAO,IAAI;AACjB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;;;;"}
@@ -32,6 +32,8 @@ function wrapQueueHandler(
32
32
  'faas.trigger': 'pubsub',
33
33
  'messaging.destination.name': batch.queue,
34
34
  'messaging.system': 'cloudflare',
35
+ 'messaging.operation.type': 'process',
36
+ 'messaging.operation.name': 'process',
35
37
  'messaging.batch.message_count': batch.messages.length,
36
38
  'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts - 1, 0),
37
39
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentQueue.js","sources":["../../../../src/instrumentations/worker/instrumentQueue.ts"],"sourcesContent":["import type { ExportedHandler, MessageBatch } from '@cloudflare/workers-types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} 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 { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core queue handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapQueueHandler(\n batch: MessageBatch,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.queue',\n name: `process ${batch.queue}`,\n attributes: {\n 'faas.trigger': 'pubsub',\n 'messaging.destination.name': batch.queue,\n 'messaging.system': 'cloudflare',\n 'messaging.batch.message_count': batch.messages.length,\n 'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts - 1, 0),\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',\n [SEMANTIC_ATTRIBUTE_SENTRY_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.queue' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a queue handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerQueue<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('queue' in handler) || typeof handler.queue !== 'function') {\n return;\n }\n\n handler.queue = ensureInstrumented(\n handler.queue,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['queue']>>) {\n const [batch, 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 wrapQueueHandler(batch, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a queue method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointQueue<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.queue) {\n return;\n }\n\n const original = instance.queue.bind(instance);\n instance.queue = new Proxy(original, {\n apply(target, thisArg, args: [MessageBatch]) {\n const [batch] = args;\n\n return wrapQueueHandler(batch, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentQueue.js","sources":["../../../../src/instrumentations/worker/instrumentQueue.ts"],"sourcesContent":["import type { ExportedHandler, MessageBatch } from '@cloudflare/workers-types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n withIsolationScope,\n} 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 { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core queue handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapQueueHandler(\n batch: MessageBatch,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n op: 'faas.queue',\n name: `process ${batch.queue}`,\n attributes: {\n 'faas.trigger': 'pubsub',\n 'messaging.destination.name': batch.queue,\n 'messaging.system': 'cloudflare',\n 'messaging.operation.type': 'process',\n 'messaging.operation.name': 'process',\n 'messaging.batch.message_count': batch.messages.length,\n 'messaging.message.retry.count': batch.messages.reduce((acc, message) => acc + message.attempts - 1, 0),\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'queue.process',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.queue',\n [SEMANTIC_ATTRIBUTE_SENTRY_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.queue' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a queue handler for ExportedHandler (env/ctx come from args).\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function instrumentExportedHandlerQueue<T extends ExportedHandler<any, any, any>>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('queue' in handler) || typeof handler.queue !== 'function') {\n return;\n }\n\n handler.queue = ensureInstrumented(\n handler.queue,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['queue']>>) {\n const [batch, 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 wrapQueueHandler(batch, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a queue method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointQueue<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.queue) {\n return;\n }\n\n const original = instance.queue.bind(instance);\n instance.queue = new Proxy(original, {\n apply(target, thisArg, args: [MessageBatch]) {\n const [batch] = args;\n\n return wrapQueueHandler(batch, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":[],"mappings":"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"}