@moostjs/otel 0.4.15 → 0.4.16

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.cjs CHANGED
@@ -117,6 +117,49 @@ function getMoostMetrics() {
117
117
  return moostMetrics;
118
118
  }
119
119
 
120
+ function withSpan(span, cb, postProcess) {
121
+ const _span = typeof span.name === 'string' && !span.spanContext
122
+ ? span
123
+ : api.trace
124
+ .getTracer('default')
125
+ .startSpan(span.name, span.options);
126
+ let result = undefined;
127
+ const finalizeSpan = (e, r) => {
128
+ if (e) {
129
+ _span.recordException(e);
130
+ }
131
+ if (postProcess) {
132
+ postProcess(_span, e, r);
133
+ }
134
+ else {
135
+ _span.end();
136
+ }
137
+ };
138
+ api.context.with(api.trace.setSpan(api.context.active(), _span), () => {
139
+ try {
140
+ result = cb();
141
+ }
142
+ catch (error) {
143
+ finalizeSpan(error, undefined);
144
+ throw error;
145
+ }
146
+ if (result instanceof Promise) {
147
+ result
148
+ .then(r => {
149
+ finalizeSpan(undefined, r);
150
+ return r;
151
+ })
152
+ .catch(error => {
153
+ finalizeSpan(error, undefined);
154
+ });
155
+ }
156
+ else {
157
+ finalizeSpan(undefined, result);
158
+ }
159
+ });
160
+ return result;
161
+ }
162
+
120
163
  const tracer = api.trace.getTracer('moost-tracer');
