@inference-net/otel-cf-workers 2.1.0 → 2.2.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.
package/dist/index.d.ts CHANGED
@@ -177,6 +177,36 @@ export declare interface InstrumentationOptions {
177
177
 
178
178
  export declare function instrumentDO(doClass: DOClass, config: ConfigurationOption): DOClass;
179
179
 
180
+ /**
181
+ * Base class for instrumented Durable Objects with TypeScript support for injected methods.
182
+ * Extend this instead of DurableObject to automatically get typing for `this.instrument()`.
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * import { InstrumentedDurableObject } from '@inference-net/otel-cf-workers'
187
+ *
188
+ * export class MyDO extends InstrumentedDurableObject<Env> {
189
+ * async someMethod() {
190
+ * // this.instrument is available with full TypeScript support!
191
+ * await this.instrument('custom-operation', async () => {
192
+ * // Your code here
193
+ * })
194
+ * }
195
+ * }
196
+ * ```
197
+ */
198
+ export declare class InstrumentedDurableObject<Env = unknown> extends DurableObject_2<Env> {
199
+ instrument: InstrumentMethod;
200
+ }
201
+
202
+ export declare type InstrumentMethod = {
203
+ <T>(name: string, fn: () => Promise<T>): Promise<T>;
204
+ <T>(name: string, options: InstrumentOptions, fn: () => Promise<T>): Promise<T>;
205
+ };
206
+
207
+ export declare interface InstrumentOptions extends Omit<SpanOptions, 'kind'> {
208
+ }
209
+
180
210
  export declare function isAlarm(trigger: Trigger): trigger is 'do-alarm';
181
211
 
182
212
  export declare const isHeadSampled: TailSampleFn;
package/dist/index.js CHANGED
@@ -96,7 +96,7 @@ function passthroughGet(target, prop, thisArg) {
96
96
  }
97
97
  }
98
98
 
99
- const PACKAGE_VERSION = "2.1.0";
99
+ const PACKAGE_VERSION = "2.2.0";
100
100
  const PACKAGE_NAME = "@inference-net/otel-cf-workers";
101
101
  const ATTR_CLOUDFLARE_COLO = "cloudflare.colo";
102
102
  const ATTR_CLOUDFLARE_RAY_ID = "cloudflare.ray_id";
@@ -1443,9 +1443,10 @@ function getParentContextFromRequest(request) {
1443
1443
  }
