@lensmcp/nest-instrumentation 1.25.23 → 1.25.25
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/lib/instrument.js +1 -1
- package/lib/state.js +1 -1
- package/lib/trace-interceptor.js +2 -2
- package/package.json +4 -4
package/lib/instrument.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Q=Object.defineProperty;var m=(e,r)=>Q(e,"name",{value:r,configurable:!0});var V=Object.defineProperty,l=m((e,r)=>V(e,"name",{value:r,configurable:!0}),"i");import{fingerprint as b,ulid as w}from"@lensmcp/core";import{redactText as O}from"@lensmcp/core/redact";import{captureFor as z,capturedValue as R}from"./capture.js";import{currentLensmcpContext as H,currentSpanId as J,LENSMCP_SPAN_STORAGE as X}from"./context.js";import{activeOptions as K}from"./state.js";import{performance as T}from"node:perf_hooks";export const LENSMCP_TRACED=Symbol.for("@lensmcp/nest-instrumentation/traced"),LENSMCP_IGNORE=Symbol.for("@lensmcp/nest-instrumentation/ignore");const h=300;function A(e){if(e instanceof Error){const d=e.code,p=O(e.message??"");return{name:e.name||e.constructor?.name||"Error",...p?{message:p.length>h?`${p.slice(0,h)}\u2026`:p}:{},...typeof d=="string"&&d.length<=64?{code:d}:{}}}const r=typeof e=="string"?O(e):void 0;return{name:e==null?"nothing":typeof e=="object"?"non-Error object":`non-Error ${typeof e}`,...r?{message:r.slice(0,h)}:{}}}m(A,"J"),l(A,"thrownOf");export function LensmcpIgnore(){return((e,r)=>{if(r===void 0)e[LENSMCP_IGNORE]=!0;else{const d=e[r];typeof d=="function"&&(d[LENSMCP_IGNORE]=!0)}})}m(LensmcpIgnore,"LensmcpIgnore"),l(LensmcpIgnore,"LensmcpIgnore");export function isTraced(e){return typeof e=="function"&&!!e[LENSMCP_TRACED]}m(isTraced,"isTraced"),l(isTraced,"isTraced");export function isIgnored(e){return!!e&&(typeof e=="function"||typeof e=="object")&&!!e[LENSMCP_IGNORE]}m(isIgnored,"isIgnored"),l(isIgnored,"isIgnored");export function traceWrap(e,r,d={}){if(isTraced(e))return e;const p=d.db??!1,x=l(function(...I){let a;try{a=K()}catch{return e.apply(this,I)}if(!a.trace.services)return e.apply(this,I);const c=Date.now();let D=c,E=0;const t=H(),g=w(),v=J(),P=t?.dbCallCount??0,N=t?.redisCallCount??0,_=t?.externalCallCount??0,B=t?.loopDbCalls??0,G=t?.loopRedisCalls??0,W=t?.loopExternalCalls??0,f=d.capture??z(r),q=f==="args"||f==="both"?R(I):void 0,M=l((n,o,C)=>{const s=Date.now()-c,i={id:w(),sessionId:a.sessionId,timestamp:Date.now(),source:"nestjs",category:"backend",severity:n==="error"?"error":"info",context:{sessionId:a.sessionId,flowId:t?.flowId,requestId:t?.requestId,...t?.runId?{runId:t.runId}:{}},fingerprint:b({kind:"method-call",identity:r}),title:`${r} (${s}ms)${n==="error"?" \u2717":""}`,message:o instanceof Error?o.message:void 0,raw:{kind:"span",span:{name:r,spanId:g,...v?{parentSpanId:v}:{},flowId:t?.flowId,requestId:t?.requestId,startTime:c,endTime:Date.now(),durationMs:s,syncStartedAt:D,syncDurationMs:E,status:n,outcome:n==="error"?"threw":"returned",...n==="error"?{error:A(o)}:{},...q!==void 0?{args:q}:{},...n==="ok"&&(f==="result"||f==="both")?{result:R(C)}:{}}}};a.emit(i)},"emitSpan"),S=l(()=>{t&&(t.dbCallCount=(t.dbCallCount??0)+1);const n=Date.now();a.emit({id:w(),sessionId:a.sessionId,timestamp:Date.now(),source:"db",category:"db",severity:"info",context:{sessionId:a.sessionId,flowId:t?.flowId,requestId:t?.requestId,...t?.runId?{runId:t.runId}:{}},fingerprint:b({kind:"db-query",identity:r}),title:`query ${r}`,raw:{kind:"db-query",query:{signature:r},startedAt:c,durationMs:n-c,span:{parentSpanId:g}}})},"emitDbQuery"),k=l(()=>{if(p||!t)return;const n=(t.dbCallCount??0)-P,o=(t.redisCallCount??0)-N,C=(t.externalCallCount??0)-_,s=Math.max(0,n-((t.loopDbCalls??0)-B)),i=Math.max(0,o-((t.loopRedisCalls??0)-G)),u=Math.max(0,C-((t.loopExternalCalls??0)-W));if(s<3&&i<3&&u<3)return;const F=Date.now()-c,y=[];s>=3&&y.push(`${s} DB calls`),i>=3&&y.push(`${i} redis calls`),u>=3&&y.push(`${u} external calls`),s>=3&&(t.loopDbCalls=(t.loopDbCalls??0)+s),i>=3&&(t.loopRedisCalls=(t.loopRedisCalls??0)+i),u>=3&&(t.loopExternalCalls=(t.loopExternalCalls??0)+u);const j=n-s+(o-i)+(C-u);a.emit({id:w(),sessionId:a.sessionId,timestamp:Date.now(),source:"nestjs",category:"backend",severity:"warning",context:{sessionId:a.sessionId,flowId:t.flowId,requestId:t.requestId,...t.runId?{runId:t.runId}:{}},fingerprint:b({kind:"loop",identity:r}),title:`loop in ${r} (${y.join(", ")})`,raw:{kind:"loop",loop:{iterations:Math.max(s,i,u),durationMs:F,startedAt:c,dbCallsInsideLoop:s,redisCallsInsideLoop:i,externalCallsInsideLoop:u,awaitedOperationsInsideLoop:s+i+u,...j>0?{reportedBeneath:j}:{}}}})},"emitLoopIfNeeded"),L=l(n=>{p&&S(),M("ok",void 0,n),k()},"onOk"),$=l(n=>{p&&S(),M("error",n),k()},"onErr");try{const n=X.run(g,()=>{D=Date.now();const o=T.now();try{return e.apply(this,I)}finally{E=Math.round((T.now()-o)*100)/100}});return n instanceof Promise?n.then(o=>(L(o),o),o=>{throw $(o),o}):(L(n),n)}catch(n){throw $(n),n}},"wrapped");return x[LENSMCP_TRACED]=!0,x}m(traceWrap,"traceWrap"),l(traceWrap,"traceWrap");
|
package/lib/state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var r=(e,t)=>u(e,"name",{value:t,configurable:!0});var d=Object.defineProperty,o=r((e,t)=>d(e,"name",{value:t,configurable:!0}),"r");import{ulid as m}from"@lensmcp/core";import{defaultEventSink as p}from"./event-sink.js";import{performance as f}from"node:perf_hooks";import{threadId as l}from"node:worker_threads";let s,a=0;export function setActiveOptions(e){const t=e.emit??p(),c=`node:${process.pid}:${l}:${f.timeOrigin}`,n={projectName:e.projectName,sessionId:e.sessionId??process.env.LENSMCP_SESSION_ID??m(),emit:o(i=>t({...i,raw:{...i.raw,loopId:c}}),"emit"),trace:{requests:e.trace?.requests??!0,guards:e.trace?.guards??!0,controllers:e.trace?.controllers??!0,services:e.trace?.services??!0,db:e.trace?.db??!1,redis:e.trace?.redis??!1,queues:e.trace?.queues??!1,autoInstrumentMethods:e.trace?.autoInstrumentMethods??!1,suppressNoiseMethods:e.trace?.suppressNoiseMethods??!0},memory:{mode:e.memory?.mode??"off",scope:e.memory?.scope??"tagged"}};return s=n,a+=1,n}r(setActiveOptions,"setActiveOptions"),o(setActiveOptions,"setActiveOptions");export function activeOptions(){if(!s)throw new Error("@lensmcp/nest-instrumentation: LensmcpModule.forRoot(...) has not been registered. Did you forget to add it to your AppModule?");return s}r(activeOptions,"activeOptions"),o(activeOptions,"activeOptions");export function currentGeneration(){return a}r(currentGeneration,"currentGeneration"),o(currentGeneration,"currentGeneration");
|
package/lib/trace-interceptor.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Y=Object.defineProperty;var u=(t,e)=>Y(t,"name",{value:e,configurable:!0});var ee=Object.defineProperty,a=u((t,e)=>ee(t,"name",{value:e,configurable:!0}),"d");import{__decorate as te}from"tslib";import{Injectable as re}from"@nestjs/common";import{Observable as U}from"rxjs";import{catchError as se,tap as oe}from"rxjs/operators";import{fingerprint as $,headlessFlowId as ne,headlessFlowsEnabled as ae,isProbePath as ie,requestFacts as de,responseFacts as ue,shapeOf as z,ulid as y}from"@lensmcp/core";import{activeMemoryOptions as ce,onFlowStart as fe,onFlowSettled as le}from"@lensmcp/memory-tracker";import{LENSMCP_CONTEXT_STORAGE as pe}from"./context.js";import{attachContextEnd as me}from"./context-end.js";import{activeOptions as q}from"./state.js";const Ie=Symbol.for("lensmcp.exchangeId");let T=class{static{u(this,"S")}static{a(this,"TraceInterceptor")}intercept(t,e){const o=q();if(!o.trace.requests)return e.handle();const d=t.switchToHttp(),r=d.getRequest(),s=d.getResponse(),n=h(r.headers?.["x-request-id"])??y(),c=h(r.headers?.["x-lensmcp-flow-id"]),f=h(r.headers?.["x-internal-token"])!==void 0,I=c??(!f&&ae()&&!ie(r.url)?ne(n):void 0),i={sessionId:o.sessionId,requestId:n,parentRequestId:h(r.headers?.["x-lensmcp-parent-request-id"]),flowId:I,originNodeId:h(r.headers?.["x-lensmcp-origin-node-id"]),traceparent:h(r.headers?.traceparent),runId:y(),dbCallCount:0},m=r[Ie],l=(r.method??"GET").toUpperCase(),p=r.route?.path??r.url??"<unknown>",O=t.getClass?.()?.name,D=t.getHandler?.()?.name,v=Date.now();I&&!c&&K(i,l,p,v);const M=o.memory.mode!=="off";M&&fe(n);const P=a(()=>{if(!M)return;const g=ce()?.settleMs??1e3;setTimeout(()=>le(n,i.flowId),g).unref?.()},"settleAndCheck"),V=me(i);let E;typeof s?.once=="function"&&we()&&s.once("finish",()=>X(o.projectName,i,l,p,r,s,E));let A=!1,j=typeof s?.once!="function";const H=a(()=>{A&&j&&V()},"endIfOver");if(!j){const g=a(()=>{j=!0,H()},"responseOut");s.once?.("finish",g),s.once?.("close",g)}return new U(g=>{let F;return pe.run(i,()=>{F=e.handle().pipe(oe({next:a(w=>{E??={value:w},g.next(w)},"next"),complete:a(()=>{x(o.projectName,i,l,p,s.statusCode??200,v,void 0,m,k(s)),N(i,O,D,v,"ok"),P(),g.complete()},"complete")}),se(w=>{const _=w?.getResponse?.();_!==void 0&&(E??={value:_});const B=R(w);if(B!==void 0||typeof s.once!="function")x(o.projectName,i,l,p,B??S(s),v,w,m,k(s));else{let L=!1;const G=a(W=>{if(L)return;L=!0;const Z=W&&s.statusCode&&s.statusCode>=400?s.statusCode:S(s);x(o.projectName,i,l,p,Z,v,w,m,k(s))},"settle");s.once("finish",()=>G(!0)),s.once("close",()=>G(!1))}return N(i,O,D,v,"error"),P(),g.error(w),new U})).subscribe()}),()=>{F?.unsubscribe(),A=!0,H()}})}};T=te([re()],T);export{T as TraceInterceptor};const b=new Map,ge=6e4,we=a(()=>process.env.LENSMCP_HTTP_SHAPES!=="0","shapesOn");function X(t,e,o,d,r,s,n){try{const c=s.statusCode??200,f=`${o} ${d} ${Math.floor(c/100)}`,I=Date.now();if(I-(b.get(f)??0)<ge)return;b.set(f,I),b.size>2e3&&b.delete(b.keys().next().value);const i=r.headers??{},m=r.body!==void 0&&r.body!==null&&typeof r.body=="object"&&!Buffer.isBuffer(r.body)?z(r.body):void 0,l=n&&n.value!==void 0&&typeof n.value=="object"&&n.value!==null&&!Buffer.isBuffer(n.value)&&typeof n.value.pipe!="function"?z(n.value):void 0,p={id:y(),sessionId:e.sessionId,timestamp:I,source:"nestjs",category:"backend",severity:"info",context:{sessionId:e.sessionId,flowId:e.flowId,requestId:e.requestId,...e.runId?{runId:e.runId}:{}},fingerprint:$({kind:"http-exchange",identity:f}),title:`${o} ${d} \u2192 ${c} (its shape)`,raw:{kind:"http-exchange",method:o,route:d,status:c,request:{...de(i,r.query,r.params),...m?{body:m}:{}},response:{...ue(s.getHeaders?.()??{},typeof i.origin=="string"?i.origin:void 0),...l?{body:l}:{}}}};C(p,t),q().emit(p)}catch{}}u(X,"pe"),a(X,"recordExchange");function R(t){const e=t;if(typeof e?.getStatus=="function")return e.getStatus();if(typeof e?.status=="number"&&e.status>=100)return e.status;if(typeof e?.statusCode=="number"&&e.statusCode>=100)return e.statusCode}u(R,"U"),a(R,"ownStatus");const ye=new Set(["TypeError","ReferenceError","SyntaxError","RangeError","EvalError","URIError"]);export function requestOutcome(t,e){return e instanceof Error&&ye.has(e.name)&&R(e)===void 0?"fault":t<400?"ok":t<500?"refused":t===500?"fault":"declared"}u(requestOutcome,"requestOutcome"),a(requestOutcome,"requestOutcome");function J(t){return t==="ok"?"info":t==="refused"?"warning":"error"}u(J,"me"),a(J,"severityOf");function S(t){return t.statusCode&&t.statusCode>=400?t.statusCode:500}u(S,"X"),a(S,"inferStatus");function h(t){if(typeof t=="string")return t;if(Array.isArray(t)&&typeof t[0]=="string")return t[0]}u(h,"h"),a(h,"stringHeader");function K(t,e,o,d){const r=q(),s=`request:${e} ${o}`,n={id:y(),sessionId:t.sessionId,timestamp:d,source:"nestjs",category:"backend",severity:"info",context:{sessionId:t.sessionId,flowId:t.flowId,requestId:t.requestId,originType:"request",originNodeId:s},fingerprint:$({kind:"flow-origin",identity:`${e}:${o}`}),title:`${e} ${o}`,raw:{kind:"flow-origin",originNodeId:s,method:e,route:o}};C(n,r.projectName),r.emit(n)}u(K,"ye"),a(K,"emitRequestOrigin");function N(t,e,o,d,r){if(!e||!o)return;const s=q(),n=Date.now()-d,c=`${e}.${o}`,f={id:y(),sessionId:t.sessionId,timestamp:Date.now(),source:"nestjs",category:"backend",severity:r==="error"?"error":"info",context:{sessionId:t.sessionId,flowId:t.flowId,requestId:t.requestId,...t.runId?{runId:t.runId}:{}},fingerprint:$({kind:"method-call",identity:c}),title:`${c} (${n}ms)${r==="error"?" \u2717":""}`,raw:{kind:"span",span:{name:c,role:"controller",flowId:t.flowId,requestId:t.requestId,startTime:d,endTime:Date.now(),durationMs:n,status:r}}};C(f,q().projectName),s.emit(f)}u(N,"z"),a(N,"emitControllerSpan");function Q(t){if(!(t instanceof Error))return{message:String(t)};const e=t.stack?t.stack.split(`
|
|
2
2
|
`).slice(0,30).join(`
|
|
3
|
-
`):void 0;return{...t.name?{name:t.name}:{},message:t.message,...e?{stack:e}:{}}}u(
|
|
3
|
+
`):void 0;return{...t.name?{name:t.name}:{},message:t.message,...e?{stack:e}:{}}}u(Q,"ge"),a(Q,"errorDetail");function C(t,e){if(!e)return;const o=t.raw;o&&o.project===void 0&&(o.project=e)}u(C,"E"),a(C,"stampProject");function k(t){try{const e=t.getHeaders?.()["content-type"];return typeof e=="string"?e.split(";")[0]?.trim().toLowerCase():void 0}catch{return}}u(k,"O"),a(k,"responseContentType");function x(t,e,o,d,r,s,n,c,f){const I=q(),i=Date.now()-s,m=requestOutcome(r,n),l={id:y(),sessionId:e.sessionId,timestamp:Date.now(),source:"nestjs",category:"backend",severity:J(m),context:{sessionId:e.sessionId,flowId:e.flowId,requestId:e.requestId,...e.runId?{runId:e.runId}:{},...e.parentRequestId?{parentRequestId:e.parentRequestId}:{},originNodeId:e.originNodeId,traceparent:e.traceparent},fingerprint:$({kind:"server-request",identity:`${o}:${d}:${Math.floor(r/100)}xx`}),title:`${o} ${d} \u2192 ${r} (${i}ms)`,message:n instanceof Error?n.message:void 0,raw:{kind:"server-request",request:{method:o,route:d,status:r,outcome:m,durationMs:i,startedAt:s,...f?{contentType:f,streaming:f==="text/event-stream"}:{},endedAt:Date.now(),flowId:e.flowId,requestId:e.requestId,...e.parentRequestId?{parentRequestId:e.parentRequestId}:{},...typeof c=="string"?{exchangeId:c}:{},...e.runId?{runId:e.runId}:{},...e.dbCallCount||e.redisCallCount?{calls:{...e.dbCallCount?{db:e.dbCallCount}:{},...e.redisCallCount?{cache:e.redisCallCount}:{}}}:{},...n?{error:Q(n)}:{}}}},p={...l,id:y(),raw:{kind:"span",span:{name:`nest.request ${o} ${d}`,traceId:e.traceparent,flowId:e.flowId,requestId:e.requestId,startTime:s,endTime:Date.now(),durationMs:i,status:m==="ok"?"ok":"error"}}};C(l,t),C(p,t),I.emit(l),I.emit(p)}u(x,"j"),a(x,"emitRequest");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/nest-instrumentation",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lensmcp/core": "1.25.
|
|
18
|
-
"@lensmcp/memory-tracker": "1.25.
|
|
19
|
-
"@lensmcp/protocol-types": "1.25.
|
|
17
|
+
"@lensmcp/core": "1.25.25",
|
|
18
|
+
"@lensmcp/memory-tracker": "1.25.25",
|
|
19
|
+
"@lensmcp/protocol-types": "1.25.25",
|
|
20
20
|
"tslib": "^2.3.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|