@lensmcp/cluster 1.16.0 → 1.16.1
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/executors/gateway/runtime/lens-children.d.ts +1 -1
- package/executors/gateway/runtime/lens-children.d.ts.map +1 -1
- package/executors/gateway/runtime/lens-children.js +2 -1
- package/executors/gateway/runtime/observability.d.ts +9 -0
- package/executors/gateway/runtime/observability.d.ts.map +1 -1
- package/executors/gateway/runtime/observability.js +18 -0
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SpawnChild } from '@lensmcp/nx-plugin/lens-frontend';
|
|
2
2
|
import type { GatewayRuntime, GatewayRuntimeOptions } from './types';
|
|
3
|
-
import type
|
|
3
|
+
import { type Observability } from './observability';
|
|
4
4
|
export interface LensChildren {
|
|
5
5
|
spawnManagedChild: SpawnChild;
|
|
6
6
|
/** Boot the dashboard + MCP singletons and every `lens:true` app. Pushes the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAgB,MAAM,SAAS,CAAC;AACnF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAgB,MAAM,SAAS,CAAC;AACnF,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;iFAC6E;IAC7E,qBAAqB,IAAI,IAAI,CAAC;IAC9B,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CA0HvH"}
|
|
@@ -11,6 +11,7 @@ const node_child_process_1 = require("node:child_process");
|
|
|
11
11
|
const manifest_1 = require("../manifest");
|
|
12
12
|
const lens_frontend_1 = require("@lensmcp/nx-plugin/lens-frontend");
|
|
13
13
|
const scope_1 = require("./scope");
|
|
14
|
+
const observability_1 = require("./observability");
|
|
14
15
|
const HEAL_BASE_MS = 1_500; // first restart delay
|
|
15
16
|
const HEAL_MAX_MS = 30_000; // backoff cap — a true boot-loop settles here, never hot-loops
|
|
16
17
|
const HEAL_HEALTHY_MS = 20_000; // ran at least this long ⇒ a FRESH crash ⇒ reset the backoff budget
|
|
@@ -72,7 +73,7 @@ function createLensChildren(rt, obs, options) {
|
|
|
72
73
|
const lensBase = scope.basePath; // e.g. /tetros
|
|
73
74
|
// Pushed BEFORE the cert SANs are derived (routes.map(r=>r.host)), so lensmcp.local
|
|
74
75
|
// auto-joins the TLS SANs. Run `gateway:trust` to add it to /etc/hosts.
|
|
75
|
-
rt.routes.push({ host: lensHost, prefix: lensBase, project:
|
|
76
|
+
rt.routes.push({ host: lensHost, prefix: lensBase, project: observability_1.LENS_DASHBOARD_PROJECT, target: `http://localhost:${dashboardPort}` });
|
|
76
77
|
(0, manifest_1.sortBySpecificity)(rt.routes);
|
|
77
78
|
console.log(`[gateway] starting lens dashboard → http://localhost:${dashboardPort} (routed at https://${lensHost}${lensBase}/)`);
|
|
78
79
|
emit('info', `lens dashboard up: ${lensHost}${lensBase} → :${dashboardPort}`, 'cluster-lens-dashboard', { kind: 'lens-dashboard-up', host: lensHost, port: dashboardPort, base: lensBase });
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type * as http from 'node:http';
|
|
2
2
|
import type { GwTrace, Route } from './types';
|
|
3
3
|
export type Severity = 'info' | 'warning' | 'error';
|
|
4
|
+
/**
|
|
5
|
+
* The lens's OWN dashboard route project (the value `lens-children.ts` gives the `lensmcp.local/<key>/`
|
|
6
|
+
* route). Traffic to it is the lens UI polling its own control-plane API (`/<key>/api/cluster|logs|snapshot`)
|
|
7
|
+
* ~1×/s — pure self-observation with NO app-diagnostic value. Its SUCCESSFUL request narration + traffic
|
|
8
|
+
* edges are suppressed from the bus (the same "don't bloat the bus" rationale as header-less traffic); a 5xx
|
|
9
|
+
* still surfaces so a genuine lens-dashboard failure isn't hidden. One home for the literal (imported by
|
|
10
|
+
* `lens-children.ts` for the route + this layer for the filter, so they can't drift).
|
|
11
|
+
*/
|
|
12
|
+
export declare const LENS_DASHBOARD_PROJECT = "(lens-dashboard)";
|
|
4
13
|
export interface Observability {
|
|
5
14
|
emit(severity: Severity, title: string, fingerprint: string, raw?: Record<string, unknown>, flowCtx?: Record<string, unknown>): void;
|
|
6
15
|
eid(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/observability.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrI,GAAG,IAAI,MAAM,CAAC;IACd,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3D,SAAS,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1F,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5G,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,0FAA0F;IAC1F,gBAAgB,IAAI,MAAM,CAAC,OAAO,CAAC;CACpC;AAKD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/observability.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrI,GAAG,IAAI,MAAM,CAAC;IACd,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3D,SAAS,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1F,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5G,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,0FAA0F;IAC1F,gBAAgB,IAAI,MAAM,CAAC,OAAO,CAAC;CACpC;AAKD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAmGtG"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LENS_DASHBOARD_PROJECT = void 0;
|
|
3
4
|
exports.createObservability = createObservability;
|
|
4
5
|
const tslib_1 = require("tslib");
|
|
5
6
|
/**
|
|
@@ -16,6 +17,15 @@ const tslib_1 = require("tslib");
|
|
|
16
17
|
*/
|
|
17
18
|
const fs = tslib_1.__importStar(require("node:fs"));
|
|
18
19
|
const path = tslib_1.__importStar(require("node:path"));
|
|
20
|
+
/**
|
|
21
|
+
* The lens's OWN dashboard route project (the value `lens-children.ts` gives the `lensmcp.local/<key>/`
|
|
22
|
+
* route). Traffic to it is the lens UI polling its own control-plane API (`/<key>/api/cluster|logs|snapshot`)
|
|
23
|
+
* ~1×/s — pure self-observation with NO app-diagnostic value. Its SUCCESSFUL request narration + traffic
|
|
24
|
+
* edges are suppressed from the bus (the same "don't bloat the bus" rationale as header-less traffic); a 5xx
|
|
25
|
+
* still surfaces so a genuine lens-dashboard failure isn't hidden. One home for the literal (imported by
|
|
26
|
+
* `lens-children.ts` for the route + this layer for the filter, so they can't drift).
|
|
27
|
+
*/
|
|
28
|
+
exports.LENS_DASHBOARD_PROJECT = '(lens-dashboard)';
|
|
19
29
|
const hdr = (v) => typeof v === 'string' && v !== '' ? v : Array.isArray(v) ? v[0] : undefined;
|
|
20
30
|
function createObservability(eventFile, opts) {
|
|
21
31
|
const eid = () => Date.now().toString(36) + Math.random().toString(36).slice(2, 12);
|
|
@@ -69,6 +79,10 @@ function createObservability(eventFile, opts) {
|
|
|
69
79
|
if (!t || t.done)
|
|
70
80
|
return;
|
|
71
81
|
t.done = true;
|
|
82
|
+
// The lens dashboard's own control-plane self-polling (1 req/s) would spam the bus with no
|
|
83
|
+
// app-diagnostic value — suppress its successful narration, but let a 5xx through (a real lens bug).
|
|
84
|
+
if (project === exports.LENS_DASHBOARD_PROJECT && status < 500)
|
|
85
|
+
return;
|
|
72
86
|
const durationMs = Date.now() - t.startedAt;
|
|
73
87
|
emit(status >= 500 ? 'error' : 'info', `gateway ${t.method} ${t.host}${t.url} → ${status} (${durationMs}ms)`, `gateway-request:${project}`, {
|
|
74
88
|
kind: 'gateway-request', project, host: t.host, method: t.method, url: t.url,
|
|
@@ -83,6 +97,10 @@ function createObservability(eventFile, opts) {
|
|
|
83
97
|
// The request-derived topology (nodes/edges appear from observed traffic).
|
|
84
98
|
const edges = new Map();
|
|
85
99
|
const recordEdge = (route, ms, status, caller) => {
|
|
100
|
+
// Don't accumulate a traffic edge for the lens dashboard's own self-polling (kills the
|
|
101
|
+
// `traffic lensmcp.local → (lens-dashboard)` spam); an error edge (5xx / connect-fail) still records.
|
|
102
|
+
if (route.project === exports.LENS_DASHBOARD_PROJECT && status < 500 && status !== 0)
|
|
103
|
+
return;
|
|
86
104
|
const host = route.host ?? '(default)';
|
|
87
105
|
const key = (caller ? caller + '⇒' : '') + host + '→' + route.project;
|
|
88
106
|
const e = edges.get(key) ?? { host, project: route.project, caller, count: 0, totalMs: 0, errors: 0 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/cluster",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"description": "Run your Nx workspace as a local production cluster: pods on unix sockets with true HMR, one https gateway with per-project domains, scale-from-zero, autoscale, idle-kill, local-CA TLS — observed by the LensMCP lens.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@lensmcp/node-instrumentation": "1.16.
|
|
69
|
-
"@lensmcp/nx-plugin": "1.16.
|
|
68
|
+
"@lensmcp/node-instrumentation": "1.16.1",
|
|
69
|
+
"@lensmcp/nx-plugin": "1.16.1",
|
|
70
70
|
"fork-ts-checker-webpack-plugin": "^9.0.0",
|
|
71
71
|
"glob": "^11.0.0",
|
|
72
72
|
"http-proxy": "^1.18.0",
|