@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 +53 -36
- package/dist/index.d.ts +21 -2
- package/dist/index.mjs +54 -38
- package/package.json +2 -2
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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.
|
|
303
|
+
if (opts.withMetrics) {
|
|
262
304
|
const chm = this.getControllerHandlerMeta();
|
|
263
305
|
if (!chm.ignoreMeter) {
|
|
264
|
-
this.endEventMetrics(chm.attrs,
|
|
306
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
265
307
|
}
|
|
266
308
|
}
|
|
267
309
|
if (opts.endSpan) {
|
|
268
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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.
|
|
301
|
+
if (opts.withMetrics) {
|
|
260
302
|
const chm = this.getControllerHandlerMeta();
|
|
261
303
|
if (!chm.ignoreMeter) {
|
|
262
|
-
this.endEventMetrics(chm.attrs,
|
|
304
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
263
305
|
}
|
|
264
306
|
}
|
|
265
307
|
if (opts.endSpan) {
|
|
266
|
-
|
|
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.
|
|
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.
|
|
42
|
+
"moost": "0.4.16"
|
|
43
43
|
}
|
|
44
44
|
}
|