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