@moostjs/otel 0.4.15 → 0.4.17
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 +57 -36
- package/dist/index.d.ts +21 -2
- package/dist/index.mjs +58 -38
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -117,6 +117,53 @@ 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
|
+
_span.setStatus({
|
|
131
|
+
code: api.SpanStatusCode.ERROR,
|
|
132
|
+
message: e.message || 'Unknown Error',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (postProcess) {
|
|
136
|
+
postProcess(_span, e, r);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
_span.end();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
api.context.with(api.trace.setSpan(api.context.active(), _span), () => {
|
|
143
|
+
try {
|
|
144
|
+
result = cb();
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
finalizeSpan(error, undefined);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
if (result instanceof Promise) {
|
|
151
|
+
result
|
|
152
|
+
.then(r => {
|
|
153
|
+
finalizeSpan(undefined, r);
|
|
154
|
+
return r;
|
|
155
|
+
})
|
|
156
|
+
.catch(error => {
|
|
157
|
+
finalizeSpan(error, undefined);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
finalizeSpan(undefined, result);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
120
167
|
const tracer = api.trace.getTracer('moost-tracer');
|
|
121
168
|
class SpanInjector extends moost.ContextInjector {
|
|
122
169
|
constructor() {
|
|
@@ -135,10 +182,11 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
135
182
|
}
|
|
136
183
|
else {
|
|
137
184
|
const span = tracer.startSpan(name, {
|
|
185
|
+
kind: api.SpanKind.INTERNAL,
|
|
138
186
|
attributes: attrs,
|
|
139
187
|
});
|
|
140
188
|
return this.withSpan(span, fn, {
|
|
141
|
-
|
|
189
|
+
withMetrics: false,
|
|
142
190
|
endSpan: true,
|
|
143
191
|
});
|
|
144
192
|
}
|
|
@@ -174,7 +222,7 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
174
222
|
if (span) {
|
|
175
223
|
registerSpan(span);
|
|
176
224
|
return this.withSpan(span, cb, {
|
|
177
|
-
|
|
225
|
+
withMetrics: true,
|
|
178
226
|
endSpan: eventType !== 'HTTP',
|
|
179
227
|
});
|
|
180
228
|
}
|
|
@@ -252,48 +300,20 @@ class SpanInjector extends moost.ContextInjector {
|
|
|
252
300
|
}
|
|
253
301
|
}
|
|
254
302
|
withSpan(span, cb, opts) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (error) {
|
|
259
|
-
span.recordException(error);
|
|
303
|
+
return withSpan(span, cb, (_span, exception, result) => {
|
|
304
|
+
if (result instanceof Error) {
|
|
305
|
+
_span.recordException(result);
|
|
260
306
|
}
|
|
261
|
-
if (opts.
|
|
307
|
+
if (opts.withMetrics) {
|
|
262
308
|
const chm = this.getControllerHandlerMeta();
|
|
263
309
|
if (!chm.ignoreMeter) {
|
|
264
|
-
this.endEventMetrics(chm.attrs,
|
|
310
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
265
311
|
}
|
|
266
312
|
}
|
|
267
313
|
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);
|
|
314
|
+
_span.end();
|
|
278
315
|
}
|
|
279
316
|
});
|
|
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
317
|
}
|
|
298
318
|
startEventMetrics(a, route) {
|
|
299
319
|
if (a['moost.event_type'] === 'HTTP') {
|
|
@@ -1220,3 +1240,4 @@ exports.useOtelContext = useOtelContext;
|
|
|
1220
1240
|
exports.useOtelPropagation = useOtelPropagation;
|
|
1221
1241
|
exports.useSpan = useSpan;
|
|
1222
1242
|
exports.useTrace = useTrace;
|
|
1243
|
+
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, SpanStatusCode, 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,53 @@ 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
|
+
_span.setStatus({
|
|
129
|
+
code: SpanStatusCode.ERROR,
|
|
130
|
+
message: e.message || 'Unknown Error',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (postProcess) {
|
|
134
|
+
postProcess(_span, e, r);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
_span.end();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
context.with(trace.setSpan(context.active(), _span), () => {
|
|
141
|
+
try {
|
|
142
|
+
result = cb();
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
finalizeSpan(error, undefined);
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
if (result instanceof Promise) {
|
|
149
|
+
result
|
|
150
|
+
.then(r => {
|
|
151
|
+
finalizeSpan(undefined, r);
|
|
152
|
+
return r;
|
|
153
|
+
})
|
|
154
|
+
.catch(error => {
|
|
155
|
+
finalizeSpan(error, undefined);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
finalizeSpan(undefined, result);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
|
|
118
165
|
const tracer = trace.getTracer('moost-tracer');
|
|
119
166
|
class SpanInjector extends ContextInjector {
|
|
120
167
|
constructor() {
|
|
@@ -133,10 +180,11 @@ class SpanInjector extends ContextInjector {
|
|
|
133
180
|
}
|
|
134
181
|
else {
|
|
135
182
|
const span = tracer.startSpan(name, {
|
|
183
|
+
kind: SpanKind.INTERNAL,
|
|
136
184
|
attributes: attrs,
|
|
137
185
|
});
|
|
138
186
|
return this.withSpan(span, fn, {
|
|
139
|
-
|
|
187
|
+
withMetrics: false,
|
|
140
188
|
endSpan: true,
|
|
141
189
|
});
|
|
142
190
|
}
|
|
@@ -172,7 +220,7 @@ class SpanInjector extends ContextInjector {
|
|
|
172
220
|
if (span) {
|
|
173
221
|
registerSpan(span);
|
|
174
222
|
return this.withSpan(span, cb, {
|
|
175
|
-
|
|
223
|
+
withMetrics: true,
|
|
176
224
|
endSpan: eventType !== 'HTTP',
|
|
177
225
|
});
|
|
178
226
|
}
|
|
@@ -250,48 +298,20 @@ class SpanInjector extends ContextInjector {
|
|
|
250
298
|
}
|
|
251
299
|
}
|
|
252
300
|
withSpan(span, cb, opts) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (error) {
|
|
257
|
-
span.recordException(error);
|
|
301
|
+
return withSpan(span, cb, (_span, exception, result) => {
|
|
302
|
+
if (result instanceof Error) {
|
|
303
|
+
_span.recordException(result);
|
|
258
304
|
}
|
|
259
|
-
if (opts.
|
|
305
|
+
if (opts.withMetrics) {
|
|
260
306
|
const chm = this.getControllerHandlerMeta();
|
|
261
307
|
if (!chm.ignoreMeter) {
|
|
262
|
-
this.endEventMetrics(chm.attrs,
|
|
308
|
+
this.endEventMetrics(chm.attrs, result instanceof Error ? result : exception);
|
|
263
309
|
}
|
|
264
310
|
}
|
|
265
311
|
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);
|
|
312
|
+
_span.end();
|
|
276
313
|
}
|
|
277
314
|
});
|
|
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
315
|
}
|
|
296
316
|
startEventMetrics(a, route) {
|
|
297
317
|
if (a['moost.event_type'] === 'HTTP') {
|
|
@@ -1206,4 +1226,4 @@ class MoostSimpleSpanProcessor extends SimpleSpanProcessor {
|
|
|
1206
1226
|
}
|
|
1207
1227
|
}
|
|
1208
1228
|
|
|
1209
|
-
export { MoostBatchSpanProcessor, MoostSimpleSpanProcessor, OtelIgnoreMeter, OtelIgnoreSpan, SpanInjector, enableOtelForMoost, getOtelMate, shouldSpanBeIgnored, useOtelContext, useOtelPropagation, useSpan, useTrace };
|
|
1229
|
+
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.17",
|
|
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.17"
|
|
43
43
|
}
|
|
44
44
|
}
|