@lensmcp/node-instrumentation 1.25.35 → 1.25.36

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/emit.d.ts CHANGED
@@ -31,6 +31,11 @@ export type LensSeverity = 'info' | 'warning' | 'error';
31
31
  export type LogSeverity = 'debug' | 'info' | 'warning' | 'error' | 'fatal';
32
32
  /** Service identity stamped on every event (set by the cluster serve executor). */
33
33
  export declare const PROJECT: string;
34
+ /**
35
+ * The `serve` worker this process is (`LENSMCP_WORKER`, set by the devserver's `workerEnv`) — absent in a pod. A
36
+ * worker shares its service's PROJECT, so its log lines say which process wrote them (issues/closed/foodguard-112).
37
+ */
38
+ export declare const WORKER: string | undefined;
34
39
  /** The file bus — same default the cluster gateway and dashboard use. */
35
40
  export declare const EVENT_FILE: string;
36
41
  /** True while the lens itself is appending — the fs tap skips self-writes. */
package/lib/emit.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var m=Object.defineProperty;var i=(r,s)=>m(r,"name",{value:s,configurable:!0});var a=Object.defineProperty,c=i((r,s)=>a(r,"name",{value:s,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EVENT_FILE=exports.PROJECT=exports.EVENT_MAX_FILES=exports.EVENT_MAX_BYTES=void 0,exports.maybeRotateEventFile=maybeRotateEventFile,exports.isLensWriting=isLensWriting,exports.lensEmit=lensEmit,exports.lensEmitOutcome=lensEmitOutcome,exports.lensLog=lensLog;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_path_1=require("node:path"),bus_rotation_1=require("@lensmcp/core/bus-rotation"),flood_guard_1=require("./flood-guard"),flow_context_1=require("./flow-context"),loop_identity_1=require("./loop-identity"),appendFileSync=nodeFs.appendFileSync,mkdirSync=nodeFs.mkdirSync,statSync=nodeFs.statSync,renameSync=nodeFs.renameSync,unlinkSync=nodeFs.unlinkSync,openSync=nodeFs.openSync,closeSync=nodeFs.closeSync,BUS_CAPS=(0,bus_rotation_1.busCapsFromEnv)();exports.EVENT_MAX_BYTES=BUS_CAPS.maxBytes,exports.EVENT_MAX_FILES=BUS_CAPS.maxFiles;const rotators=new Map,BUS_FS={statSync,renameSync,unlinkSync,openSync,closeSync};function maybeRotateEventFile(r,s,e){if(e!==void 0){const n=e.maxBytes??exports.EVENT_MAX_BYTES,t=e.maxFiles??exports.EVENT_MAX_FILES;(0,bus_rotation_1.createBusRotator)(r,{maxBytes:n,maxFiles:t,fs:BUS_FS,checkEveryBytes:0})(s);return}let o=rotators.get(r);o||(o=(0,bus_rotation_1.createBusRotator)(r,{maxBytes:exports.EVENT_MAX_BYTES,maxFiles:exports.EVENT_MAX_FILES,fs:BUS_FS}),rotators.set(r,o)),o(s)}i(maybeRotateEventFile,"maybeRotateEventFile"),c(maybeRotateEventFile,"maybeRotateEventFile"),exports.PROJECT=process.env.LENSMCP_PROJECT||process.env.SERVICE_NAME||"app",exports.EVENT_FILE=process.env.LENSMCP_EVENT_FILE||`${process.cwd()}/.lensmcp/events.jsonl`;let writing=!1,dirReady=!1;const emitGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),logGuard=(0,flood_guard_1.createEventFloodGuard)({burst:120,perSec:20});function isLensWriting(){return writing}i(isLensWriting,"isLensWriting"),c(isLensWriting,"isLensWriting");function lensEmit(r,s,e,o,n,t,p="cluster"){return lensEmitOutcome(r,s,e,o,n,t,p)==="written"}i(lensEmit,"lensEmit"),c(lensEmit,"lensEmit");function lensEmitOutcome(r,s,e,o,n,t,p="cluster",u=emitGuard){try{writing=!0;const E=n??`${r}:${String(o.name??r)}`,d=u.admit(E);if(!d.ok)return"suppressed";dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const l=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:r,category:p,severity:s,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{},...t?.originNodeId?{originNodeId:t.originNodeId}:{},...t?.originType?{originType:t.originType}:{}},fingerprint:E,title:e,raw:{project:exports.PROJECT,...o,loopId:loop_identity_1.NODE_LOOP.id,...d.suppressed>0?{floodSuppressed:d.suppressed}:{}}})+`
2
- `;return maybeRotateEventFile(exports.EVENT_FILE,l.length),appendFileSync(exports.EVENT_FILE,l),"written"}catch{return"failed"}finally{writing=!1}}i(lensEmitOutcome,"lensEmitOutcome"),c(lensEmitOutcome,"lensEmitOutcome");function lensLog(r,s,e){try{writing=!0;const o=e?.bucket!==void 0?`log:${exports.PROJECT}:${e.bucket}`:r==="error"||r==="fatal"?`log:error:${exports.PROJECT}`:`log:${exports.PROJECT}`,n=e?.bucket!==void 0?{ok:!0,suppressed:e.suppressed??0}:logGuard.admit(o);if(!n.ok)return!1;dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const t=(0,flow_context_1.flowContext)(),p=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:"nestjs",category:"runtime",severity:r,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{}},fingerprint:o,title:s,raw:{project:exports.PROJECT,kind:"log",...e?.stack?{request:{error:{message:s,stack:e.stack}}}:{},...e?.text?{text:e.text}:{},...e?.continues?{continues:!0}:{},...e?.stream?{stream:e.stream}:{},...e?.level?{level:e.level}:{},...e?.logger?{logger:e.logger}:{},...n.suppressed>0?{floodSuppressed:n.suppressed}:{}}})+`
1
+ "use strict";var x=Object.defineProperty;var i=(r,o)=>x(r,"name",{value:o,configurable:!0});var a=Object.defineProperty,c=i((r,o)=>a(r,"name",{value:o,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.EVENT_FILE=exports.WORKER=exports.PROJECT=exports.EVENT_MAX_FILES=exports.EVENT_MAX_BYTES=void 0,exports.maybeRotateEventFile=maybeRotateEventFile,exports.isLensWriting=isLensWriting,exports.lensEmit=lensEmit,exports.lensEmitOutcome=lensEmitOutcome,exports.lensLog=lensLog;const tslib_1=require("tslib"),nodeFs=tslib_1.__importStar(require("node:fs")),node_path_1=require("node:path"),bus_rotation_1=require("@lensmcp/core/bus-rotation"),flood_guard_1=require("./flood-guard"),flow_context_1=require("./flow-context"),loop_identity_1=require("./loop-identity"),appendFileSync=nodeFs.appendFileSync,mkdirSync=nodeFs.mkdirSync,statSync=nodeFs.statSync,renameSync=nodeFs.renameSync,unlinkSync=nodeFs.unlinkSync,openSync=nodeFs.openSync,closeSync=nodeFs.closeSync,BUS_CAPS=(0,bus_rotation_1.busCapsFromEnv)();exports.EVENT_MAX_BYTES=BUS_CAPS.maxBytes,exports.EVENT_MAX_FILES=BUS_CAPS.maxFiles;const rotators=new Map,BUS_FS={statSync,renameSync,unlinkSync,openSync,closeSync};function maybeRotateEventFile(r,o,e){if(e!==void 0){const n=e.maxBytes??exports.EVENT_MAX_BYTES,t=e.maxFiles??exports.EVENT_MAX_FILES;(0,bus_rotation_1.createBusRotator)(r,{maxBytes:n,maxFiles:t,fs:BUS_FS,checkEveryBytes:0})(o);return}let s=rotators.get(r);s||(s=(0,bus_rotation_1.createBusRotator)(r,{maxBytes:exports.EVENT_MAX_BYTES,maxFiles:exports.EVENT_MAX_FILES,fs:BUS_FS}),rotators.set(r,s)),s(o)}i(maybeRotateEventFile,"maybeRotateEventFile"),c(maybeRotateEventFile,"maybeRotateEventFile"),exports.PROJECT=process.env.LENSMCP_PROJECT||process.env.SERVICE_NAME||"app",exports.WORKER=process.env.LENSMCP_WORKER||void 0,exports.EVENT_FILE=process.env.LENSMCP_EVENT_FILE||`${process.cwd()}/.lensmcp/events.jsonl`;let writing=!1,dirReady=!1;const emitGuard=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),logGuard=(0,flood_guard_1.createEventFloodGuard)({burst:120,perSec:20});function isLensWriting(){return writing}i(isLensWriting,"isLensWriting"),c(isLensWriting,"isLensWriting");function lensEmit(r,o,e,s,n,t,p="cluster"){return lensEmitOutcome(r,o,e,s,n,t,p)==="written"}i(lensEmit,"lensEmit"),c(lensEmit,"lensEmit");function lensEmitOutcome(r,o,e,s,n,t,p="cluster",u=emitGuard){try{writing=!0;const d=n??`${r}:${String(s.name??r)}`,E=u.admit(d);if(!E.ok)return"suppressed";dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const l=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:r,category:p,severity:o,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{},...t?.originNodeId?{originNodeId:t.originNodeId}:{},...t?.originType?{originType:t.originType}:{}},fingerprint:d,title:e,raw:{project:exports.PROJECT,...s,loopId:loop_identity_1.NODE_LOOP.id,...E.suppressed>0?{floodSuppressed:E.suppressed}:{}}})+`
2
+ `;return maybeRotateEventFile(exports.EVENT_FILE,l.length),appendFileSync(exports.EVENT_FILE,l),"written"}catch{return"failed"}finally{writing=!1}}i(lensEmitOutcome,"lensEmitOutcome"),c(lensEmitOutcome,"lensEmitOutcome");function lensLog(r,o,e){try{writing=!0;const s=e?.bucket!==void 0?`log:${exports.PROJECT}:${e.bucket}`:r==="error"||r==="fatal"?`log:error:${exports.PROJECT}`:`log:${exports.PROJECT}`,n=e?.bucket!==void 0?{ok:!0,suppressed:e.suppressed??0}:logGuard.admit(s);if(!n.ok)return!1;dirReady||(mkdirSync((0,node_path_1.dirname)(exports.EVENT_FILE),{recursive:!0}),dirReady=!0);const t=(0,flow_context_1.flowContext)(),p=JSON.stringify({id:Date.now().toString(36)+Math.random().toString(36).slice(2,10),sessionId:"pending",timestamp:Date.now(),source:"nestjs",category:"runtime",severity:r,context:{sessionId:"pending",projectName:exports.PROJECT,...t?.flowId?{flowId:t.flowId}:{},...t?.requestId?{requestId:t.requestId}:{},...t?.runId?{runId:t.runId}:{}},fingerprint:s,title:o,raw:{project:exports.PROJECT,kind:"log",...exports.WORKER?{worker:exports.WORKER}:{},...e?.stack?{request:{error:{message:o,stack:e.stack}}}:{},...e?.text?{text:e.text}:{},...e?.continues?{continues:!0}:{},...e?.stream?{stream:e.stream}:{},...e?.level?{level:e.level}:{},...e?.logger?{logger:e.logger}:{},...n.suppressed>0?{floodSuppressed:n.suppressed}:{}}})+`
3
3
  `;return maybeRotateEventFile(exports.EVENT_FILE,p.length),appendFileSync(exports.EVENT_FILE,p),!0}catch{return!1}finally{writing=!1}}i(lensLog,"lensLog"),c(lensLog,"lensLog");
@@ -1 +1,14 @@
1
+ /**
2
+ * Is this process one of a service's own — whose output is the service's log?
3
+ *
4
+ * A pod (`APP_RUNNER=1`), or one of its `serve` workers (`LENSMCP_WORKER`, which the devserver's `workerEnv` sets and
5
+ * `APP_RUNNER` it does not). Never the gateway or the devserver parent, whose high-volume proxy logging would swamp
6
+ * the bus with synchronous appends — and which already relays every pod's and worker's lines into its own ring.
7
+ *
8
+ * Workers were left out (issues/closed/foodguard-112): a worker carries the same preload as a pod, but this gate read
9
+ * `APP_RUNNER` alone, so nothing a worker printed ever reached the bus. A background loop's periodic line — printed
10
+ * outside any request, where the Nest logger tap does not capture — was current in `lensmcp logs <service>` (the
11
+ * devserver's ring) and absent from `logs_read`, while the pods' lines kept the service reading as `connected`.
12
+ */
13
+ export declare function isServiceProcess(env?: NodeJS.ProcessEnv): boolean;
1
14
  export declare function tapStdout(): void;
package/lib/tap-stdout.js CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var R=Object.defineProperty;var f=(t,e)=>R(t,"name",{value:e,configurable:!0});var E=Object.defineProperty,u=f((t,e)=>E(t,"name",{value:e,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.tapStdout=tapStdout;const emit_1=require("./emit"),tap_nest_logger_1=require("./tap-nest-logger"),ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function severityOf(t,e){return/\bFATAL\b/.test(t)?"fatal":/\bERROR\b/.test(t)?"error":/\bWARN\b/.test(t)?"warning":/\bDEBUG\b/.test(t)||/\bVERBOSE\b/.test(t)?"debug":/\bLOG\b/.test(t)?"info":e}f(severityOf,"severityOf"),u(severityOf,"severityOf");const STACK_FRAME=/^\s+(at\s|\.\.\.\s\d+\smore)/,CONTINUATION=/^(\s+\S|[}\])]+[,;]?$)/,CONTINUES_WITHIN_MS=1e3;function emitChunk(t,e,p,c,l){const o=t.split(`
2
- `).map(r=>r.replace(ANSI,"").replace(/\s+$/,""));let s=0,n=p;for(;s<o.length;){const r=o[s];if(s+=1,!r.trim())continue;const i=[];for(;s<o.length&&o[s].trim()&&CONTINUATION.test(o[s]);)i.push(o[s]),s+=1;const g=[r,...i].filter(_=>STACK_FRAME.test(_)),a=CONTINUATION.test(r)&&n&&c-n.at<=CONTINUES_WITHIN_MS?n.severity:void 0,m=severityOf(r,e),O=m!==e||/\b(?:FATAL|ERROR|WARN|DEBUG|VERBOSE|LOG)\b/.test(r),b=a??(O?m:g.length>0?"error":e),d=[r,...i];if(!a&&(0,tap_nest_logger_1.isLoggerEcho)(d.join(`
3
- `),c)){n={severity:b,at:c};continue}(0,emit_1.lensLog)(b,a?r.trim():r,{...g.length>0?{stack:d.join(`
1
+ "use strict";var R=Object.defineProperty;var f=(e,t)=>R(e,"name",{value:t,configurable:!0});var E=Object.defineProperty,u=f((e,t)=>E(e,"name",{value:t,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isServiceProcess=isServiceProcess,exports.tapStdout=tapStdout;const emit_1=require("./emit"),tap_nest_logger_1=require("./tap-nest-logger"),ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function severityOf(e,t){return/\bFATAL\b/.test(e)?"fatal":/\bERROR\b/.test(e)?"error":/\bWARN\b/.test(e)?"warning":/\bDEBUG\b/.test(e)||/\bVERBOSE\b/.test(e)?"debug":/\bLOG\b/.test(e)?"info":t}f(severityOf,"severityOf"),u(severityOf,"severityOf");const STACK_FRAME=/^\s+(at\s|\.\.\.\s\d+\smore)/,CONTINUATION=/^(\s+\S|[}\])]+[,;]?$)/,CONTINUES_WITHIN_MS=1e3;function emitChunk(e,t,p,c,l){const o=e.split(`
2
+ `).map(r=>r.replace(ANSI,"").replace(/\s+$/,""));let n=0,s=p;for(;n<o.length;){const r=o[n];if(n+=1,!r.trim())continue;const i=[];for(;n<o.length&&o[n].trim()&&CONTINUATION.test(o[n]);)i.push(o[n]),n+=1;const g=[r,...i].filter(O=>STACK_FRAME.test(O)),a=CONTINUATION.test(r)&&s&&c-s.at<=CONTINUES_WITHIN_MS?s.severity:void 0,S=severityOf(r,t),_=S!==t||/\b(?:FATAL|ERROR|WARN|DEBUG|VERBOSE|LOG)\b/.test(r),b=a??(_?S:g.length>0?"error":t),d=[r,...i];if(!a&&(0,tap_nest_logger_1.isLoggerEcho)(d.join(`
3
+ `),c)){s={severity:b,at:c};continue}(0,emit_1.lensLog)(b,a?r.trim():r,{...g.length>0?{stack:d.join(`
4
4
  `)}:{},...i.length>0&&g.length<i.length?{text:d.join(`
5
- `)}:{},...a?{continues:!0}:{},stream:l}),n={severity:b,at:c}}return n}f(emitChunk,"emitChunk"),u(emitChunk,"emitChunk");function tapStdout(){if(process.env.LENSMCP_LOGS==="0"||process.env.APP_RUNNER!=="1")return;const t=[[process.stdout,"info","stdout"],[process.stderr,"error","stderr"]];for(const[e,p,c]of t){if(e.write.__lensmcp)continue;const l=e.write.bind(e);let o;const s=u(function(n,...r){try{if(!(0,emit_1.isLensWriting)()){const i=typeof n=="string"?n:Buffer.isBuffer(n)?n.toString("utf8"):"";i&&i.indexOf("[lensmcp]")===-1&&(o=emitChunk(i,p,o,Date.now(),c))}}catch{}return l(n,...r)},"wrapped");s.__lensmcp=!0,e.write=s}}f(tapStdout,"tapStdout"),u(tapStdout,"tapStdout");
5
+ `)}:{},...a?{continues:!0}:{},stream:l}),s={severity:b,at:c}}return s}f(emitChunk,"emitChunk"),u(emitChunk,"emitChunk");function isServiceProcess(e=process.env){return e.APP_RUNNER==="1"||!!e.LENSMCP_WORKER}f(isServiceProcess,"isServiceProcess"),u(isServiceProcess,"isServiceProcess");function tapStdout(){if(process.env.LENSMCP_LOGS==="0"||!isServiceProcess())return;const e=[[process.stdout,"info","stdout"],[process.stderr,"error","stderr"]];for(const[t,p,c]of e){if(t.write.__lensmcp)continue;const l=t.write.bind(t);let o;const n=u(function(s,...r){try{if(!(0,emit_1.isLensWriting)()){const i=typeof s=="string"?s:Buffer.isBuffer(s)?s.toString("utf8"):"";i&&i.indexOf("[lensmcp]")===-1&&(o=emitChunk(i,p,o,Date.now(),c))}}catch{}return l(s,...r)},"wrapped");n.__lensmcp=!0,t.write=n}}f(tapStdout,"tapStdout"),u(tapStdout,"tapStdout");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/node-instrumentation",
3
- "version": "1.25.35",
3
+ "version": "1.25.36",
4
4
  "main": "./index.js",
5
5
  "types": "./index.d.ts",
6
6
  "exports": {
@@ -15,9 +15,9 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@lensmcp/core": "1.25.35",
19
- "@lensmcp/nest-instrumentation": "1.25.35",
20
- "@lensmcp/protocol-types": "1.25.35",
18
+ "@lensmcp/core": "1.25.36",
19
+ "@lensmcp/nest-instrumentation": "1.25.36",
20
+ "@lensmcp/protocol-types": "1.25.36",
21
21
  "tslib": "^2.3.0"
22
22
  },
23
23
  "optionalDependencies": {