rigscope 0.1.0 → 0.1.2
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +2 -2
- package/.next/build-manifest.json +2 -2
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/administration/page_client-reference-manifest.js +1 -1
- package/.next/server/app/administration.html +1 -1
- package/.next/server/app/administration.rsc +2 -2
- package/.next/server/app/administration.segments/_full.segment.rsc +2 -2
- package/.next/server/app/administration.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/administration.segments/administration/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/alerts/page_client-reference-manifest.js +1 -1
- package/.next/server/app/alerts.html +1 -1
- package/.next/server/app/alerts.rsc +2 -2
- package/.next/server/app/alerts.segments/_full.segment.rsc +2 -2
- package/.next/server/app/alerts.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/alerts.segments/alerts/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/connections/page_client-reference-manifest.js +1 -1
- package/.next/server/app/connections.html +1 -1
- package/.next/server/app/connections.rsc +2 -2
- package/.next/server/app/connections.segments/_full.segment.rsc +2 -2
- package/.next/server/app/connections.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/connections.segments/connections/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/history/page.js +2 -2
- package/.next/server/app/history/page_client-reference-manifest.js +1 -1
- package/.next/server/app/history.html +1 -1
- package/.next/server/app/history.rsc +5 -5
- package/.next/server/app/history.segments/_full.segment.rsc +5 -5
- package/.next/server/app/history.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/history.segments/history/__PAGE__.segment.rsc +5 -5
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +2 -2
- package/.next/server/app/login.segments/_full.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/machines/[machineId]/page.js +1 -1
- package/.next/server/app/machines/[machineId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/processes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/processes.html +1 -1
- package/.next/server/app/processes.rsc +2 -2
- package/.next/server/app/processes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/processes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/processes.segments/processes/__PAGE__.segment.rsc +2 -2
- package/.next/server/app-paths-manifest.json +2 -2
- package/.next/server/chunks/168.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/408-4fe7147e38981ee1.js +1 -0
- package/.next/static/chunks/app/history/page-22be927a4c3a9c76.js +3 -0
- package/.next/static/chunks/app/machines/[machineId]/page-916ee73de5eb067d.js +1 -0
- package/.next/static/css/3fbf75e4c471c6a8.css +1 -0
- package/CHANGELOG.md +27 -0
- package/README.md +53 -136
- package/dist/collector.cjs +9 -1
- package/dist/hub.cjs +14 -5
- package/dist/ops.cjs +8 -4
- package/docs/bottlenecks.md +1 -1
- package/docs/configuration.md +85 -0
- package/docs/development.md +1 -1
- package/docs/installation.md +205 -376
- package/docs/monitoring.md +112 -0
- package/docs/operations.md +103 -68
- package/docs/releasing.md +16 -14
- package/docs/scale-validation.md +34 -3
- package/docs/stress-2026-11-04/180301-probe-m100-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180335-probe-m200-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180409-probe-m400-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180443-probe-m800-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180518-probe-m600-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180553-probe-m500-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180628-probe-m550-u1-s1-20000ms.json +412 -0
- package/docs/stress-2026-11-04/180716-probe-m800-u1-s0-20000ms.json +415 -0
- package/docs/stress-2026-11-04/180751-probe-m1600-u1-s0-20000ms.json +415 -0
- package/docs/stress-2026-11-04/180828-probe-m3200-u1-s0-20000ms.json +416 -0
- package/docs/stress-2026-11-04/180941-probe-m2400-u1-s0-20000ms.json +416 -0
- package/docs/stress-2026-11-04/181031-probe-m2000-u1-s0-20000ms.json +416 -0
- package/docs/stress-2026-11-04/181114-probe-m1800-u1-s0-20000ms.json +416 -0
- package/docs/stress-2026-11-04/181203-probe-m100-u64-s64-20000ms.json +418 -0
- package/docs/stress-2026-11-04/181304-probe-m200-u64-s64-20000ms.json +418 -0
- package/docs/stress-2026-11-04/181405-probe-m400-u64-s64-20000ms.json +418 -0
- package/docs/stress-2026-11-04/181507-probe-m500-u64-s64-20000ms.json +418 -0
- package/docs/stress-2026-11-04/181609-probe-m450-u64-s64-20000ms.json +418 -0
- package/docs/stress-2026-11-04/181845-probe-m2-u2-s2-3000ms.json +419 -0
- package/docs/stress-2026-11-04/181931-probe-m500-u64-s64-30000ms.json +420 -0
- package/docs/stress-2026-11-04/182108-probe-m1800-u1-s0-120000ms.json +418 -0
- package/docs/stress-2026-11-04/182354-probe-m1200-u1-s0-120000ms.json +418 -0
- package/docs/stress-2026-11-04/182625-probe-m900-u1-s0-120000ms.json +418 -0
- package/docs/stress-2026-11-04/182847-probe-m1050-u1-s0-120000ms.json +418 -0
- package/docs/stress-2026-11-04/183112-probe-m1125-u1-s0-120000ms.json +418 -0
- package/docs/stress-2026-11-04/193608-probe-m500-u64-s64-120000ms.json +420 -0
- package/docs/stress-2026-11-04/193909-probe-m529-u1-s1-15000ms.json +420 -0
- package/docs/stress-2026-11-04/193940-probe-m530-u1-s1-15000ms.json +420 -0
- package/docs/stress-2026-11-04/194011-probe-m100-u1-s65-10000ms.json +421 -0
- package/docs/stress-2026-11-04/README.md +205 -0
- package/docs/stress-2026-11-04/index.jsonl +29 -0
- package/docs/stress-2026-11-04/manifest.json +13 -0
- package/docs/stress-2026-11-04/results.html +22 -0
- package/docs/system-installation.md +195 -0
- package/package.json +9 -1
- package/packaging/system/README.md +1 -1
- package/.next/static/chunks/408-18819c6490a5f8d3.js +0 -1
- package/.next/static/chunks/app/history/page-3fa5846eca26b7f7.js +0 -3
- package/.next/static/chunks/app/machines/[machineId]/page-a5aa1d8676272f38.js +0 -1
- package/.next/static/css/e41ccbccc3afaae5.css +0 -1
- /package/.next/static/{DZKWF9ur7H5wI0c7RAhdq → npHoP6NSY976Yaye-xi86}/_buildManifest.js +0 -0
- /package/.next/static/{DZKWF9ur7H5wI0c7RAhdq → npHoP6NSY976Yaye-xi86}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -1,158 +1,75 @@
|
|
|
1
1
|
# Rigscope
|
|
2
2
|
|
|
3
|
-
Your machines, in view. A self-hosted Linux system and process monitor
|
|
3
|
+
Your machines, in view. A self-hosted Linux system and process monitor.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
View CPU, memory, GPU, disk and network readings, browse History, inspect running
|
|
6
|
+
processes and set alerts. Run a hub for the dashboard and a collector on each
|
|
7
|
+
machine you want to monitor. The default installation runs both on this computer.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Requires **Linux, Node.js 26+ with npm, and systemd** for background services.
|
|
6
12
|
|
|
7
13
|
```sh
|
|
8
14
|
npx --yes rigscope@latest install --boot
|
|
9
|
-
~/.local/bin/rigscope
|
|
10
15
|
```
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
Save the generated `owner` password and open the printed dashboard URL
|
|
18
|
+
(normally `http://127.0.0.1:8081`). The services keep running after you close the
|
|
19
|
+
terminal. `--boot` starts them at boot; omit it to start at login instead.
|
|
20
|
+
|
|
21
|
+
Add `~/.local/bin` to PATH to use `rigscope`. You can also run
|
|
22
|
+
`~/.local/bin/rigscope` directly. No global npm install or source checkout is needed.
|
|
13
23
|
|
|
14
|
-
|
|
24
|
+
To try Rigscope in the terminal before installing services:
|
|
15
25
|
|
|
16
26
|
```sh
|
|
17
|
-
rigscope
|
|
18
|
-
rigscope logs hub
|
|
19
|
-
rigscope stop collector
|
|
20
|
-
rigscope start collector
|
|
21
|
-
rigscope upgrade
|
|
22
|
-
rigscope rollback
|
|
27
|
+
npx --yes rigscope@latest try
|
|
23
28
|
```
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
The trial uses separate data and stops with Ctrl+C.
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
## Use it
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
| Task | Command or guide |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| Check services and the dashboard URL | `rigscope status` |
|
|
37
|
+
| Follow hub logs | `rigscope logs hub --follow` |
|
|
38
|
+
| Upgrade from npm | `rigscope upgrade` |
|
|
39
|
+
| Stop or start the installation | `rigscope stop` / `rigscope start` |
|
|
40
|
+
| Open the dashboard through Tailscale HTTPS | [Set up remote access](docs/installation.md#access-from-another-computer) |
|
|
41
|
+
| Monitor another machine | [Add a collector](docs/installation.md#add-machines-and-hubs) |
|
|
42
|
+
| Install a downloaded package | [Install from an archive](docs/installation.md#install-from-an-archive) |
|
|
30
43
|
|
|
31
|
-
|
|
44
|
+
Each collector connects outbound to up to eight hubs. Each hub has its own users,
|
|
45
|
+
permissions, history and alerts. Collectors need no incoming ports.
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
## What to expect
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
Rigscope is read-only: it does not kill processes, change priorities or control
|
|
50
|
+
services on monitored machines. Missing sensor readings stay unavailable.
|
|
51
|
+
NVIDIA and available AMD GPU counters are supported; Intel GPU readings are
|
|
52
|
+
partial. See the [hardware notes](docs/installation.md#hardware).
|
|
36
53
|
|
|
37
|
-
|
|
38
|
-
[
|
|
39
|
-
|
|
40
|
-
your shell does not reconfigure a managed service.
|
|
54
|
+
History is stored in SQLite. Process details are fetched while you view them and
|
|
55
|
+
are never saved to History. See [Monitoring and alerts](docs/monitoring.md) for
|
|
56
|
+
retention, sharing, freshness and notification behavior.
|
|
41
57
|
|
|
42
|
-
|
|
58
|
+
## Documentation
|
|
43
59
|
|
|
44
|
-
|
|
|
45
|
-
| --- | --- |
|
|
46
|
-
| `HUB_HOST`, `HUB_PORT` | Loopback-only listener; defaults `127.0.0.1:8081`. Port `0` is useful for isolated tests. |
|
|
47
|
-
| `HUB_PUBLIC_ORIGIN`, `HUB_SOCKET_PATH` | Required together for remote mode. Exact HTTPS origin and private absolute Unix socket. No TCP listener in this mode. |
|
|
48
|
-
| `HUB_DATABASE_PATH` | Authoritative SQLite telemetry/users/alerts/collector registry. Defaults beside `HUB_STATE_FILE`, otherwise `$XDG_STATE_HOME/rigscope/hub/telemetry.sqlite` (falling back to `~/.local/state`). |
|
|
49
|
-
| `HUB_BROWSER_USERS` | First-run bootstrap JSON: `{username,passwordHash,machineIds,admin?}`. Scope is `"*"` or a machine-ID array; `[]` grants no machine access. |
|
|
50
|
-
| `HUB_ADMIN_USERS` | Comma-separated usernames explicitly elevated during first import. When absent, an existing bootstrap account named `owner` is migrated as administrator. Other users need an explicit `admin:true`. |
|
|
51
|
-
| `HUB_COLLECTORS` | First-run bootstrap JSON: `{collectorId,machineId,token}`; bounded by JSON bytes rather than machine count. Credentials travel only in bearer headers. |
|
|
52
|
-
| `HUB_MAX_COLLECTOR_CONNECTIONS` | Concurrent collector socket budget; defaults to 100. Positive integer; tune to measured deployment capacity. |
|
|
53
|
-
| `HUB_STATE_FILE` | Private enrollment-file import source for existing installations; enables the enrollment endpoint. Preserve it with deployment configuration for recovery. |
|
|
54
|
-
| `HUB_ENROLLMENT_GRANTS` | Bootstrap grants `{token,expiresAt}`; at most 15 minutes. Consumed grants remain consumed across migration/restart. |
|
|
55
|
-
|
|
56
|
-
From a source checkout, generate salted scrypt hashes with
|
|
57
|
-
`scripts/hash-browser-password.cjs`, which reads passwords from stdin. Managed
|
|
58
|
-
installation generates the initial account automatically. Keep hashes private. The database imports existing
|
|
59
|
-
users/credentials once; later configuration restarts do not overwrite managed users
|
|
60
|
-
or resurrect revoked credentials. Administration changes apply to active sessions
|
|
61
|
-
and collector connections. Existing owner passwords and scopes are preserved.
|
|
62
|
-
|
|
63
|
-
| Collector variable | Behavior |
|
|
60
|
+
| Guide | Covers |
|
|
64
61
|
| --- | --- |
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
## Source enrollment, rotation and replacement
|
|
80
|
-
|
|
81
|
-
For a managed installation, use `rigscope connect` as described in
|
|
82
|
-
[Add machines and hubs](docs/installation.md#add-machines-and-hubs). The following
|
|
83
|
-
commands require a source checkout with development dependencies installed.
|
|
84
|
-
|
|
85
|
-
Create a short-lived grant through an authorized administration flow. On the machine,
|
|
86
|
-
set `COLLECTOR_ENROLL_URL` to its full `ws[s]://…/api/collector/connect` URL and
|
|
87
|
-
`COLLECTOR_ENROLL_TOKEN` privately, then run:
|
|
88
|
-
|
|
89
|
-
```sh
|
|
90
|
-
npm run collector:enroll
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
The collector saves a random recovery proof before requesting a credential. A retry
|
|
94
|
-
after a lost successful response recovers the same credential using that proof;
|
|
95
|
-
collector ID or hostname alone is insufficient. Restart the collector to apply changes.
|
|
96
|
-
|
|
97
|
-
Rotation/replacement requires a grant explicitly bound to the existing hub-local
|
|
98
|
-
machine mapping. Use `npm run collector:enroll -- --replace-enrollment` to replace a
|
|
99
|
-
saved destination. Revocation invalidates open connections and old recovery proofs.
|
|
100
|
-
Replacement never matches a machine by hostname or address.
|
|
101
|
-
|
|
102
|
-
## Monitoring behavior and bounds
|
|
103
|
-
|
|
104
|
-
- Samples are acknowledged only after a durable SQLite commit. Retries deduplicate
|
|
105
|
-
by collector/run/sequence. Replay fills History without replacing live state or
|
|
106
|
-
triggering historical threshold incidents.
|
|
107
|
-
- Per-destination outboxes retain pending metrics across collector restart, prioritize
|
|
108
|
-
live telemetry, and bound replay/in-flight work. Defaults: ten minutes or 64 MiB
|
|
109
|
-
of queued JSON per destination, 256 MiB aggregate queued JSON. Separate physical
|
|
110
|
-
budgets count main database files plus WAL: 80 MiB per destination and 640 MiB
|
|
111
|
-
across eight destinations. SQLite page caps, bounded writes, checkpoints and
|
|
112
|
-
pressure rejection enforce these budgets; they are not OS filesystem quotas.
|
|
113
|
-
- History defaults: raw 48 hours, one-minute rollups 30 days, one-hour rollups 400 days.
|
|
114
|
-
Rollups preserve minima/maxima. Queries have point, series, scanned-row and elapsed
|
|
115
|
-
budgets; partial results are disclosed. The hub defaults to a 2 GiB physical
|
|
116
|
-
database/WAL budget shared by telemetry, users, enrollment and alerts. Retention
|
|
117
|
-
protects the newest hour; when it cannot reclaim enough space, ingestion returns
|
|
118
|
-
busy without acknowledging records. Existing oversized databases enter pressure
|
|
119
|
-
mode; they are not destructively vacuumed at startup. Atomic writes may briefly
|
|
120
|
-
grow WAL before checkpointing; blocked checkpoints surface pressure and stop
|
|
121
|
-
subsequent ingestion rather than permitting continued growth.
|
|
122
|
-
- Receipt freshness is `max(15 seconds, 3 × expected delivery interval)`. Unknown cadence
|
|
123
|
-
uses a disclosed 15-second fallback. Connection state, collection availability and
|
|
124
|
-
clock skew remain separate. Browser/hub clocks are not calibrated.
|
|
125
|
-
- Process detail uses renewable viewer interests and one shared collector scan. Pausing,
|
|
126
|
-
hiding/closing a view, session termination or lease expiry releases extra work.
|
|
127
|
-
Process detail is never persisted. CPU is 100% per core; machine CPU is normalized
|
|
128
|
-
across logical cores. Missing/inaccessible readings remain unavailable.
|
|
129
|
-
- User sessions are in memory with a fixed twelve-hour lifetime; a hub restart requires
|
|
130
|
-
signing in again. Users/scopes/password hashes and collector credentials persist.
|
|
131
|
-
- Physical checks cover the Ubuntu RTX 3090 rig and the laptop’s RTX 5060 plus Radeon
|
|
132
|
-
860M iGPU. Intel sensor and ARM/RISC-V naming paths have deterministic fixture coverage;
|
|
133
|
-
physical validation for those paths remains outstanding. See the [hardware support notes](docs/installation.md#hardware).
|
|
134
|
-
- There is no fixed machine-count limit. The default concurrent collector connection
|
|
135
|
-
budget is 100; [scale validation](docs/scale-validation.md) records synthetic
|
|
136
|
-
workloads up to 75 machines on one host and is not a capacity guarantee.
|
|
137
|
-
Remote kill/renice, service control, hub federation and clustering are out
|
|
138
|
-
of scope for this read-only release.
|
|
139
|
-
|
|
140
|
-
## Alerts and administration
|
|
141
|
-
|
|
142
|
-
Administration requires an explicit administrator role as well as machine scope.
|
|
143
|
-
Use it to manage accounts/scopes, display names/tags, collector revocation and
|
|
144
|
-
short-lived enrollment/replacement grants. User changes revoke existing browser
|
|
145
|
-
sessions; credential changes close invalid collector connections. Wildcard scope
|
|
146
|
-
alone does not grant administration.
|
|
147
|
-
|
|
148
|
-
Alerts support above/below thresholds, duration, unavailable readings, missing
|
|
149
|
-
receipts, maintenance and recovery. Value, unavailable and stale-receipt rules
|
|
150
|
-
apply to every machine the hub tracks. Replay never opens historical incidents.
|
|
151
|
-
Configure one HTTPS webhook channel in Alerts (loopback HTTP only for controlled
|
|
152
|
-
test sinks). URL, headers and HMAC secret are write-only. Delivery is at-least-once:
|
|
153
|
-
receivers should deduplicate the `Idempotency-Key`. Six attempts, a five-second
|
|
154
|
-
request deadline and bounded persistent queues prevent unbounded delivery work.
|
|
155
|
-
|
|
156
|
-
See [operations](docs/operations.md) for packaging, private service configuration,
|
|
157
|
-
boot enablement, backups, tested restores, upgrades/rollback and measurements.
|
|
158
|
-
The managed installer starts services by default; low-level archive tools print service commands for explicit execution.
|
|
62
|
+
| [Installation](docs/installation.md) | npm, HTTPS, collectors, upgrades and hardware |
|
|
63
|
+
| [Operations](docs/operations.md) | Diagnostics, backups, recovery and archive deployment |
|
|
64
|
+
| [System installation](docs/system-installation.md) | Dedicated service accounts and system units |
|
|
65
|
+
| [Configuration reference](docs/configuration.md) | Environment variables and source enrollment |
|
|
66
|
+
| [Monitoring and alerts](docs/monitoring.md) | Data limits, sharing, users and webhooks |
|
|
67
|
+
| [Sensor readings](docs/bottlenecks.md) / [Exports](docs/exports.md) | Reading meanings and downloads |
|
|
68
|
+
| [Development](docs/development.md) / [Architecture](ARCHITECTURE.md) / [Design](DESIGN.md) | Source setup and implementation references |
|
|
69
|
+
| [Releasing](docs/releasing.md) / [Release notes](CHANGELOG.md) | Publishing checks and version changes |
|
|
70
|
+
| [Scale validation](docs/scale-validation.md) | Synthetic measurements on one host; no capacity guarantee |
|
|
71
|
+
|
|
72
|
+
Published on [npm](https://www.npmjs.com/package/rigscope).
|
|
73
|
+
Maintained by [Triet (@Triet1402)](https://github.com/Triet1402).
|
|
74
|
+
Licensed under [MIT](LICENSE); see [dependency notices](THIRD_PARTY_NOTICES.md).
|
|
75
|
+
Report vulnerabilities privately using [SECURITY.md](SECURITY.md).
|
package/dist/collector.cjs
CHANGED
|
@@ -5292,7 +5292,7 @@ function budget(value, fallback) {
|
|
|
5292
5292
|
// package.json
|
|
5293
5293
|
var package_default = {
|
|
5294
5294
|
name: "rigscope",
|
|
5295
|
-
version: "0.1.
|
|
5295
|
+
version: "0.1.2",
|
|
5296
5296
|
rigscopeConfigVersion: 2,
|
|
5297
5297
|
private: false,
|
|
5298
5298
|
engines: {
|
|
@@ -5360,6 +5360,9 @@ var package_default = {
|
|
|
5360
5360
|
"README.md",
|
|
5361
5361
|
"CHANGELOG.md",
|
|
5362
5362
|
"docs/installation.md",
|
|
5363
|
+
"docs/system-installation.md",
|
|
5364
|
+
"docs/configuration.md",
|
|
5365
|
+
"docs/monitoring.md",
|
|
5363
5366
|
"docs/operations.md",
|
|
5364
5367
|
"docs/bottlenecks.md",
|
|
5365
5368
|
"docs/exports.md",
|
|
@@ -5368,6 +5371,11 @@ var package_default = {
|
|
|
5368
5371
|
"docs/scale-validation.md",
|
|
5369
5372
|
"docs/scale-validation.json",
|
|
5370
5373
|
"docs/scale-acceptance.json",
|
|
5374
|
+
"docs/stress-2026-11-04/README.md",
|
|
5375
|
+
"docs/stress-2026-11-04/index.jsonl",
|
|
5376
|
+
"docs/stress-2026-11-04/manifest.json",
|
|
5377
|
+
"docs/stress-2026-11-04/results.html",
|
|
5378
|
+
"docs/stress-2026-11-04/*ms.json",
|
|
5371
5379
|
"ARCHITECTURE.md",
|
|
5372
5380
|
"DESIGN.md",
|
|
5373
5381
|
"LICENSE",
|
package/dist/hub.cjs
CHANGED
|
@@ -1741,7 +1741,7 @@ function describeError(error) {
|
|
|
1741
1741
|
// package.json
|
|
1742
1742
|
var package_default = {
|
|
1743
1743
|
name: "rigscope",
|
|
1744
|
-
version: "0.1.
|
|
1744
|
+
version: "0.1.2",
|
|
1745
1745
|
rigscopeConfigVersion: 2,
|
|
1746
1746
|
private: false,
|
|
1747
1747
|
engines: {
|
|
@@ -1809,6 +1809,9 @@ var package_default = {
|
|
|
1809
1809
|
"README.md",
|
|
1810
1810
|
"CHANGELOG.md",
|
|
1811
1811
|
"docs/installation.md",
|
|
1812
|
+
"docs/system-installation.md",
|
|
1813
|
+
"docs/configuration.md",
|
|
1814
|
+
"docs/monitoring.md",
|
|
1812
1815
|
"docs/operations.md",
|
|
1813
1816
|
"docs/bottlenecks.md",
|
|
1814
1817
|
"docs/exports.md",
|
|
@@ -1817,6 +1820,11 @@ var package_default = {
|
|
|
1817
1820
|
"docs/scale-validation.md",
|
|
1818
1821
|
"docs/scale-validation.json",
|
|
1819
1822
|
"docs/scale-acceptance.json",
|
|
1823
|
+
"docs/stress-2026-11-04/README.md",
|
|
1824
|
+
"docs/stress-2026-11-04/index.jsonl",
|
|
1825
|
+
"docs/stress-2026-11-04/manifest.json",
|
|
1826
|
+
"docs/stress-2026-11-04/results.html",
|
|
1827
|
+
"docs/stress-2026-11-04/*ms.json",
|
|
1820
1828
|
"ARCHITECTURE.md",
|
|
1821
1829
|
"DESIGN.md",
|
|
1822
1830
|
"LICENSE",
|
|
@@ -4054,7 +4062,8 @@ function queryHistory(db, q, budget = {}) {
|
|
|
4054
4062
|
seriesRows = seriesRows.slice(0, Math.max(0, chosen.cutSeries));
|
|
4055
4063
|
truncated = true;
|
|
4056
4064
|
}
|
|
4057
|
-
const stepMs = Math.max(
|
|
4065
|
+
const stepMs = Math.max(1, Math.ceil(rangeMs / maxPoints / chosen.resolutionMs)) * chosen.resolutionMs;
|
|
4066
|
+
const originMs = Math.floor(q.fromMs / stepMs) * stepMs;
|
|
4058
4067
|
const series = [];
|
|
4059
4068
|
for (const row of seriesRows) {
|
|
4060
4069
|
if (performance.now() - started > maxElapsedMs) {
|
|
@@ -4070,7 +4079,7 @@ function queryHistory(db, q, budget = {}) {
|
|
|
4070
4079
|
Number(row.series_id),
|
|
4071
4080
|
fromBucketMs(chosen.tier, q.fromMs),
|
|
4072
4081
|
q.toMs,
|
|
4073
|
-
|
|
4082
|
+
originMs,
|
|
4074
4083
|
stepMs,
|
|
4075
4084
|
// An additional per-series guard. Tier selection already keeps the total
|
|
4076
4085
|
// under budget; this makes a single query bounded even if a custom
|
|
@@ -4236,8 +4245,8 @@ function readGaps(db, machineId, fromMs, toMs) {
|
|
|
4236
4245
|
"SELECT from_ms, to_ms, dropped, reason FROM gaps WHERE machine_id = ? AND to_ms >= ? AND from_ms <= ? ORDER BY from_ms LIMIT ?"
|
|
4237
4246
|
).all(machineId, fromMs, toMs, MAX_GAPS);
|
|
4238
4247
|
const missing = db.db.prepare(
|
|
4239
|
-
"WITH
|
|
4240
|
-
).all(machineId, fromMs, toMs, MAX_GAPS);
|
|
4248
|
+
"WITH before_window AS ( SELECT captured_at_ms, expected_interval_ms FROM sample_receipts WHERE machine_id = ? AND captured_at_ms < ? ORDER BY captured_at_ms DESC LIMIT 1 ), in_window AS ( SELECT captured_at_ms, expected_interval_ms FROM sample_receipts WHERE machine_id = ? AND captured_at_ms >= ? AND captured_at_ms <= ? ), ordered AS ( SELECT captured_at_ms, expected_interval_ms, LAG(captured_at_ms) OVER (ORDER BY captured_at_ms) AS prev_ms FROM (SELECT * FROM before_window UNION ALL SELECT * FROM in_window) ) SELECT MAX(prev_ms, ?) AS from_ms, captured_at_ms AS to_ms FROM ordered WHERE prev_ms IS NOT NULL AND captured_at_ms > ? AND captured_at_ms - prev_ms > MAX(15000, 3 * COALESCE(expected_interval_ms, 5000)) ORDER BY captured_at_ms LIMIT ?"
|
|
4249
|
+
).all(machineId, fromMs, machineId, fromMs, toMs, fromMs, fromMs, MAX_GAPS);
|
|
4241
4250
|
const gaps = [
|
|
4242
4251
|
...dropped.map((row) => ({
|
|
4243
4252
|
fromMs: Number(row.from_ms),
|
package/dist/ops.cjs
CHANGED
|
@@ -1559,6 +1559,9 @@ var PACKAGE_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
1559
1559
|
]);
|
|
1560
1560
|
var PACKAGE_DOCS = /* @__PURE__ */ new Set([
|
|
1561
1561
|
"docs/installation.md",
|
|
1562
|
+
"docs/system-installation.md",
|
|
1563
|
+
"docs/configuration.md",
|
|
1564
|
+
"docs/monitoring.md",
|
|
1562
1565
|
"docs/operations.md",
|
|
1563
1566
|
"docs/development.md",
|
|
1564
1567
|
"docs/releasing.md",
|
|
@@ -4080,7 +4083,8 @@ function queryHistory(db, q, budget = {}) {
|
|
|
4080
4083
|
seriesRows = seriesRows.slice(0, Math.max(0, chosen.cutSeries));
|
|
4081
4084
|
truncated = true;
|
|
4082
4085
|
}
|
|
4083
|
-
const stepMs = Math.max(
|
|
4086
|
+
const stepMs = Math.max(1, Math.ceil(rangeMs / maxPoints / chosen.resolutionMs)) * chosen.resolutionMs;
|
|
4087
|
+
const originMs = Math.floor(q.fromMs / stepMs) * stepMs;
|
|
4084
4088
|
const series = [];
|
|
4085
4089
|
for (const row of seriesRows) {
|
|
4086
4090
|
if (performance.now() - started > maxElapsedMs) {
|
|
@@ -4096,7 +4100,7 @@ function queryHistory(db, q, budget = {}) {
|
|
|
4096
4100
|
Number(row.series_id),
|
|
4097
4101
|
fromBucketMs(chosen.tier, q.fromMs),
|
|
4098
4102
|
q.toMs,
|
|
4099
|
-
|
|
4103
|
+
originMs,
|
|
4100
4104
|
stepMs,
|
|
4101
4105
|
// An additional per-series guard. Tier selection already keeps the total
|
|
4102
4106
|
// under budget; this makes a single query bounded even if a custom
|
|
@@ -4262,8 +4266,8 @@ function readGaps(db, machineId, fromMs, toMs) {
|
|
|
4262
4266
|
"SELECT from_ms, to_ms, dropped, reason FROM gaps WHERE machine_id = ? AND to_ms >= ? AND from_ms <= ? ORDER BY from_ms LIMIT ?"
|
|
4263
4267
|
).all(machineId, fromMs, toMs, MAX_GAPS);
|
|
4264
4268
|
const missing = db.db.prepare(
|
|
4265
|
-
"WITH
|
|
4266
|
-
).all(machineId, fromMs, toMs, MAX_GAPS);
|
|
4269
|
+
"WITH before_window AS ( SELECT captured_at_ms, expected_interval_ms FROM sample_receipts WHERE machine_id = ? AND captured_at_ms < ? ORDER BY captured_at_ms DESC LIMIT 1 ), in_window AS ( SELECT captured_at_ms, expected_interval_ms FROM sample_receipts WHERE machine_id = ? AND captured_at_ms >= ? AND captured_at_ms <= ? ), ordered AS ( SELECT captured_at_ms, expected_interval_ms, LAG(captured_at_ms) OVER (ORDER BY captured_at_ms) AS prev_ms FROM (SELECT * FROM before_window UNION ALL SELECT * FROM in_window) ) SELECT MAX(prev_ms, ?) AS from_ms, captured_at_ms AS to_ms FROM ordered WHERE prev_ms IS NOT NULL AND captured_at_ms > ? AND captured_at_ms - prev_ms > MAX(15000, 3 * COALESCE(expected_interval_ms, 5000)) ORDER BY captured_at_ms LIMIT ?"
|
|
4270
|
+
).all(machineId, fromMs, machineId, fromMs, toMs, fromMs, fromMs, MAX_GAPS);
|
|
4267
4271
|
const gaps = [
|
|
4268
4272
|
...dropped.map((row) => ({
|
|
4269
4273
|
fromMs: Number(row.from_ms),
|
package/docs/bottlenecks.md
CHANGED
|
@@ -27,7 +27,7 @@ CPU temperature supports known CPU hwmon drivers, including `coretemp` and
|
|
|
27
27
|
`k10temp`. CPU package power uses the Linux powercap `intel-rapl:N` interface,
|
|
28
28
|
including compatible AMD implementations. Many systems restrict `energy_uj` to
|
|
29
29
|
root. The collector remains unprivileged. The optional
|
|
30
|
-
[system installer](installation.md#
|
|
30
|
+
[system installer](system-installation.md#cpu-package-power) grants its dedicated account persistent
|
|
31
31
|
read-only package-counter access; ordinary user installation leaves permissions
|
|
32
32
|
under the operator's control.
|
|
33
33
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Configuration reference
|
|
2
|
+
|
|
3
|
+
For an installation made with `rigscope install`, use `rigscope config` to find
|
|
4
|
+
its private settings. See [Hub configuration](installation.md#hub-configuration)
|
|
5
|
+
and [Remote access](installation.md#access-from-another-computer) for managed setup.
|
|
6
|
+
|
|
7
|
+
The environment variables below apply to source development and services that
|
|
8
|
+
run the hub or collector directly. Setting them in your shell does not change
|
|
9
|
+
an installed background service. Keep private directories at mode `0700` and
|
|
10
|
+
configuration files at `0600`; do not commit them.
|
|
11
|
+
|
|
12
|
+
## Hub variables
|
|
13
|
+
|
|
14
|
+
| Variable | Purpose and default |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `HUB_HOST`, `HUB_PORT` | Local listener: `127.0.0.1:8081`. Only literal loopback addresses are accepted. Port `0` selects an unused port for tests. |
|
|
17
|
+
| `HUB_PUBLIC_ORIGIN`, `HUB_SOCKET_PATH` | Remote access: set both the exact HTTPS origin and an absolute Unix socket path in a private directory. The hub then has no TCP listener. |
|
|
18
|
+
| `HUB_DATABASE_PATH` | SQLite database for telemetry, users, alerts and the collector registry. Defaults beside `HUB_STATE_FILE`, or under `$XDG_STATE_HOME/rigscope/hub/` (falling back to `~/.local/state`). |
|
|
19
|
+
| `HUB_BROWSER_USERS` | First-run users as JSON: `{username,passwordHash,machineIds,admin?}`. `machineIds` is `"*"` or a list; `[]` allows no machines. |
|
|
20
|
+
| `HUB_ADMIN_USERS` | Comma-separated usernames to make administrators during first import. If omitted, an existing bootstrap account named `owner` becomes an administrator. Other users need an explicit `admin:true`. |
|
|
21
|
+
| `HUB_COLLECTORS` | First-run collector credentials as JSON: `{collectorId,machineId,token}`. The limit applies to JSON bytes, not a fixed machine count. |
|
|
22
|
+
| `HUB_MAX_COLLECTOR_CONNECTIONS` | Maximum concurrent collector connections. Positive integer; defaults to `100`. Choose a value based on measured capacity. |
|
|
23
|
+
| `HUB_STATE_FILE` | Private enrollment file to import from an existing installation; also enables enrollment. Keep it with the deployment configuration for recovery. |
|
|
24
|
+
| `HUB_ENROLLMENT_GRANTS` | Initial grants as JSON: `{token,expiresAt}`. Expiry must be within 15 minutes. Used grants stay consumed after import and restart. |
|
|
25
|
+
|
|
26
|
+
### First-run users and credentials
|
|
27
|
+
|
|
28
|
+
The database imports bootstrap users and collector credentials once. Later
|
|
29
|
+
restarts do not overwrite managed users or restore revoked credentials. Use
|
|
30
|
+
**Administration** to change users after the first start.
|
|
31
|
+
|
|
32
|
+
The managed installer creates the initial account for you. From a source
|
|
33
|
+
checkout, use `scripts/hash-browser-password.cjs` to generate salted scrypt
|
|
34
|
+
hashes; it reads passwords from stdin. Keep hashes private.
|
|
35
|
+
|
|
36
|
+
## Collector variables
|
|
37
|
+
|
|
38
|
+
| Variable | Purpose and default |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `COLLECTOR_MODE` | `real` by default. `mock` generates synthetic readings and never scans real processes. |
|
|
41
|
+
| `COLLECTOR_STATE_FILE` | Private saved identity, destinations and enrollment recovery proof. Defaults to `$XDG_STATE_HOME/rigscope/collector.json` (falling back to `~/.local/state`). |
|
|
42
|
+
| `COLLECTOR_INTERVAL_MS` | Sampling interval: `1000` ms by default, minimum `100` ms. GPU polling runs at most once per second. |
|
|
43
|
+
| `COLLECTOR_HUBS` | Explicit destinations as JSON: `{url,token,sharing?,intervalMs?}`, up to eight. Otherwise the collector uses saved enrollment. |
|
|
44
|
+
| `COLLECTOR_HOSTNAME` | Display metadata; defaults to the OS hostname in real mode. |
|
|
45
|
+
|
|
46
|
+
### Sharing settings
|
|
47
|
+
|
|
48
|
+
Each destination's `sharing` object accepts `cpu`, `memory`, `swap`, `gpus`,
|
|
49
|
+
`disks`, `network`, `networkAddresses`, `processes` and `processArguments`.
|
|
50
|
+
When supplying an object, CPU and memory must remain enabled.
|
|
51
|
+
|
|
52
|
+
Omitted fields default to true, except `swap` follows `memory` and
|
|
53
|
+
`processArguments` defaults to false. Managed enrollment starts with network
|
|
54
|
+
addresses and full process arguments disabled. Review a destination's saved
|
|
55
|
+
policy before expanding what it shares. Environment variables are never collected.
|
|
56
|
+
|
|
57
|
+
The collector applies sharing rules before queueing samples, again before
|
|
58
|
+
sending restored samples, and to each hub's process results. Restricting a policy
|
|
59
|
+
also restricts pending records.
|
|
60
|
+
|
|
61
|
+
## Source enrollment, rotation and replacement
|
|
62
|
+
|
|
63
|
+
For a managed installation, follow [Add machines and hubs](installation.md#add-machines-and-hubs)
|
|
64
|
+
using `rigscope connect`. The steps here require a source checkout with
|
|
65
|
+
development dependencies installed.
|
|
66
|
+
|
|
67
|
+
1. Create a short-lived grant through the hub's administration interface.
|
|
68
|
+
2. Set `COLLECTOR_ENROLL_URL` to the full `ws[s]://…/api/collector/connect` URL.
|
|
69
|
+
Set `COLLECTOR_ENROLL_TOKEN` privately to the grant.
|
|
70
|
+
3. Run:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
npm run collector:enroll
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
4. Remove the grant from the environment and restart the collector.
|
|
77
|
+
|
|
78
|
+
The collector saves a random recovery proof before enrolling. If a successful
|
|
79
|
+
response is lost, retrying with that proof recovers the same credential. A
|
|
80
|
+
hostname or collector ID alone cannot recover it.
|
|
81
|
+
|
|
82
|
+
Rotation or replacement needs a grant bound to the existing machine on that
|
|
83
|
+
hub. Use `npm run collector:enroll -- --replace-enrollment` to replace a saved
|
|
84
|
+
destination. Revocation closes existing connections and invalidates old recovery
|
|
85
|
+
proofs. Replacement never identifies a machine by its hostname or address.
|
package/docs/development.md
CHANGED
|
@@ -16,7 +16,7 @@ npm start
|
|
|
16
16
|
npm run collector:start
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
`npm run collector:enroll` uses `COLLECTOR_ENROLL_URL` and a private `COLLECTOR_ENROLL_TOKEN`. `npm run collector:mock` emits synthetic readings. Real collection continues without a browser. See the
|
|
19
|
+
`npm run collector:enroll` uses `COLLECTOR_ENROLL_URL` and a private `COLLECTOR_ENROLL_TOKEN`. `npm run collector:mock` emits synthetic readings. Real collection continues without a browser. See the [configuration reference](configuration.md) for variables, enrollment and sharing settings.
|
|
20
20
|
|
|
21
21
|
## HTTPS boundary
|
|
22
22
|
|