@lensmcp/node-instrumentation 1.25.42 → 1.25.44

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.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The record's `raw.kind`. `@lensmcp/core` reads it under the same name (`SQL_DROPS_KIND` in `performance-window.ts`),
3
+ * and the SQL catalog after it; `sql-drops.spec.ts` reads this lib's real output through core's reader.
4
+ */
5
+ export declare const SQL_DROPS_KIND = "db-dropped";
6
+ /**
7
+ * A run this slow is slow: the lens's default `slowQueryMs`. The pg tap buckets slow runs apart from the fast ones by it,
8
+ * and a record counts dropped runs at or over it as `slow` — the record says the value (`slowMs`), since a workspace can
9
+ * judge by another.
10
+ */
11
+ export declare const SLOW_QUERY_MS = 100;
12
+ /** Pending drops are written this long after the first of them. */
13
+ export declare const SQL_DROPS_EVERY_MS = 1000;
14
+ /** One statement's dropped runs since the last record. */
15
+ export interface DroppedStatement {
16
+ sqlId: string;
17
+ op: string;
18
+ table?: string;
19
+ sqlName?: string;
20
+ /** The first 500 characters — only for a statement no event of which reached the bus, so a reader can name it. */
21
+ query?: string;
22
+ runs: number;
23
+ /** Runs at or over {@link SLOW_QUERY_MS}. */
24
+ slow: number;
25
+ failed: number;
26
+ workMs: number;
27
+ maxMs: number;
28
+ firstAt: number;
29
+ lastAt: number;
30
+ }
31
+ /** One dropped run, as the tap knows it when its bucket refuses the event. */
32
+ export interface DroppedRun {
33
+ sqlId: string;
34
+ op: string;
35
+ table?: string;
36
+ sqlName?: string;
37
+ query?: string;
38
+ durationMs: number;
39
+ failed: boolean;
40
+ at: number;
41
+ }
42
+ /** A run whose event its flood bucket refused. Counted under its statement; written within a second. */
43
+ export declare function noteDroppedRun(run: DroppedRun): void;
44
+ /** Write the pending drops as one record now. Kept for the next record when its own bucket refuses it. */
45
+ export declare function flushSqlDrops(): void;
@@ -0,0 +1 @@
1
+ "use strict";var n=Object.defineProperty;var u=(e,o)=>n(e,"name",{value:o,configurable:!0});var a=Object.defineProperty,d=u((e,o)=>a(e,"name",{value:o,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SQL_DROPS_EVERY_MS=exports.SLOW_QUERY_MS=exports.SQL_DROPS_KIND=void 0,exports.noteDroppedRun=noteDroppedRun,exports.flushSqlDrops=flushSqlDrops;const flood_guard_1=require("./flood-guard"),emit_1=require("./emit");exports.SQL_DROPS_KIND="db-dropped",exports.SLOW_QUERY_MS=100,exports.SQL_DROPS_EVERY_MS=1e3;const MAX_SHAPES=200,guard=(0,flood_guard_1.createEventFloodGuard)({burst:10,perSec:2}),pending=new Map;let overflow,timer,exitHooked=!1;function noteDroppedRun(e){const o=e.durationMs>=exports.SLOW_QUERY_MS?1:0,t=e.failed?1:0;let s=pending.get(e.sqlId);!s&&pending.size>=MAX_SHAPES?(overflow??={runs:0,slow:0,failed:0,maxMs:0},overflow.runs+=1,overflow.slow+=o,overflow.failed+=t,overflow.maxMs=Math.max(overflow.maxMs,e.durationMs)):(s||(s={sqlId:e.sqlId,op:e.op,...e.table?{table:e.table}:{},...e.sqlName?{sqlName:e.sqlName}:{},runs:0,slow:0,failed:0,workMs:0,maxMs:0,firstAt:e.at,lastAt:e.at},pending.set(e.sqlId,s)),e.query&&!s.query&&(s.query=e.query),s.runs+=1,s.slow+=o,s.failed+=t,s.workMs+=e.durationMs,s.maxMs=Math.max(s.maxMs,e.durationMs),s.lastAt=Math.max(s.lastAt,e.at)),exitHooked||(exitHooked=!0,process.once("exit",()=>flushSqlDrops())),timer||(timer=setTimeout(()=>{timer=void 0,flushSqlDrops()},exports.SQL_DROPS_EVERY_MS),timer.unref?.())}u(noteDroppedRun,"noteDroppedRun"),d(noteDroppedRun,"noteDroppedRun");function flushSqlDrops(){if(timer&&(clearTimeout(timer),timer=void 0),pending.size===0&&!overflow)return;const e=[...pending.values()],o=e.reduce((r,l)=>r+l.runs,overflow?.runs??0),t=e.reduce((r,l)=>r+l.slow,overflow?.slow??0),s=e.reduce((r,l)=>r+l.failed,overflow?.failed??0);if((0,emit_1.lensEmitOutcome)("lens",s?"error":"info",`SQL: ${o} run${o===1?"":"s"} of ${e.length} statement${e.length===1?"":"s"} not on the bus (flood guard${t?`; ${t} slow`:""}${s?`; ${s} failed`:""})`,{kind:exports.SQL_DROPS_KIND,slowMs:exports.SLOW_QUERY_MS,runs:o,slow:t,failed:s,shapes:e,...overflow?{overflow}:{}},`lens:sql-drops:${emit_1.PROJECT}`,void 0,"db",guard)==="suppressed"){timer||(timer=setTimeout(()=>{timer=void 0,flushSqlDrops()},exports.SQL_DROPS_EVERY_MS),timer.unref?.());return}pending.clear(),overflow=void 0}u(flushSqlDrops,"flushSqlDrops"),d(flushSqlDrops,"flushSqlDrops");
package/lib/tap-pg.js CHANGED
@@ -1 +1 @@
1
- "use strict";var B=Object.defineProperty;var p=(t,e)=>B(t,"name",{value:e,configurable:!0});var X=Object.defineProperty,r=p((t,e)=>X(t,"name",{value:e,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedAppName=taggedAppName,exports.pgTap=pgTap;const redact_1=require("@lensmcp/core/redact"),sql_shape_1=require("@lensmcp/core/sql-shape"),emit_1=require("./emit"),flow_context_1=require("./flow-context"),sql_accounting_1=require("./sql-accounting"),tap_pg_pool_1=require("./tap-pg-pool"),callsite_1=require("./callsite"),active_work_1=require("./active-work"),emit_2=require("./emit"),sql_values_1=require("./sql-values"),SKIP_OPS=new Set(["BEGIN","START","COMMIT","END","ROLLBACK","SAVEPOINT","RELEASE","SET","RESET","SHOW","DEALLOCATE","DISCARD","LISTEN","UNLISTEN"]),STATEMENT_EVERY_MS=10*6e4,STATEMENT_MAX=64*1024,SLOW_SITE_MS=250,sites=new callsite_1.SiteSampler,statementSentAt=new Map,MAX_SHAPES_REMEMBERED=2e3,firstWord=r(t=>(/^\s*(?:(?:\/\*[\s\S]*?\*\/|--[^\n]*\n?)\s*)*(\w+)/.exec(t)?.[1]??"query").toUpperCase(),"firstWord");function parseSql(t){const e=(0,sql_shape_1.sqlShape)(t),n=(e.target??e.tables[0])?.split(".").pop();return{op:e.verb,...n?{table:n}:{},sqlId:e.id,tables:e.tables,...e.name?{name:e.name}:{}}}p(parseSql,"parseSql"),r(parseSql,"parseSql");const oneLine=r(t=>t.replace(/\s+/g," ").trim(),"oneLine"),clip=r((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function paramPreview(t){if(!(!Array.isArray(t)||t.length===0))return t.slice(0,10).map(e=>{if(e==null)return String(e);const n=typeof e=="string"?e:(()=>{try{return JSON.stringify(e)}catch{return String(e)}})();return clip(n,80)})}p(paramPreview,"paramPreview"),r(paramPreview,"paramPreview");const rowsOf=r(t=>t?.rowCount??t?.rows?.length??0,"rowsOf");function resultPreview(t){const e=t?.rows;if(!(!Array.isArray(e)||e.length===0))try{return clip(JSON.stringify((0,redact_1.redactDeep)(e.slice(0,2))),240)}catch{return}}p(resultPreview,"resultPreview"),r(resultPreview,"resultPreview");function connectionOf(t){const e=t,n=e?.connectionParameters,o=typeof e?.database=="string"?e.database:typeof n?.database=="string"?n.database:void 0,s=typeof e?.host=="string"?e.host:typeof n?.host=="string"?n.host:void 0,i=typeof e?.port=="number"||typeof e?.port=="string"?e.port:typeof n?.port=="number"||typeof n?.port=="string"?n.port:5432;return{...o?{database:o}:{},...s?{server:`${s}:${i}`}:{}}}p(connectionOf,"connectionOf"),r(connectionOf,"connectionOf");const APP_NAME_MAX=63;function taggedAppName(t,e,n,o){const s=` lens:${e.replace(/[^\x21-\x7e]/g,"?").replace(/:/g,"_")}${n>0?`:g${n}`:""}${o?`:p${o}`:""}`.slice(0,APP_NAME_MAX);return`${(t??"node").replace(/[^\x20-\x7e]/g,"?").replace(/ lens:\S+$/,"").slice(0,Math.max(0,APP_NAME_MAX-s.length))}${s}`}p(taggedAppName,"taggedAppName"),r(taggedAppName,"taggedAppName");function tagApplicationName(t){if(process.env.LENSMCP_PG_APP_NAME==="0")return;const e=t.getStartupConf;if(typeof e!="function"||e.__lensmcp)return;const n=r(function(){const o=e.call(this);try{o&&typeof o=="object"&&emit_2.PROJECT&&(o.application_name=taggedAppName(typeof o.application_name=="string"?o.application_name:void 0,emit_2.PROJECT,(0,active_work_1.activeWorkGeneration)(),process.pid))}catch{}return o},"wrapped");n.__lensmcp=!0,t.getStartupConf=n}p(tagApplicationName,"tagApplicationName"),r(tagApplicationName,"tagApplicationName");function pgTap(t){const e=t?.Client?.prototype,n=e?.query;if(!e||typeof n!="function")return!1;try{(0,tap_pg_pool_1.pgPoolTap)(t)}catch{}try{tagApplicationName(e)}catch{}if(n.__lensmcp)return!0;const o=r(function(s,i,q){const m=s,d=typeof m=="string"?m:m?.text;if(!d||m&&typeof m=="object"&&typeof m.submit=="function")return n.call(this,s,i,q);if(SKIP_OPS.has(firstWord(d)))return n.call(this,s,i,q);const{op:W,table:l,sqlId:S,tables:$,name:C}=parseSql(d),J=connectionOf(this),y=W.toLowerCase(),V=`db:${y}:${l??"query"}`,u=Date.now(),A=(0,flow_context_1.flowContext)(),j=(0,callsite_1.captureSite)(),M=(0,tap_pg_pool_1.checkoutSite)(),b=(0,flow_context_1.liveFlowContext)();b&&(b.dbCallCount=(b.dbCallCount??0)+1);const w=(0,sql_accounting_1.beginSqlStatement)(b,A,u),N=clip(oneLine(d),500),O=Array.isArray(i)?i:s?.values,x=paramPreview(O),h=x&&(0,redact_1.redactSqlParams)(d,x),v=r((a,f)=>{const c=Date.now()-u,T=u-(statementSentAt.get(S)??-1/0)>=STATEMENT_EVERY_MS;let P;try{P=sites.site(S,j,{force:!!a||T||c>=SLOW_SITE_MS,...M?{fallback:M}:{}})}catch{}const L={sqlId:S,...$.length?{tables:$}:{},...C?{sqlName:C}:{},...J,...P?{site:P}:{},...T?{statement:clip(d.trim(),STATEMENT_MAX)}:{}},E=(0,sql_values_1.newSqlValuesId)(u),R=E?{valuesId:E}:{};let _;if(a)_=(0,emit_1.lensEmitOutcome)("db","error",`${y}${l?" "+l:""} failed (${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...R,startedAt:u,error:String(a?.message??a),durationMs:c},`db:error:${y}:${l??"query"}`,A);else{const k=rowsOf(f),D=resultPreview(f);_=(0,emit_1.lensEmitOutcome)("db","info",`${y} ${l??"query"} (${k} rows, ${c}ms)`,{name:"postgres",kind:"db-query",op:y,...l?{table:l}:{},...L,query:N,...h?{params:h}:{},...D?{result:D}:{},...R,startedAt:u,rows:k,durationMs:c},V,A)}E&&_==="written"&&(0,sql_values_1.keepSqlValues)(E,u,d,O,a?void 0:f?.rows),T&&_==="written"&&(statementSentAt.delete(S),statementSentAt.set(S,u),statementSentAt.size>MAX_SHAPES_REMEMBERED&&statementSentAt.delete(statementSentAt.keys().next().value)),(0,sql_accounting_1.endSqlStatement)(w,{durationMs:c,failed:!!a,emitted:_})},"done"),I=typeof q=="function"?q:typeof i=="function"?i:void 0;if(I){const a=r((f,c)=>{try{v(f,c)}catch{}I(f,c)},"wrappedCb");try{return typeof i=="function"?n.call(this,s,a):n.call(this,s,i,a)}catch(f){throw(0,sql_accounting_1.abandonSqlStatement)(w),f}}let g;try{g=n.call(this,s,i)}catch(a){throw(0,sql_accounting_1.abandonSqlStatement)(w),a}return g&&typeof g.then=="function"?g.then(a=>v(void 0,a),a=>v(a,void 0)):(0,sql_accounting_1.abandonSqlStatement)(w),g},"wrapped");return o.__lensmcp=!0,e.query=o,!0}p(pgTap,"pgTap"),r(pgTap,"pgTap");
1
+ "use strict";var j=Object.defineProperty;var u=(t,e)=>j(t,"name",{value:e,configurable:!0});var U=Object.defineProperty,r=u((t,e)=>U(t,"name",{value:e,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedAppName=taggedAppName,exports.pgTap=pgTap;const redact_1=require("@lensmcp/core/redact"),sql_shape_1=require("@lensmcp/core/sql-shape"),emit_1=require("./emit"),flood_guard_1=require("./flood-guard"),flow_context_1=require("./flow-context"),sql_accounting_1=require("./sql-accounting"),tap_pg_pool_1=require("./tap-pg-pool"),callsite_1=require("./callsite"),active_work_1=require("./active-work"),emit_2=require("./emit"),sql_values_1=require("./sql-values"),sql_drops_1=require("./sql-drops"),SKIP_OPS=new Set(["BEGIN","START","COMMIT","END","ROLLBACK","SAVEPOINT","RELEASE","SET","RESET","SHOW","DEALLOCATE","DISCARD","LISTEN","UNLISTEN"]),STATEMENT_EVERY_MS=10*6e4,STATEMENT_MAX=64*1024,SLOW_SITE_MS=250,sites=new callsite_1.SiteSampler,buckets=(0,flood_guard_1.createEventFloodGuard)({burst:30,perSec:5}),statementGuard={admit:r(t=>({ok:buckets.admit(t).ok,suppressed:0}),"admit")},statementSentAt=new Map,MAX_SHAPES_REMEMBERED=2e3,firstWord=r(t=>(/^\s*(?:(?:\/\*[\s\S]*?\*\/|--[^\n]*\n?)\s*)*(\w+)/.exec(t)?.[1]??"query").toUpperCase(),"firstWord");function parseSql(t){const e=(0,sql_shape_1.sqlShape)(t),n=(e.target??e.tables[0])?.split(".").pop();return{op:e.verb,...n?{table:n}:{},sqlId:e.id,tables:e.tables,...e.name?{name:e.name}:{}}}u(parseSql,"parseSql"),r(parseSql,"parseSql");const oneLine=r(t=>t.replace(/\s+/g," ").trim(),"oneLine"),clip=r((t,e)=>t.length>e?t.slice(0,e-1)+"\u2026":t,"clip");function paramPreview(t){if(!(!Array.isArray(t)||t.length===0))return t.slice(0,10).map(e=>{if(e==null)return String(e);const n=typeof e=="string"?e:(()=>{try{return JSON.stringify(e)}catch{return String(e)}})();return clip(n,80)})}u(paramPreview,"paramPreview"),r(paramPreview,"paramPreview");const rowsOf=r(t=>t?.rowCount??t?.rows?.length??0,"rowsOf");function resultPreview(t){const e=t?.rows;if(!(!Array.isArray(e)||e.length===0))try{return clip(JSON.stringify((0,redact_1.redactDeep)(e.slice(0,2))),240)}catch{return}}u(resultPreview,"resultPreview"),r(resultPreview,"resultPreview");function connectionOf(t){const e=t,n=e?.connectionParameters,a=typeof e?.database=="string"?e.database:typeof n?.database=="string"?n.database:void 0,s=typeof e?.host=="string"?e.host:typeof n?.host=="string"?n.host:void 0,i=typeof e?.port=="number"||typeof e?.port=="string"?e.port:typeof n?.port=="number"||typeof n?.port=="string"?n.port:5432;return{...a?{database:a}:{},...s?{server:`${s}:${i}`}:{}}}u(connectionOf,"connectionOf"),r(connectionOf,"connectionOf");const APP_NAME_MAX=63;function taggedAppName(t,e,n,a){const s=` lens:${e.replace(/[^\x21-\x7e]/g,"?").replace(/:/g,"_")}${n>0?`:g${n}`:""}${a?`:p${a}`:""}`.slice(0,APP_NAME_MAX);return`${(t??"node").replace(/[^\x20-\x7e]/g,"?").replace(/ lens:\S+$/,"").slice(0,Math.max(0,APP_NAME_MAX-s.length))}${s}`}u(taggedAppName,"taggedAppName"),r(taggedAppName,"taggedAppName");function tagApplicationName(t){if(process.env.LENSMCP_PG_APP_NAME==="0")return;const e=t.getStartupConf;if(typeof e!="function"||e.__lensmcp)return;const n=r(function(){const a=e.call(this);try{a&&typeof a=="object"&&emit_2.PROJECT&&(a.application_name=taggedAppName(typeof a.application_name=="string"?a.application_name:void 0,emit_2.PROJECT,(0,active_work_1.activeWorkGeneration)(),process.pid))}catch{}return a},"wrapped");n.__lensmcp=!0,t.getStartupConf=n}u(tagApplicationName,"tagApplicationName"),r(tagApplicationName,"tagApplicationName");function pgTap(t){const e=t?.Client?.prototype,n=e?.query;if(!e||typeof n!="function")return!1;try{(0,tap_pg_pool_1.pgPoolTap)(t)}catch{}try{tagApplicationName(e)}catch{}if(n.__lensmcp)return!0;const a=r(function(s,i,q){const S=s,f=typeof S=="string"?S:S?.text;if(!f||S&&typeof S=="object"&&typeof S.submit=="function")return n.call(this,s,i,q);if(SKIP_OPS.has(firstWord(f)))return n.call(this,s,i,q);const{op:G,table:c,sqlId:m,tables:N,name:b}=parseSql(f),J=connectionOf(this),g=G.toLowerCase(),v=`${g}:${c??"query"}`,p=Date.now(),M=(0,flow_context_1.flowContext)(),V=(0,callsite_1.captureSite)(),O=(0,tap_pg_pool_1.checkoutSite)(),w=(0,flow_context_1.liveFlowContext)();w&&(w.dbCallCount=(w.dbCallCount??0)+1);const E=(0,sql_accounting_1.beginSqlStatement)(w,M,p),T=clip(oneLine(f),500),x=Array.isArray(i)?i:s?.values,I=paramPreview(x),h=I&&(0,redact_1.redactSqlParams)(f,I),$=r((o,d)=>{const l=Date.now()-p,P=p-(statementSentAt.get(m)??-1/0)>=STATEMENT_EVERY_MS;let C;try{C=sites.site(m,V,{force:!!o||P||l>=SLOW_SITE_MS,...O?{fallback:O}:{}})}catch{}const k={sqlId:m,...N.length?{tables:N}:{},...b?{sqlName:b}:{},...J,...C?{site:C}:{},...P?{statement:clip(f.trim(),STATEMENT_MAX)}:{}},A=(0,sql_values_1.newSqlValuesId)(p),R=A?{valuesId:A}:{};let y;if(o)y=(0,emit_1.lensEmitOutcome)("db","error",`${g}${c?" "+c:""} failed (${l}ms)`,{name:"postgres",kind:"db-query",op:g,...c?{table:c}:{},...k,query:T,...h?{params:h}:{},...R,startedAt:p,error:String(o?.message??o),durationMs:l},`db:error:${v}`,M,"cluster",statementGuard);else{const D=rowsOf(d),W=resultPreview(d);y=(0,emit_1.lensEmitOutcome)("db","info",`${g} ${c??"query"} (${D} rows, ${l}ms)`,{name:"postgres",kind:"db-query",op:g,...c?{table:c}:{},...k,query:T,...h?{params:h}:{},...W?{result:W}:{},...R,startedAt:p,rows:D,durationMs:l},l>=sql_drops_1.SLOW_QUERY_MS?`db:slow:${v}`:`db:${v}`,M,"cluster",statementGuard)}y==="suppressed"&&(0,sql_drops_1.noteDroppedRun)({sqlId:m,op:g,...c?{table:c}:{},...b?{sqlName:b}:{},...statementSentAt.has(m)?{}:{query:T},durationMs:l,failed:!!o,at:p}),A&&y==="written"&&(0,sql_values_1.keepSqlValues)(A,p,f,x,o?void 0:d?.rows),P&&y==="written"&&(statementSentAt.delete(m),statementSentAt.set(m,p),statementSentAt.size>MAX_SHAPES_REMEMBERED&&statementSentAt.delete(statementSentAt.keys().next().value)),(0,sql_accounting_1.endSqlStatement)(E,{durationMs:l,failed:!!o,emitted:y})},"done"),L=typeof q=="function"?q:typeof i=="function"?i:void 0;if(L){const o=r((d,l)=>{try{$(d,l)}catch{}L(d,l)},"wrappedCb");try{return typeof i=="function"?n.call(this,s,o):n.call(this,s,i,o)}catch(d){throw(0,sql_accounting_1.abandonSqlStatement)(E),d}}let _;try{_=n.call(this,s,i)}catch(o){throw(0,sql_accounting_1.abandonSqlStatement)(E),o}return _&&typeof _.then=="function"?_.then(o=>$(void 0,o),o=>$(o,void 0)):(0,sql_accounting_1.abandonSqlStatement)(E),_},"wrapped");return a.__lensmcp=!0,e.query=a,!0}u(pgTap,"pgTap"),r(pgTap,"pgTap");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/node-instrumentation",
3
- "version": "1.25.42",
3
+ "version": "1.25.44",
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.42",
19
- "@lensmcp/nest-instrumentation": "1.25.42",
20
- "@lensmcp/protocol-types": "1.25.42",
18
+ "@lensmcp/core": "1.25.44",
19
+ "@lensmcp/nest-instrumentation": "1.25.44",
20
+ "@lensmcp/protocol-types": "1.25.44",
21
21
  "tslib": "^2.3.0"
22
22
  },
23
23
  "optionalDependencies": {