@camstack/system 1.2.146 → 1.2.147
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/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/load-series-config.d.ts +74 -0
- package/dist/builtins/native-metrics/load-series-reader.d.ts +37 -0
- package/dist/builtins/native-metrics/load-series-store.d.ts +232 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts +118 -35
- package/dist/builtins/native-metrics/native-metrics.addon.js +1463 -199
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1463 -199
- package/dist/builtins/native-metrics/node-load-ring.d.ts +214 -0
- package/dist/builtins/native-metrics/process-classification.d.ts +51 -0
- package/dist/builtins/native-metrics/thread-cpu-sampler.d.ts +116 -0
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +25 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +2 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-BVU5JADq.js → dist-Dl6MFXPr.js} +496 -35
- package/dist/{dist-CG7kwIZp.mjs → dist-DrBc-7Y3.mjs} +479 -36
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{manifest-python-deps-CVeckyXx.mjs → manifest-python-deps-DhT0oFOZ.mjs} +1 -1
- package/dist/{manifest-python-deps-CktMcXzS.js → manifest-python-deps-FYZBHc3v.js} +1 -1
- package/dist/{retired-settings-keys-_PLI9w0k.js → retired-settings-keys-6w_JOqBg.js} +1 -1
- package/dist/{retired-settings-keys-Dm1z4mO4.mjs → retired-settings-keys-CF5r4YKq.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { ProviderRegistration, BaseAddon } from '@camstack/types';
|
|
2
2
|
interface NativeMetricsConfig {
|
|
3
3
|
readonly samplingIntervalMs: number;
|
|
4
|
+
/**
|
|
5
|
+
* Fixed cadence of the process-tree snapshot, in SECONDS. 5-60, refused
|
|
6
|
+
* outside — `load-series-config.ts` explains why refused and not clamped.
|
|
7
|
+
*/
|
|
8
|
+
readonly loadSeriesCadenceSec: number;
|
|
9
|
+
/** How long the durable series is KEPT, in hours. The intention; the row
|
|
10
|
+
* cap in `load-series-store.ts` is the guarantee. */
|
|
11
|
+
readonly loadSeriesRetentionHours: number;
|
|
4
12
|
}
|
|
5
13
|
/**
|
|
6
14
|
* Native metrics — CPU, memory, disk usage sampling.
|
|
@@ -18,9 +26,88 @@ export default class NativeMetricsAddon extends BaseAddon<NativeMetricsConfig> {
|
|
|
18
26
|
* elapsed) is skipped.
|
|
19
27
|
*/
|
|
20
28
|
private lastResourcesEmit;
|
|
21
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Holds the previous `/proc/<pid>/task/*` tick counts so each process scan
|
|
31
|
+
* can turn them into an instantaneous CPU rate split between the process's
|
|
32
|
+
* own threads and V8's helper pool. Self-bounding — see `ThreadCpuTracker`.
|
|
33
|
+
*/
|
|
34
|
+
private readonly threadCpu;
|
|
35
|
+
/**
|
|
36
|
+
* Retention for the snapshots this addon emits. Fed by SUBSCRIBING to
|
|
37
|
+
* `metrics.node-processes-snapshot`, never by a second sampler — on the hub
|
|
38
|
+
* that bus carries every node, so the hub's ring is the cluster's. Bounds and
|
|
39
|
+
* measured cost live in `node-load-ring.ts`.
|
|
40
|
+
*/
|
|
41
|
+
private readonly loadRing;
|
|
42
|
+
/**
|
|
43
|
+
* The COLD tier, and it exists only on the HUB.
|
|
44
|
+
*
|
|
45
|
+
* The table is hub-resident and the hub already hears every node's snapshot
|
|
46
|
+
* on its bus, so the hub's writer is the cluster's. An agent writing through
|
|
47
|
+
* the `settings-store` singleton would ship its rows over Moleculer, once
|
|
48
|
+
* per sample, to reach that very same table.
|
|
49
|
+
*/
|
|
50
|
+
private loadStore;
|
|
51
|
+
/** The resolved knobs. Re-resolved on every settings write. */
|
|
52
|
+
private loadConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Process rows seen in each node's most recent snapshot — the OBSERVED
|
|
55
|
+
* numbers the settings form projects its cost from. A constant here would be
|
|
56
|
+
* a projection that stops being true the first time the fleet changes.
|
|
57
|
+
*/
|
|
58
|
+
private readonly observedRowsByNode;
|
|
22
59
|
constructor();
|
|
60
|
+
/** Is this the hub? The same test every other addon uses (`addon-ai`). */
|
|
61
|
+
private get isHub();
|
|
62
|
+
/** Process rows observed across the whole fleet, for the cost projection. */
|
|
63
|
+
private observedFleetRows;
|
|
64
|
+
/**
|
|
65
|
+
* Project a `NodeProcess` onto the series' own row.
|
|
66
|
+
*
|
|
67
|
+
* `command`, `ppid`, `pgid`, `nodeId`, `threadCount` and `uptimeSec` are
|
|
68
|
+
* dropped here, at the single point both tiers pass through, so the hot ring
|
|
69
|
+
* and the cold table carry the SAME shape and the merged read cannot tell
|
|
70
|
+
* them apart. `command` in particular is the fattest field in a snapshot and
|
|
71
|
+
* the same identical string on every runner — the runner id travels in the
|
|
72
|
+
* environment, not in argv — and nothing that draws this series reads it.
|
|
73
|
+
*/
|
|
74
|
+
private static toRetained;
|
|
23
75
|
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Retain one arriving snapshot in BOTH tiers.
|
|
78
|
+
*
|
|
79
|
+
* The ring is written FIRST and it is the gate: `record` refuses a timestamp
|
|
80
|
+
* this node has already delivered, and only an accepted sample reaches the
|
|
81
|
+
* table. That is what makes the append idempotent without a unique index
|
|
82
|
+
* over two million rows — the composite key it replaces was measured at ~40
|
|
83
|
+
* bytes per row (`load-series-store.ts`).
|
|
84
|
+
*
|
|
85
|
+
* The durable append is fire-and-forget: a storage stall must cost a gap in
|
|
86
|
+
* the cold window, never a blocked event-bus handler. Every failure logs.
|
|
87
|
+
*/
|
|
88
|
+
private retainSnapshot;
|
|
89
|
+
/**
|
|
90
|
+
* The ONE reader, over both tiers.
|
|
91
|
+
*
|
|
92
|
+
* Cold first, hot second, merged and deduped on `atMs` — see
|
|
93
|
+
* `load-series-reader.ts`. The cold read is bounded in ROWS, because rows
|
|
94
|
+
* are what a query costs, and the fold + reduction happen HERE rather than
|
|
95
|
+
* in the browser: six hours at the 10 s cadence is 2 160 snapshots, and
|
|
96
|
+
* shipping them to a page that will discard most of them is precisely the
|
|
97
|
+
* cost this subsystem exists to avoid.
|
|
98
|
+
*/
|
|
99
|
+
private readLoadSeries;
|
|
100
|
+
/**
|
|
101
|
+
* Re-resolve the knobs and restate the fixed cadence.
|
|
102
|
+
*
|
|
103
|
+
* A REFUSED value (out of 5-60 s, or out of 1-72 h) leaves the previous
|
|
104
|
+
* configuration in force and says so. Refused, never clamped: storing 10
|
|
105
|
+
* when the operator typed 2 and reading 10 back is a knob and a readback
|
|
106
|
+
* agreeing on a value nobody chose.
|
|
107
|
+
*/
|
|
108
|
+
private applyLoadSeriesConfig;
|
|
109
|
+
/** (Re)arm the fixed-cadence process-tree timer at the configured interval. */
|
|
110
|
+
private startProcessSnapshotTimer;
|
|
24
111
|
protected onShutdown(): Promise<void>;
|
|
25
112
|
/**
|
|
26
113
|
* Resolve this node's short id (strips any `nodeId/addonId` suffix).
|
|
@@ -34,10 +121,14 @@ export default class NativeMetricsAddon extends BaseAddon<NativeMetricsConfig> {
|
|
|
34
121
|
*/
|
|
35
122
|
private emitResourcesSnapshot;
|
|
36
123
|
/**
|
|
37
|
-
* Emit one `metrics.node-processes-snapshot` for this node.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
124
|
+
* Emit one `metrics.node-processes-snapshot` for this node.
|
|
125
|
+
*
|
|
126
|
+
* Heavy — a full OS `ps -eo` scan plus a `$process.list` broker call — and
|
|
127
|
+
* UNCONDITIONAL. The change-detection that used to guard it is gone: with a
|
|
128
|
+
* fixed cadence a missing interval means exactly one thing, and that is the
|
|
129
|
+
* property an operator investigating a spike is actually looking for.
|
|
130
|
+
*
|
|
131
|
+
* A failed scan emits nothing, which is the same signal: nobody reported.
|
|
41
132
|
*/
|
|
42
133
|
private emitProcessesSnapshot;
|
|
43
134
|
protected onConfigChanged(): Promise<void>;
|
|
@@ -47,38 +138,12 @@ export default class NativeMetricsAddon extends BaseAddon<NativeMetricsConfig> {
|
|
|
47
138
|
/**
|
|
48
139
|
* Walk the OS process table and classify each camstack-shaped process.
|
|
49
140
|
*
|
|
50
|
-
* Classification
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* - system — ancestry walk crosses a SUPERVISOR_BOUNDARY_RE match
|
|
55
|
-
* (tsx-watch launcher, agent CLI, concurrently, vite,
|
|
56
|
-
* npm exec wrapper). The process belongs to the dev
|
|
57
|
-
* tree even if not in `$process.list`. NEVER killable.
|
|
58
|
-
* - ghost — ancestry walk reaches `ppid=1` without crossing any
|
|
59
|
-
* supervisor boundary AND the parent isn't visible in
|
|
60
|
-
* `ps`. A truly orphaned camstack-shaped process. The
|
|
61
|
-
* ONLY classification that's eligible for kill.
|
|
62
|
-
*
|
|
63
|
-
* Old pattern-only ghost detection produced false positives: every
|
|
64
|
-
* monorepo-path process matched CAMSTACK_CMD_RE, ancestry walk
|
|
65
|
-
* stopping at ppid=hub returned false-positive ghosts whenever a
|
|
66
|
-
* concurrently sibling sat above hub. Ancestry-driven classification
|
|
67
|
-
* fixes that.
|
|
141
|
+
* Classification is IDENTITY-driven: `root` is this pid, `managed` is a pid
|
|
142
|
+
* the kernel's `$process.list` names, and every other camstack-shaped
|
|
143
|
+
* process is `system`. The rules — and why there is no longer an ancestry
|
|
144
|
+
* walk behind them — live in `process-classification.ts`.
|
|
68
145
|
*/
|
|
69
146
|
private listNodeProcesses;
|
|
70
|
-
/**
|
|
71
|
-
* Send SIGTERM / SIGKILL to a pid. Refuses pids that don't appear in
|
|
72
|
-
* `listNodeProcesses()` to prevent arbitrary system kills — a dedicated
|
|
73
|
-
* admin-path for resurrected zombies, not a generic shell replacement.
|
|
74
|
-
*
|
|
75
|
-
* `root`-classified pids (the running launcher / agent CLI / hub itself)
|
|
76
|
-
* are also refused: killing them tears down the whole node and the
|
|
77
|
-
* operator's intent is almost always to nuke a leaked child, not the
|
|
78
|
-
* supervisor that keeps the rest alive. Process restart goes through
|
|
79
|
-
* the dedicated `$process.restart` action, not this kill API.
|
|
80
|
-
*/
|
|
81
|
-
private killProcess;
|
|
82
147
|
/**
|
|
83
148
|
* Ask the addon's forked runner to write a V8 heap snapshot (SIGUSR2 → the
|
|
84
149
|
* runner's diagnostic handler in addon-runner.ts), for deep per-addon memory
|
|
@@ -89,6 +154,24 @@ export default class NativeMetricsAddon extends BaseAddon<NativeMetricsConfig> {
|
|
|
89
154
|
private dumpHeapSnapshot;
|
|
90
155
|
/** Raw `ps` scan returning every pid + command + resource stats. */
|
|
91
156
|
private runPs;
|
|
157
|
+
/**
|
|
158
|
+
* The knobs live HERE, on the document this addon already owns.
|
|
159
|
+
*
|
|
160
|
+
* Fields on an existing document, never a method per knob —
|
|
161
|
+
* `system.getLoggingSettings` / `setLoggingSettings` set that precedent.
|
|
162
|
+
* They are deliberately NOT in the logging document: that one is about
|
|
163
|
+
* levels and diagnostic windows, and two documents both claiming a knob is
|
|
164
|
+
* how this repo has already shipped a switch nobody read.
|
|
165
|
+
*
|
|
166
|
+
* Cluster-wide, not per-node: every node must emit on the same cadence or
|
|
167
|
+
* the fleet's series cannot be laid over each other, and the table is single
|
|
168
|
+
* and hub-resident, so a per-node retention would be a promise nothing could
|
|
169
|
+
* keep.
|
|
170
|
+
*
|
|
171
|
+
* The cost line is computed from OBSERVED numbers — the nodes and process
|
|
172
|
+
* counts the cluster is actually reporting — so an operator raising the
|
|
173
|
+
* retention sees what it costs BEFORE applying it, not afterwards.
|
|
174
|
+
*/
|
|
92
175
|
protected globalSettingsSchema(): import('@camstack/types').ConfigUISchema;
|
|
93
176
|
}
|
|
94
177
|
export {};
|