121
164
  class SpanInjector extends moost.ContextInjector {
122
165
  constructor() {
@@ -135,10 +178,11 @@ class SpanInjector extends moost.ContextInjector {
135
178
  }
136
179
  else {
137
180
  const span = tracer.startSpan(name, {
181
+ kind: api.SpanKind.INTERNAL,
138
182
  attributes: attrs,
139
183
  });
140
184
  return this.withSpan(span, fn, {
141
- rootSpan: false,
185
+ withMetrics: false,
142
186
  endSpan: true,
143
187
  });
144
188
  }
@@ -174,7 +218,7 @@ class SpanInjector extends moost.ContextInjector {
174
218
  if (span) {
175
219
  registerSpan(span);
176
220
  return this.withSpan(span, cb, {
177
- rootSpan: true,
221
+ withMetrics: true,
178
222
  endSpan: eventType !== 'HTTP',
179
223
  });
180
224
  }
@@ -252,48 +296,20 @@ class SpanInjector extends moost.ContextInjector {
252
296
  }
253
297
  }
254
298
  withSpan(span, cb, opts) {
255
- let result;
256
- let exception;
257
- const endSpan = (error) => {
258
- if (error) {
259
- span.recordException(error);
299
+ return withSpan(span, cb, (_span, exception, result) => {
300
+ if (result instanceof Error) {
301
+ _span.recordException(result);
260
302
  }
261
- if (opts.rootSpan) {
303
+ if (opts.withMetrics) {
262
304
  const chm = this.getControllerHandlerMeta();
263
305
  if (!chm.ignoreMeter) {
264
- this.endEventMetrics(chm.attrs, error);
306
+ this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
265
307
  }
266
308
  }
267
309
  if (opts.endSpan) {
268
- span.end();
269
- }
270
- };
271
- api.context.with(api.trace.setSpan(api.context.active(), span), () => {
272
- try {
273
- result = cb();
274
- }
275
- catch (error) {
276
- exception = error;
277
- endSpan(exception);
310
+ _span.end();
278
311
  }
279
312
  });
280
- const ret = result;
281
- if (!exception) {
282
- if (ret && ret instanceof Promise) {
283
- ret
284
- .then(r => {
285
- endSpan(r instanceof Error ? r : undefined);
286
- return r;
287
- })
288
- .catch(error => {
289
- endSpan(error);
290
- });
291
- }
292
- else {
293
- endSpan(ret instanceof Error ? ret : undefined);
294
- }
295
- }
296
- return ret;
297
313
  }
298
314
  startEventMetrics(a, route) {
299
315
  if (a['moost.event_type'] === 'HTTP') {
@@ -1220,3 +1236,4 @@ exports.useOtelContext = useOtelContext;
1220
1236
  exports.useOtelPropagation = useOtelPropagation;
1221
1237
  exports.useSpan = useSpan;
1222
1238
  exports.useTrace = useTrace;
1239
+ exports.withSpan = withSpan;
package/dist/index.d.ts CHANGED
@@ -230,7 +230,7 @@ declare class SpanInjector extends ContextInjector<TContextInjectorHook> {
230
230
  };
231
231
  hook(method: string, name: 'Handler:not_found' | 'Handler:routed' | 'Controller:registered', route?: string): void;
232
232
  withSpan<T>(span: Span, cb: () => T, opts: {
233
- rootSpan: boolean;
233
+ withMetrics: boolean;
234
234
  endSpan: boolean;
235
235
  }): T;
236
236
  startEventMetrics(a: Record<string, string | number | boolean | undefined>, route?: string): void;
@@ -242,4 +242,23 @@ declare class SpanInjector extends ContextInjector<TContextInjectorHook> {
242
242
  }) | undefined;
243
243
  }
244
244
 
245
- export { MoostBatchSpanProcessor, MoostSimpleSpanProcessor, OtelIgnoreMeter, OtelIgnoreSpan, SpanInjector, type TOtelContext, type TOtelMate, enableOtelForMoost, getOtelMate, shouldSpanBeIgnored, useOtelContext, useOtelPropagation, useSpan, useTrace };
245
+ type TPostSpanProcessFn<T> = (span: Span, exception: Error | undefined, result: Awaited<T> | undefined) => void;
246
+ interface TSpanInput {
247
+ name: string;
248
+ options?: SpanOptions;
249
+ }
250
+ /**
251
+ * Starts or continues a span, executes the callback within the span's context,
252
+ * and handles span completion and error recording. Supports both synchronous and asynchronous callbacks.
253
+ * An optional post-processing callback can be used to enrich the span before it ends.
254
+ *
255
+ * @template T
256
+ * @param {TSpanInput | Span} span - The span input containing name and options, or an existing span.
257
+ * @param {() => T} cb - The callback function to execute within the span's context.
258
+ * @param {TPostSpanProcessFn<T>=} postProcess - An optional post-processing callback to enrich the span before it ends. **CAUTION: When used, you must end the span yourself `span.end()`.**
259
+ * @returns {T} The result of the callback function.
260
+ * @throws {Error} Will throw an error if the callback function throws.
261
+ */
262
+ declare function withSpan<T>(span: TSpanInput | Span, cb: () => T, postProcess?: TPostSpanProcessFn<T>): T;
263
+
264
+ export { MoostBatchSpanProcessor, MoostSimpleSpanProcessor, OtelIgnoreMeter, OtelIgnoreSpan, SpanInjector, type TOtelContext, type TOtelMate, type TPostSpanProcessFn, type TSpanInput, enableOtelForMoost, getOtelMate, shouldSpanBeIgnored, useOtelContext, useOtelPropagation, useSpan, useTrace, withSpan };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { trace, context, metrics } from '@opentelemetry/api';
1
+ import { trace, context, metrics, SpanKind } from '@opentelemetry/api';
2
2
  import { useAsyncEventContext as useAsyncEventContext$1, ContextInjector, useControllerContext, getConstructor as getConstructor$2, replaceContextInjector } from 'moost';
3
3
  import { randomUUID } from 'crypto';
4
4
  import { AsyncLocalStorage } from 'node:async_hooks';
@@ -115,6 +115,49 @@ function getMoostMetrics() {
115
115
  return moostMetrics;
116
116
  }
117
117
 
118
+ function withSpan(span, cb, postProcess) {
119
+ const _span = typeof span.name === 'string' && !span.spanContext
120
+ ? span
121
+ : trace
122
+ .getTracer('default')
123
+ .startSpan(span.name, span.options);
124
+ let result = undefined;
125
+ const finalizeSpan = (e, r) => {
126
+ if (e) {
127
+ _span.recordException(e);
128
+ }
129
+ if (postProcess) {
130
+ postProcess(_span, e, r);
131
+ }
132
+ else {
133
+ _span.end();
134
+ }
135
+ };
136
+ context.with(trace.setSpan(context.active(), _span), () => {
137
+ try {
138
+ result = cb();
139
+ }
140
+ catch (error) {
141
+ finalizeSpan(error, undefined);
142
+ throw error;
143
+ }
144
+ if (result instanceof Promise) {
145
+ result
146
+ .then(r => {
147
+ finalizeSpan(undefined, r);
148
+ return r;
149
+ })
150
+ .catch(error => {
151
+ finalizeSpan(error, undefined);
152
+ });
153
+ }
154
+ else {
155
+ finalizeSpan(undefined, result);
156
+ }
157
+ });
158
+ return result;
159
+ }
160
+
118
161
  const tracer = trace.getTracer('moost-tracer');
119
162
  class SpanInjector extends ContextInjector {
120
163
  constructor() {
@@ -133,10 +176,11 @@ class SpanInjector extends ContextInjector {
133
176
  }
134
177
  else {
135
178
  const span = tracer.startSpan(name, {
179
+ kind: SpanKind.INTERNAL,
136
180
  attributes: attrs,
137
181
  });
138
182
  return this.withSpan(span, fn, {
139
- rootSpan: false,
183
+ withMetrics: false,
140
184
  endSpan: true,
141
185
  });
142
186
  }
@@ -172,7 +216,7 @@ class SpanInjector extends ContextInjector {
172
216
  if (span) {
173
217
  registerSpan(span);
174
218
  return this.withSpan(span, cb, {
175
- rootSpan: true,
219
+ withMetrics: true,
176
220
  endSpan: eventType !== 'HTTP',
177
221
  });
178
222
  }
@@ -250,48 +294,20 @@ class SpanInjector extends ContextInjector {
250
294
  }
251
295
  }
252
296
  withSpan(span, cb, opts) {
253
- let result;
254
- let exception;
255
- const endSpan = (error) => {
256
- if (error) {
257
- span.recordException(error);
297
+ return withSpan(span, cb, (_span, exception, result) => {
298
+ if (result instanceof Error) {
299
+ _span.recordException(result);
258
300
  }
259
- if (opts.rootSpan) {
301
+ if (opts.withMetrics) {
260
302
  const chm = this.getControllerHandlerMeta();
261
303
  if (!chm.ignoreMeter) {
262
- this.endEventMetrics(chm.attrs, error);
304
+ this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
263
305
  }
264
306
  }
265
307
  if (opts.endSpan) {
266
- span.end();
267
- }
268
- };
269
- context.with(trace.setSpan(context.active(), span), () => {
270
- try {
271
- result = cb();
272
- }
273
- catch (error) {
274
- exception = error;
275
- endSpan(exception);
308
+ _span.end();
276
309
  }
277
310
  });
278
- const ret = result;
279
- if (!exception) {
280
- if (ret && ret instanceof Promise) {
281
- ret
282
- .then(r => {
283
- endSpan(r instanceof Error ? r : undefined);
284
- return r;
285
- })
286
- .catch(error => {
287
- endSpan(error);
288
- });
289
- }
290
- else {
291
- endSpan(ret instanceof Error ? ret : undefined);
292
- }
293
- }
294
- return ret;
295
311
  }
296
312
  startEventMetrics(a, route) {
297
313
  if (a['moost.event_type'] === 'HTTP') {
@@ -1206,4 +1222,4 @@ class MoostSimpleSpanProcessor extends SimpleSpanProcessor {
1206
1222
  }
1207
1223
  }
1208
1224
 
1209
- export { MoostBatchSpanProcessor, MoostSimpleSpanProcessor, OtelIgnoreMeter, OtelIgnoreSpan, SpanInjector, enableOtelForMoost, getOtelMate, shouldSpanBeIgnored, useOtelContext, useOtelPropagation, useSpan, useTrace };
1225
+ export { MoostBatchSpanProcessor, MoostSimpleSpanProcessor, OtelIgnoreMeter, OtelIgnoreSpan, SpanInjector, enableOtelForMoost, getOtelMate, shouldSpanBeIgnored, useOtelContext, useOtelPropagation, useSpan, useTrace, withSpan };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moostjs/otel",
3
- "version": "0.4.15",
3
+ "version": "0.4.16",
4
4
  "description": "@moostjs/otel",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -39,6 +39,6 @@
39
39
  "dependencies": {
40
40
  "@opentelemetry/api": "^1.9.0",
41
41
  "@opentelemetry/sdk-trace-base": "^1.25.1",
42
- "moost": "0.4.15"
42
+ "moost": "0.4.16"
43
43
  }
44
44
  }