@moostjs/otel 0.4.14 → 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 +62 -37
- package/dist/index.d.ts +21 -2
- package/dist/index.mjs +63 -39
- 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
|
}
|
|
@@ -217,8 +261,17 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
217
261
|
if (method === '__SYSTEM__') {
|
|
218
262
|
return;
|
|
219
263
|
}
|
|
264
|
+
const { getSpan } = useOtelContext();
|
|
220
265
|
if (name === 'Handler:not_found') {
|
|
221
266
|
const chm = this.getControllerHandlerMeta();
|
|
267
|
+
const span = getSpan();
|
|
268
|
+
if (span) {
|
|
269
|
+
const eventType = this.getEventType();
|
|
270
|
+
if (eventType === 'HTTP') {
|
|
271
|
+
const req = this.getRequest();
|
|
272
|
+
span.updateName(`${req?.method || ''} ${req?.url}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
222
275
|
this.startEventMetrics(chm.attrs, route);
|
|
223
276
|
}
|
|
224
277
|
else if (name === 'Controller:registered') {
|
|
@@ -227,7 +280,6 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
227
280
|
if (!chm.ignoreMeter) {
|
|
228
281
|
this.startEventMetrics(chm.attrs, _route);
|
|
229
282
|
}
|
|
230
|
-
const { getSpan } = useOtelContext();
|
|
231
283
|
const span = getSpan();
|
|
232
284
|
if (span) {
|
|
233
285
|
span.setAttributes(chm.attrs);
|
|
@@ -244,48 +296,20 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
244
296
|
}
|
|
245
297
|
}
|
|
246
298
|
withSpan(span, cb, opts) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (error) {
|
|
251
|
-
span.recordException(error);
|
|
299
|
+
return withSpan(span, cb, (_span, exception, result) => {
|
|
300
|
+
if (result instanceof Error) {
|
|
301
|
+
_span.recordException(result);
|
|
252
302
|
}
|
|
253
|
-
if (opts.
|
|
303
|
+
if (opts.withMetrics) {
|
|
254
304
|
const chm = this.getControllerHandlerMeta();
|
|
255
305
|
if (!chm.ignoreMeter) {
|
|
256
|
-
this.endEventMetrics(chm.attrs,
|
|
306
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
257
307
|
}
|
|
258
308
|
}
|
|
259
309
|
if (opts.endSpan) {
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
api.context.with(api.trace.setSpan(api.context.active(), span), () => {
|
|
264
|
-
try {
|
|
265
|
-
result = cb();
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
exception = error;
|
|
269
|
-
endSpan(exception);
|
|
310
|
+
_span.end();
|
|
270
311
|
}
|
|
271
312
|
});
|
|
272
|
-
const ret = result;
|
|
273
|
-
if (!exception) {
|
|
274
|
-
if (ret && ret instanceof Promise) {
|
|
275
|
-
ret
|
|
276
|
-
.then(r => {
|
|
277
|
-
endSpan(r instanceof Error ? r : undefined);
|
|
278
|
-
return r;
|
|
279
|
-
})
|
|
280
|
-
.catch(error => {
|
|
281
|
-
endSpan(error);
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
endSpan(ret instanceof Error ? ret : undefined);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return ret;
|
|
289
313
|
}
|
|
290
314
|
startEventMetrics(a, route) {
|
|
291
315
|
if (a['moost.event_type'] === 'HTTP') {
|
|
@@ -1212,3 +1236,4 @@ exports.useOtelContext = useOtelContext;
|
|
|
1212
1236
|
exports.useOtelPropagation = useOtelPropagation;
|
|
1213
1237
|
exports.useSpan = useSpan;
|
|
1214
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
|
}
|
|
@@ -215,8 +259,17 @@ class SpanInjector extends ContextInjector {
|
|
|
215
259
|
if (method === '__SYSTEM__') {
|
|
216
260
|
return;
|
|
217
261
|
}
|
|
262
|
+
const { getSpan } = useOtelContext();
|
|
218
263
|
if (name === 'Handler:not_found') {
|
|
219
264
|
const chm = this.getControllerHandlerMeta();
|
|
265
|
+
const span = getSpan();
|
|
266
|
+
if (span) {
|
|
267
|
+
const eventType = this.getEventType();
|
|
268
|
+
if (eventType === 'HTTP') {
|
|
269
|
+
const req = this.getRequest();
|
|
270
|
+
span.updateName(`${req?.method || ''} ${req?.url}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
220
273
|
this.startEventMetrics(chm.attrs, route);
|
|
221
274
|
}
|
|
222
275
|
else if (name === 'Controller:registered') {
|
|
@@ -225,7 +278,6 @@ class SpanInjector extends ContextInjector {
|
|
|
225
278
|
if (!chm.ignoreMeter) {
|
|
226
279
|
this.startEventMetrics(chm.attrs, _route);
|
|
227
280
|
}
|
|
228
|
-
const { getSpan } = useOtelContext();
|
|
229
281
|
const span = getSpan();
|
|
230
282
|
if (span) {
|
|
231
283
|
span.setAttributes(chm.attrs);
|
|
@@ -242,48 +294,20 @@ class SpanInjector extends ContextInjector {
|
|
|
242
294
|
}
|
|
243
295
|
}
|
|
244
296
|
withSpan(span, cb, opts) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (error) {
|
|
249
|
-
span.recordException(error);
|
|
297
|
+
return withSpan(span, cb, (_span, exception, result) => {
|
|
298
|
+
if (result instanceof Error) {
|
|
299
|
+
_span.recordException(result);
|
|
250
300
|
}
|
|
251
|
-
if (opts.
|
|
301
|
+
if (opts.withMetrics) {
|
|
252
302
|
const chm = this.getControllerHandlerMeta();
|
|
253
303
|
if (!chm.ignoreMeter) {
|
|
254
|
-
this.endEventMetrics(chm.attrs,
|
|
304
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
255
305
|
}
|
|
256
306
|
}
|
|
257
307
|
if (opts.endSpan) {
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
context.with(trace.setSpan(context.active(), span), () => {
|
|
262
|
-
try {
|
|
263
|
-
result = cb();
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
exception = error;
|
|
267
|
-
endSpan(exception);
|
|
308
|
+
_span.end();
|
|
268
309
|
}
|
|
269
310
|
});
|
|
270
|
-
const ret = result;
|
|
271
|
-
if (!exception) {
|
|
272
|
-
if (ret && ret instanceof Promise) {
|
|
273
|
-
ret
|
|
274
|
-
.then(r => {
|
|
275
|
-
endSpan(r instanceof Error ? r : undefined);
|
|
276
|
-
return r;
|
|
277
|
-
})
|
|
278
|
-
.catch(error => {
|
|
279
|
-
endSpan(error);
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
endSpan(ret instanceof Error ? ret : undefined);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return ret;
|
|
287
311
|
}
|
|
288
312
|
startEventMetrics(a, route) {
|
|
289
313
|
if (a['moost.event_type'] === 'HTTP') {
|
|
@@ -1198,4 +1222,4 @@ class MoostSimpleSpanProcessor extends SimpleSpanProcessor {
|
|
|
1198
1222
|
}
|
|
1199
1223
|
}
|
|
1200
1224
|
|
|
1201
|
-
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
|
}
|