1444
1444
  function updateSpanNameOnRoute(span, request, result) {
1445
1445
  const readable = span;
1446
- if (readable.attributes["http.route"]) {
1446
+ const route = readable.attributes?.["http.route"];
1447
+ if (route) {
1447
1448
  const method = request.method.toUpperCase();
1448
- span.updateName(`${method} ${readable.attributes["http.route"]}`);
1449
+ span.updateName(`${method} ${route}`);
1449
1450
  }
1450
1451
  if (result) {
1451
1452
  if (result.status >= 400) {
@@ -3032,6 +3033,49 @@ function extractAndRemoveRpcContext(args) {
3032
3033
  return [void 0, args];
3033
3034
  }
3034
3035
 
3036
+ class InstrumentedDurableObject extends DurableObject {
3037
+ }
3038
+ function createInstrumentMethod(state, initialiser, env) {
3039
+ return async function instrument(name, optionsOrFn, maybeFn) {
3040
+ const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
3041
+ const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
3042
+ const tracer = trace.getTracer("DO custom span");
3043
+ const spanOptions = {
3044
+ ...options,
3045
+ attributes: {
3046
+ "do.id": state.id.toString(),
3047
+ ...state.id.name && { "do.name": state.id.name },
3048
+ ...options.attributes
3049
+ }
3050
+ };
3051
+ const executeWithConfig = async () => {
3052
+ const currentContext = context.active();
3053
+ const existingConfig = getActiveConfig();
3054
+ let context$1 = currentContext;
3055
+ if (!existingConfig) {
3056
+ const config = initialiser(env, { id: state.id.toString(), name: state.id.name });
3057
+ context$1 = setConfig(config, currentContext);
3058
+ }
3059
+ return context.with(
3060
+ context$1,
3061
+ () => tracer.startActiveSpan(name, spanOptions, async (span) => {
3062
+ try {
3063
+ const result = await fn();
3064
+ span.setStatus({ code: SpanStatusCode.OK });
3065
+ return result;
3066
+ } catch (error) {
3067
+ span.recordException(error);
3068
+ span.setStatus({ code: SpanStatusCode.ERROR });
3069
+ throw error;
3070
+ } finally {
3071
+ span.end();
3072
+ }
3073
+ })
3074
+ );
3075
+ };
3076
+ return executeWithConfig();
3077
+ };
3078
+ }
3035
3079
  function instrumentRpcMethod(method, methodName, nsName, stubId) {
3036
3080
  const tracer = trace.getTracer("do_rpc_client");
3037
3081
  const rpcHandler = {
@@ -3276,14 +3320,10 @@ function instrumentRpcHandlerMethod(fn, methodName, initialiser, env, id) {
3276
3320
  };
3277
3321
  return wrap(fn, fnHandler);
3278
3322
  }
3279
- function instrumentDurableObject(doObj, initialiser, env, state, classStyle) {
3323
+ function instrumentDurableObject(doObj, initialiser, env, state) {
3280
3324
  const objHandler = {
3281
3325
  get(target, prop) {
3282
- if (classStyle && prop === "ctx") {
3283
- return state;
3284
- } else if (classStyle && prop === "env") {
3285
- return env;
3286
- } else if (prop === "fetch") {
3326
+ if (prop === "fetch") {
3287
3327
  const fetchFn = Reflect.get(target, prop);
3288
3328
  return instrumentFetchFn(fetchFn, initialiser, env, state.id);
3289
3329
  } else if (prop === "alarm") {
@@ -3312,16 +3352,28 @@ function instrumentDOClass(doClass, initialiser) {
3312
3352
  const context$1 = setConfig(constructorConfig);
3313
3353
  const state = instrumentState(orig_state);
3314
3354
  const env = instrumentEnv(orig_env);
3315
- const classStyle = doClass.prototype instanceof DurableObject;
3316
- const createDO = () => {
3317
- if (classStyle) {
3318
- return new target(orig_state, orig_env);
3319
- } else {
3320
- return new target(state, env);
3321
- }
3322
- };
3355
+ const createDO = () => new target(orig_state, orig_env);
3323
3356
  const doObj = context.with(context$1, createDO);
3324
- return instrumentDurableObject(doObj, initialiser, env, state, classStyle);
3357
+ const instrumentMethod = createInstrumentMethod(state, initialiser, env);
3358
+ Object.defineProperty(doObj, "instrument", {
3359
+ value: instrumentMethod,
3360
+ writable: false,
3361
+ enumerable: false,
3362
+ configurable: true
3363
+ });
3364
+ Object.defineProperty(doObj, "env", {
3365
+ value: env,
3366
+ writable: false,
3367
+ enumerable: true,
3368
+ configurable: true
3369
+ });
3370
+ Object.defineProperty(doObj, "ctx", {
3371
+ value: state,
3372
+ writable: false,
3373
+ enumerable: true,
3374
+ configurable: true
3375
+ });
3376
+ return instrumentDurableObject(doObj, initialiser, env, state);
3325
3377
  }
3326
3378
  };
3327
3379
  return wrap(doClass, classHandler);
@@ -3540,12 +3592,19 @@ function createHandlerFlowFn(instrumentation) {
3540
3592
  const result = tracer.startActiveSpan(name, options, parentContext, async (span) => {
3541
3593
  try {
3542
3594
  const result2 = await handlerFn(instrumentedTrigger, proxiedEnv, proxiedCtx);
3543
- if (instrumentation.getAttributesFromResult) {
3544
- const attributes = instrumentation.getAttributesFromResult(result2);
3545
- span.setAttributes(attributes);
3546
- }
3547
- if (instrumentation.executionSucces) {
3548
- instrumentation.executionSucces(span, trigger, result2);
3595
+ const isWebSocketUpgrade = isRequest(trigger) && trigger.headers.get("upgrade")?.toLowerCase() === "websocket" && trigger.headers.has("sec-websocket-key");
3596
+ if (isWebSocketUpgrade) {
3597
+ const logger = getLogger("handler");
3598
+ logger.trace("WebSocket upgrade detected, closing span without reading response");
3599
+ span.setStatus({ code: SpanStatusCode.OK });
3600
+ } else {
3601
+ if (instrumentation.getAttributesFromResult) {
3602
+ const attributes = instrumentation.getAttributesFromResult(result2);
3603
+ span.setAttributes(attributes);
3604
+ }
3605
+ if (instrumentation.executionSucces) {
3606
+ instrumentation.executionSucces(span, trigger, result2);
3607
+ }
3549
3608
  }
3550
3609
  return result2;
3551
3610
  } catch (error) {
@@ -3858,5 +3917,5 @@ class ConsoleTransport {
3858
3917
  }
3859
3918
  }
3860
3919
 
3861
- export { BatchSizeLogRecordProcessor, BatchTraceSpanProcessor, ConsoleTransport, ImmediateLogRecordProcessor, MultiSpanExporter, MultiSpanExporterAsync, MultiTransportLogRecordProcessor, OTLPExporter, OTLPTransport, SEVERITY_NUMBERS, SpanImpl, WorkerLogger, WorkerLoggerProvider, __unwrappedFetch, createLogProcessor, createSampler, exportSpans, exportTelemetry, getGlobalLoggerProvider, getLogger, instrument, instrumentDO, isAlarm, isHeadSampled, isMessageBatch, isRequest, isRootErrorSpan, multiTailSampler, setGlobalLoggerProvider, withNextSpan };
3920
+ export { BatchSizeLogRecordProcessor, BatchTraceSpanProcessor, ConsoleTransport, ImmediateLogRecordProcessor, InstrumentedDurableObject, MultiSpanExporter, MultiSpanExporterAsync, MultiTransportLogRecordProcessor, OTLPExporter, OTLPTransport, SEVERITY_NUMBERS, SpanImpl, WorkerLogger, WorkerLoggerProvider, __unwrappedFetch, createLogProcessor, createSampler, exportSpans, exportTelemetry, getGlobalLoggerProvider, getLogger, instrument, instrumentDO, isAlarm, isHeadSampled, isMessageBatch, isRequest, isRootErrorSpan, multiTailSampler, setGlobalLoggerProvider, withNextSpan };
3862
3921
  //# sourceMappingURL=index.js.map