@moostjs/otel 0.6.49 → 0.6.51
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 +91 -34
- package/dist/index.d.ts +4 -6
- package/dist/index.mjs +91 -34
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
3
3
|
let moost = require("moost");
|
|
4
|
+
let _opentelemetry_core = require("@opentelemetry/core");
|
|
4
5
|
let _moostjs_event_http = require("@moostjs/event-http");
|
|
6
|
+
let net = require("net");
|
|
5
7
|
let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
6
8
|
|
|
7
9
|
//#region packages/otel/src/context.ts
|
|
@@ -184,6 +186,56 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
184
186
|
}
|
|
185
187
|
return meta;
|
|
186
188
|
}
|
|
189
|
+
/** Root spans already owned by a Moost event — never attached to (renamed, re-attributed) twice. */ const claimedSpans = /* @__PURE__ */ new WeakSet();
|
|
190
|
+
const otelHostSpanKey = (0, moost.globalKey)("otel.hostSpan");
|
|
191
|
+
/**
|
|
192
|
+
* The server span of the http instrumentation (`@opentelemetry/instrumentation-http`) for this
|
|
193
|
+
* network request, when no Moost event owns it yet.
|
|
194
|
+
*
|
|
195
|
+
* The instrumentation publishes it as the request's RPC metadata, so it is found even when a host
|
|
196
|
+
* app's middleware span (Express instrumentation) is active, not the server span itself. Without
|
|
197
|
+
* RPC metadata only an active SERVER span qualifies — anything else active (a lifecycle span of a
|
|
198
|
+
* running event, a client span) is a parent, not the request's own span. An in-process request
|
|
199
|
+
* (`fetch()` / `request()` on the HTTP app) runs on a fake socket and never attaches: it is not
|
|
200
|
+
* the network request the server span stands for.
|
|
201
|
+
*/ function getHostServerSpan(req) {
|
|
202
|
+
if (!(req?.socket instanceof net.Socket)) return;
|
|
203
|
+
const rpc = (0, _opentelemetry_core.getRPCMetadata)(_opentelemetry_api.context.active());
|
|
204
|
+
if (rpc?.type === _opentelemetry_core.RPCType.HTTP && rpc.span) return claimedSpans.has(rpc.span) ? void 0 : {
|
|
205
|
+
span: rpc.span,
|
|
206
|
+
rpc,
|
|
207
|
+
mount: getMountRoute(req, rpc)
|
|
208
|
+
};
|
|
209
|
+
const active = _opentelemetry_api.trace.getActiveSpan();
|
|
210
|
+
return active?.kind === _opentelemetry_api.SpanKind.SERVER && !claimedSpans.has(active) ? {
|
|
211
|
+
span: active,
|
|
212
|
+
mount: ""
|
|
213
|
+
} : void 0;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* The route template a host app mounted Moost under, when it stripped that path from `req.url`
|
|
217
|
+
* (`app.use('/api', moostMiddleware)`): the route the host's own instrumentation reported
|
|
218
|
+
* for the request so far. Empty when Moost sees the whole path.
|
|
219
|
+
*/ function getMountRoute(req, rpc) {
|
|
220
|
+
const path = (url) => url?.split("?")[0];
|
|
221
|
+
if (!req.originalUrl || path(req.originalUrl) === path(req.url) || !rpc.route) return "";
|
|
222
|
+
return rpc.route.replace(/\/+$/, "");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* The controller context of the current event, or `undefined` while no handler is resolved yet
|
|
226
|
+
* (an unmatched route reports `Handler:not_found` before any controller context exists).
|
|
227
|
+
*/ function readControllerContext() {
|
|
228
|
+
const cc = (0, moost.useControllerContext)();
|
|
229
|
+
try {
|
|
230
|
+
return {
|
|
231
|
+
controller: cc.getController(),
|
|
232
|
+
method: cc.getMethod(),
|
|
233
|
+
route: cc.getRoute()
|
|
234
|
+
};
|
|
235
|
+
} catch {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
187
239
|
/** Context injector that wraps Moost lifecycle hooks with OpenTelemetry spans and records metrics. */ var SpanInjector = class extends moost.ContextInjector {
|
|
188
240
|
with(name, attributes, cb) {
|
|
189
241
|
const fn = typeof attributes === "function" ? attributes : cb;
|
|
@@ -206,45 +258,46 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
206
258
|
const res = this.getResponse();
|
|
207
259
|
if (res) {
|
|
208
260
|
const originalWriteHead = res.writeHead;
|
|
209
|
-
|
|
210
|
-
res._statusCode =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return originalWriteHead.apply(res, [
|
|
214
|
-
arg0,
|
|
215
|
-
arg1,
|
|
216
|
-
arg2
|
|
217
|
-
]);
|
|
218
|
-
} });
|
|
261
|
+
res.writeHead = (...args) => {
|
|
262
|
+
res._statusCode = args[0];
|
|
263
|
+
return originalWriteHead.apply(res, args);
|
|
264
|
+
};
|
|
219
265
|
}
|
|
220
266
|
}
|
|
221
267
|
startEvent(eventType, cb) {
|
|
222
268
|
if (eventType === "init") return cb();
|
|
223
269
|
const { registerSpan } = useOtelContext();
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
270
|
+
const isHttp = eventType === _moostjs_event_http.httpKind.name;
|
|
271
|
+
const req = isHttp ? this.getRequest() : void 0;
|
|
272
|
+
if (isHttp) this.patchRsponse();
|
|
273
|
+
const host = getHostServerSpan(req);
|
|
274
|
+
const active = _opentelemetry_api.trace.getActiveSpan();
|
|
275
|
+
const span = host?.span ?? tracer.startSpan(isHttp ? req?.method || "HTTP" : `${eventType} Event`, isHttp && !active ? { kind: _opentelemetry_api.SpanKind.SERVER } : void 0);
|
|
276
|
+
claimedSpans.add(span);
|
|
277
|
+
registerSpan(span);
|
|
278
|
+
if (host) (0, moost.current)().set(otelHostSpanKey, host);
|
|
279
|
+
const opts = {
|
|
280
|
+
withMetrics: true,
|
|
281
|
+
endSpan: !host
|
|
282
|
+
};
|
|
283
|
+
if (host && active && active !== host.span) {
|
|
284
|
+
const outer = _opentelemetry_api.context.active();
|
|
285
|
+
return this.withSpan(span, () => _opentelemetry_api.context.with(outer, cb), opts);
|
|
233
286
|
}
|
|
234
|
-
return cb
|
|
287
|
+
return this.withSpan(span, cb, opts);
|
|
235
288
|
}
|
|
236
289
|
getEventType() {
|
|
237
290
|
const ctx = (0, moost.current)();
|
|
238
291
|
return ctx.has(moost.eventTypeKey) ? ctx.get(moost.eventTypeKey) : void 0;
|
|
239
292
|
}
|
|
240
293
|
getIgnoreSpan() {
|
|
241
|
-
const
|
|
242
|
-
return readHandlerOtelMeta(
|
|
294
|
+
const cc = readControllerContext();
|
|
295
|
+
return readHandlerOtelMeta(cc?.controller, cc?.method).ignoreSpan;
|
|
243
296
|
}
|
|
244
297
|
getControllerHandlerMeta() {
|
|
245
|
-
const
|
|
246
|
-
const methodName =
|
|
247
|
-
const meta = readHandlerOtelMeta(
|
|
298
|
+
const cc = readControllerContext();
|
|
299
|
+
const methodName = cc?.method;
|
|
300
|
+
const meta = readHandlerOtelMeta(cc?.controller, methodName);
|
|
248
301
|
return {
|
|
249
302
|
ignoreMeter: meta.ignoreMeter,
|
|
250
303
|
ignoreSpan: meta.ignoreSpan,
|
|
@@ -255,7 +308,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
255
308
|
"moost.handler_label": meta.label,
|
|
256
309
|
"moost.handler_id": meta.id,
|
|
257
310
|
"moost.ignore": meta.ignoreSpan,
|
|
258
|
-
"moost.route":
|
|
311
|
+
"moost.route": cc?.route,
|
|
259
312
|
"moost.event_type": this.getEventType()
|
|
260
313
|
}
|
|
261
314
|
};
|
|
@@ -273,10 +326,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
273
326
|
const chm = this.getControllerHandlerMeta();
|
|
274
327
|
const span = getSpan();
|
|
275
328
|
if (span) {
|
|
276
|
-
if (this.getEventType() === _moostjs_event_http.httpKind.
|
|
277
|
-
const req = this.getRequest();
|
|
278
|
-
span.updateName(`${req?.method || ""} ${req?.url}`);
|
|
279
|
-
}
|
|
329
|
+
if (this.getEventType() === _moostjs_event_http.httpKind.name) span.updateName(this.getRequest()?.method || "HTTP");
|
|
280
330
|
}
|
|
281
331
|
this.startEventMetrics(chm.attrs, route);
|
|
282
332
|
} else if (name === "Controller:registered") {
|
|
@@ -286,8 +336,15 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
286
336
|
const span = getSpan();
|
|
287
337
|
if (span) {
|
|
288
338
|
span.setAttributes(chm.attrs);
|
|
289
|
-
if (chm.attrs["moost.event_type"] === _moostjs_event_http.httpKind.
|
|
290
|
-
|
|
339
|
+
if (chm.attrs["moost.event_type"] === _moostjs_event_http.httpKind.name) {
|
|
340
|
+
const host = ctx.has(otelHostSpanKey) ? ctx.get(otelHostSpanKey) : void 0;
|
|
341
|
+
const httpRoute = _route ? `${host?.mount || ""}${_route}` : void 0;
|
|
342
|
+
span.updateName(`${this.getRequest()?.method || ""} ${httpRoute || "<unresolved>"}`);
|
|
343
|
+
if (httpRoute) {
|
|
344
|
+
span.setAttribute("http.route", httpRoute);
|
|
345
|
+
if (host?.rpc) host.rpc.route = httpRoute;
|
|
346
|
+
}
|
|
347
|
+
} else span.updateName(`${chm.attrs["moost.event_type"]} ${_route || "<unresolved>"}`);
|
|
291
348
|
}
|
|
292
349
|
}
|
|
293
350
|
if (name !== "Controller:registered") ctx.set(otelRouteKey, route);
|
|
@@ -314,6 +371,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
314
371
|
const ctx = (0, moost.current)();
|
|
315
372
|
const route = ctx.has(otelRouteKey) ? ctx.get(otelRouteKey) : void 0;
|
|
316
373
|
const startTime = ctx.has(otelStartTimeKey) ? ctx.get(otelStartTimeKey) : void 0;
|
|
374
|
+
if (startTime === void 0 && route === void 0 && a["moost.event_type"] === _moostjs_event_http.httpKind.name) return;
|
|
317
375
|
const duration = Date.now() - (startTime || Date.now() - 1);
|
|
318
376
|
const attrs = {
|
|
319
377
|
...ctx.has(customMetricAttrsKey) ? ctx.get(customMetricAttrsKey) : {},
|
|
@@ -321,8 +379,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
321
379
|
"moost.event_type": a["moost.event_type"],
|
|
322
380
|
"moost.is_error": error ? 1 : 0
|
|
323
381
|
};
|
|
324
|
-
if (a["moost.event_type"] === _moostjs_event_http.httpKind.
|
|
325
|
-
if (!attrs.route) attrs.route = this.getRequest()?.url || "";
|
|
382
|
+
if (a["moost.event_type"] === _moostjs_event_http.httpKind.name) {
|
|
326
383
|
attrs["http.status_code"] = this.getResponse()?._statusCode || 0;
|
|
327
384
|
attrs["moost.is_error"] = attrs["moost.is_error"] || attrs["http.status_code"] > 399 ? 1 : 0;
|
|
328
385
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,7 @@ import * as moost from 'moost';
|
|
|
4
4
|
import { Mate, TMoostMetadata, TMateParamMeta, ContextInjector, TContextInjectorHook } from 'moost';
|
|
5
5
|
import { EventContext } from '@wooksjs/event-core';
|
|
6
6
|
import { BatchSpanProcessor, ReadableSpan, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
7
|
-
import
|
|
8
|
-
import { ServerResponse } from 'http';
|
|
7
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
9
8
|
|
|
10
9
|
/** Event context key storing the root OpenTelemetry span. */
|
|
11
10
|
declare const otelSpanKey: moost.Key<Span | undefined>;
|
|
@@ -135,7 +134,7 @@ declare class SpanInjector extends ContextInjector<TContextInjectorHook> {
|
|
|
135
134
|
'moost.handler_label': string | undefined;
|
|
136
135
|
'moost.handler_id': string | undefined;
|
|
137
136
|
'moost.ignore': boolean | undefined;
|
|
138
|
-
'moost.route': string;
|
|
137
|
+
'moost.route': string | undefined;
|
|
139
138
|
'moost.event_type': string | undefined;
|
|
140
139
|
};
|
|
141
140
|
};
|
|
@@ -146,10 +145,9 @@ declare class SpanInjector extends ContextInjector<TContextInjectorHook> {
|
|
|
146
145
|
}): T;
|
|
147
146
|
startEventMetrics(a: Record<string, string | number | boolean | undefined>, route?: string): void;
|
|
148
147
|
endEventMetrics(a: Record<string, string | number | boolean | undefined>, error?: Error): void;
|
|
149
|
-
getRequest():
|
|
150
|
-
getResponse(): (ServerResponse<
|
|
148
|
+
getRequest(): IncomingMessage | undefined;
|
|
149
|
+
getResponse(): (ServerResponse<IncomingMessage> & {
|
|
151
150
|
_statusCode?: number;
|
|
152
|
-
_contentLength?: number;
|
|
153
151
|
}) | undefined;
|
|
154
152
|
}
|
|
155
153
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SpanKind, SpanStatusCode, context, metrics, trace } from "@opentelemetry/api";
|
|
2
2
|
import { ContextInjector, current, eventTypeKey, getConstructor, getMoostMate, globalKey, replaceContextInjector, useControllerContext } from "moost";
|
|
3
|
+
import { RPCType, getRPCMetadata } from "@opentelemetry/core";
|
|
3
4
|
import { httpKind } from "@moostjs/event-http";
|
|
5
|
+
import { Socket } from "net";
|
|
4
6
|
import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
5
7
|
|
|
6
8
|
//#region packages/otel/src/context.ts
|
|
@@ -183,6 +185,56 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
183
185
|
}
|
|
184
186
|
return meta;
|
|
185
187
|
}
|
|
188
|
+
/** Root spans already owned by a Moost event — never attached to (renamed, re-attributed) twice. */ const claimedSpans = /* @__PURE__ */ new WeakSet();
|
|
189
|
+
const otelHostSpanKey = globalKey("otel.hostSpan");
|
|
190
|
+
/**
|
|
191
|
+
* The server span of the http instrumentation (`@opentelemetry/instrumentation-http`) for this
|
|
192
|
+
* network request, when no Moost event owns it yet.
|
|
193
|
+
*
|
|
194
|
+
* The instrumentation publishes it as the request's RPC metadata, so it is found even when a host
|
|
195
|
+
* app's middleware span (Express instrumentation) is active, not the server span itself. Without
|
|
196
|
+
* RPC metadata only an active SERVER span qualifies — anything else active (a lifecycle span of a
|
|
197
|
+
* running event, a client span) is a parent, not the request's own span. An in-process request
|
|
198
|
+
* (`fetch()` / `request()` on the HTTP app) runs on a fake socket and never attaches: it is not
|
|
199
|
+
* the network request the server span stands for.
|
|
200
|
+
*/ function getHostServerSpan(req) {
|
|
201
|
+
if (!(req?.socket instanceof Socket)) return;
|
|
202
|
+
const rpc = getRPCMetadata(context.active());
|
|
203
|
+
if (rpc?.type === RPCType.HTTP && rpc.span) return claimedSpans.has(rpc.span) ? void 0 : {
|
|
204
|
+
span: rpc.span,
|
|
205
|
+
rpc,
|
|
206
|
+
mount: getMountRoute(req, rpc)
|
|
207
|
+
};
|
|
208
|
+
const active = trace.getActiveSpan();
|
|
209
|
+
return active?.kind === SpanKind.SERVER && !claimedSpans.has(active) ? {
|
|
210
|
+
span: active,
|
|
211
|
+
mount: ""
|
|
212
|
+
} : void 0;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The route template a host app mounted Moost under, when it stripped that path from `req.url`
|
|
216
|
+
* (`app.use('/api', moostMiddleware)`): the route the host's own instrumentation reported
|
|
217
|
+
* for the request so far. Empty when Moost sees the whole path.
|
|
218
|
+
*/ function getMountRoute(req, rpc) {
|
|
219
|
+
const path = (url) => url?.split("?")[0];
|
|
220
|
+
if (!req.originalUrl || path(req.originalUrl) === path(req.url) || !rpc.route) return "";
|
|
221
|
+
return rpc.route.replace(/\/+$/, "");
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* The controller context of the current event, or `undefined` while no handler is resolved yet
|
|
225
|
+
* (an unmatched route reports `Handler:not_found` before any controller context exists).
|
|
226
|
+
*/ function readControllerContext() {
|
|
227
|
+
const cc = useControllerContext();
|
|
228
|
+
try {
|
|
229
|
+
return {
|
|
230
|
+
controller: cc.getController(),
|
|
231
|
+
method: cc.getMethod(),
|
|
232
|
+
route: cc.getRoute()
|
|
233
|
+
};
|
|
234
|
+
} catch {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
186
238
|
/** Context injector that wraps Moost lifecycle hooks with OpenTelemetry spans and records metrics. */ var SpanInjector = class extends ContextInjector {
|
|
187
239
|
with(name, attributes, cb) {
|
|
188
240
|
const fn = typeof attributes === "function" ? attributes : cb;
|
|
@@ -205,45 +257,46 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
205
257
|
const res = this.getResponse();
|
|
206
258
|
if (res) {
|
|
207
259
|
const originalWriteHead = res.writeHead;
|
|
208
|
-
|
|
209
|
-
res._statusCode =
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return originalWriteHead.apply(res, [
|
|
213
|
-
arg0,
|
|
214
|
-
arg1,
|
|
215
|
-
arg2
|
|
216
|
-
]);
|
|
217
|
-
} });
|
|
260
|
+
res.writeHead = (...args) => {
|
|
261
|
+
res._statusCode = args[0];
|
|
262
|
+
return originalWriteHead.apply(res, args);
|
|
263
|
+
};
|
|
218
264
|
}
|
|
219
265
|
}
|
|
220
266
|
startEvent(eventType, cb) {
|
|
221
267
|
if (eventType === "init") return cb();
|
|
222
268
|
const { registerSpan } = useOtelContext();
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
269
|
+
const isHttp = eventType === httpKind.name;
|
|
270
|
+
const req = isHttp ? this.getRequest() : void 0;
|
|
271
|
+
if (isHttp) this.patchRsponse();
|
|
272
|
+
const host = getHostServerSpan(req);
|
|
273
|
+
const active = trace.getActiveSpan();
|
|
274
|
+
const span = host?.span ?? tracer.startSpan(isHttp ? req?.method || "HTTP" : `${eventType} Event`, isHttp && !active ? { kind: SpanKind.SERVER } : void 0);
|
|
275
|
+
claimedSpans.add(span);
|
|
276
|
+
registerSpan(span);
|
|
277
|
+
if (host) current().set(otelHostSpanKey, host);
|
|
278
|
+
const opts = {
|
|
279
|
+
withMetrics: true,
|
|
280
|
+
endSpan: !host
|
|
281
|
+
};
|
|
282
|
+
if (host && active && active !== host.span) {
|
|
283
|
+
const outer = context.active();
|
|
284
|
+
return this.withSpan(span, () => context.with(outer, cb), opts);
|
|
232
285
|
}
|
|
233
|
-
return cb
|
|
286
|
+
return this.withSpan(span, cb, opts);
|
|
234
287
|
}
|
|
235
288
|
getEventType() {
|
|
236
289
|
const ctx = current();
|
|
237
290
|
return ctx.has(eventTypeKey) ? ctx.get(eventTypeKey) : void 0;
|
|
238
291
|
}
|
|
239
292
|
getIgnoreSpan() {
|
|
240
|
-
const
|
|
241
|
-
return readHandlerOtelMeta(
|
|
293
|
+
const cc = readControllerContext();
|
|
294
|
+
return readHandlerOtelMeta(cc?.controller, cc?.method).ignoreSpan;
|
|
242
295
|
}
|
|
243
296
|
getControllerHandlerMeta() {
|
|
244
|
-
const
|
|
245
|
-
const methodName =
|
|
246
|
-
const meta = readHandlerOtelMeta(
|
|
297
|
+
const cc = readControllerContext();
|
|
298
|
+
const methodName = cc?.method;
|
|
299
|
+
const meta = readHandlerOtelMeta(cc?.controller, methodName);
|
|
247
300
|
return {
|
|
248
301
|
ignoreMeter: meta.ignoreMeter,
|
|
249
302
|
ignoreSpan: meta.ignoreSpan,
|
|
@@ -254,7 +307,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
254
307
|
"moost.handler_label": meta.label,
|
|
255
308
|
"moost.handler_id": meta.id,
|
|
256
309
|
"moost.ignore": meta.ignoreSpan,
|
|
257
|
-
"moost.route":
|
|
310
|
+
"moost.route": cc?.route,
|
|
258
311
|
"moost.event_type": this.getEventType()
|
|
259
312
|
}
|
|
260
313
|
};
|
|
@@ -272,10 +325,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
272
325
|
const chm = this.getControllerHandlerMeta();
|
|
273
326
|
const span = getSpan();
|
|
274
327
|
if (span) {
|
|
275
|
-
if (this.getEventType() === httpKind.
|
|
276
|
-
const req = this.getRequest();
|
|
277
|
-
span.updateName(`${req?.method || ""} ${req?.url}`);
|
|
278
|
-
}
|
|
328
|
+
if (this.getEventType() === httpKind.name) span.updateName(this.getRequest()?.method || "HTTP");
|
|
279
329
|
}
|
|
280
330
|
this.startEventMetrics(chm.attrs, route);
|
|
281
331
|
} else if (name === "Controller:registered") {
|
|
@@ -285,8 +335,15 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
285
335
|
const span = getSpan();
|
|
286
336
|
if (span) {
|
|
287
337
|
span.setAttributes(chm.attrs);
|
|
288
|
-
if (chm.attrs["moost.event_type"] === httpKind.
|
|
289
|
-
|
|
338
|
+
if (chm.attrs["moost.event_type"] === httpKind.name) {
|
|
339
|
+
const host = ctx.has(otelHostSpanKey) ? ctx.get(otelHostSpanKey) : void 0;
|
|
340
|
+
const httpRoute = _route ? `${host?.mount || ""}${_route}` : void 0;
|
|
341
|
+
span.updateName(`${this.getRequest()?.method || ""} ${httpRoute || "<unresolved>"}`);
|
|
342
|
+
if (httpRoute) {
|
|
343
|
+
span.setAttribute("http.route", httpRoute);
|
|
344
|
+
if (host?.rpc) host.rpc.route = httpRoute;
|
|
345
|
+
}
|
|
346
|
+
} else span.updateName(`${chm.attrs["moost.event_type"]} ${_route || "<unresolved>"}`);
|
|
290
347
|
}
|
|
291
348
|
}
|
|
292
349
|
if (name !== "Controller:registered") ctx.set(otelRouteKey, route);
|
|
@@ -313,6 +370,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
313
370
|
const ctx = current();
|
|
314
371
|
const route = ctx.has(otelRouteKey) ? ctx.get(otelRouteKey) : void 0;
|
|
315
372
|
const startTime = ctx.has(otelStartTimeKey) ? ctx.get(otelStartTimeKey) : void 0;
|
|
373
|
+
if (startTime === void 0 && route === void 0 && a["moost.event_type"] === httpKind.name) return;
|
|
316
374
|
const duration = Date.now() - (startTime || Date.now() - 1);
|
|
317
375
|
const attrs = {
|
|
318
376
|
...ctx.has(customMetricAttrsKey) ? ctx.get(customMetricAttrsKey) : {},
|
|
@@ -320,8 +378,7 @@ function readHandlerOtelMeta(controller, method) {
|
|
|
320
378
|
"moost.event_type": a["moost.event_type"],
|
|
321
379
|
"moost.is_error": error ? 1 : 0
|
|
322
380
|
};
|
|
323
|
-
if (a["moost.event_type"] === httpKind.
|
|
324
|
-
if (!attrs.route) attrs.route = this.getRequest()?.url || "";
|
|
381
|
+
if (a["moost.event_type"] === httpKind.name) {
|
|
325
382
|
attrs["http.status_code"] = this.getResponse()?._statusCode || 0;
|
|
326
383
|
attrs["moost.is_error"] = attrs["moost.is_error"] || attrs["http.status_code"] > 399 ? 1 : 0;
|
|
327
384
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moostjs/otel",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.51",
|
|
4
4
|
"description": "@moostjs/otel",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -39,15 +39,16 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@opentelemetry/api": "^1.9.1",
|
|
42
|
+
"@opentelemetry/core": "^2.10.0",
|
|
42
43
|
"@opentelemetry/sdk-trace-base": "^2.10.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"vitest": "3.2.7"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"@wooksjs/event-core": "^0.7.
|
|
49
|
-
"@moostjs/event-http": "^0.6.
|
|
50
|
-
"moost": "^0.6.
|
|
49
|
+
"@wooksjs/event-core": "^0.7.29",
|
|
50
|
+
"@moostjs/event-http": "^0.6.51",
|
|
51
|
+
"moost": "^0.6.51"
|
|
51
52
|
},
|
|
52
53
|
"scripts": {
|
|
53
54
|
"pub": "pnpm publish --access public",
|