159 lines
5.6 KiB
Markdown
159 lines
5.6 KiB
Markdown
# Extending PearData
|
|
|
|
## Add a chart / context
|
|
|
|
1. Define the chart in `shared/metrics.js` (`STATIC_CHART_DEFS`, or `registerChart()` for instances).
|
|
2. Emit samples from `server/services/collector.js` (or a new collector module).
|
|
3. Store + REST/RPC pick it up automatically via `getAllChartDefs()` / `CHART_BY_ID`.
|
|
4. Ensure the chart lands in the Charts wall TOC via `shared/taxonomy.js` (`sectionForChart` matchers). Prefer a real section over **Other**.
|
|
5. Document dimensions in [DATA-MODEL.md](./DATA-MODEL.md).
|
|
6. The desktop Charts tab picks it up automatically (no per-chart HTML). Overview spotlight is optional.
|
|
|
|
Coverage is asserted by `test/taxonomy-coverage.test.js`.
|
|
|
|
## Add an RPC method
|
|
|
|
### `shared/protocol.js`
|
|
|
|
```js
|
|
export const MethodRoles = Object.freeze({
|
|
// ...
|
|
listContainers: Roles.viewer,
|
|
restartCollector: Roles.admin,
|
|
})
|
|
```
|
|
|
|
### `shared/schema.js`
|
|
|
|
Validate args.
|
|
|
|
### `server/services/…` + `server/handlers/monitor.js`
|
|
|
|
Register with `session.respond(...)`. Use `{ hot: true }` for high-frequency paths.
|
|
|
|
### Client
|
|
|
|
```js
|
|
await manager.request(Methods.listContainers, {})
|
|
```
|
|
|
|
### Docs + tests
|
|
|
|
Update [PROTOCOL.md](./PROTOCOL.md) and add a brittle test.
|
|
|
|
## Add a REST route
|
|
|
|
Edit `server/rest/routes.js` — keep stable `/api/v3/...` path naming.
|
|
|
|
## Add a job
|
|
|
|
Register in `server/services/jobs.js` `JOB_HANDLERS`.
|
|
|
|
```js
|
|
retrainAnomaly: async (args) => getAnomalyEngine().retrain(getStore(), args)
|
|
```
|
|
|
|
Operators run via `runJob` (`retrainAnomaly` is registered).
|
|
|
|
## Add a collector plugin (pattern)
|
|
|
|
```
|
|
server/services/collectors/
|
|
docker.js # PEARDATA_DOCKER=1 — cgroup + Docker socket names (installer auto-enables)
|
|
peardock.js # bridge (planned)
|
|
```
|
|
|
|
Have `pipeline.js` start each enabled collector; all emit `samples` batches into the same store.
|
|
|
|
### Docker collector (shipped spike)
|
|
|
|
1. Set `PEARDATA_DOCKER=1` on the agent (or re-run the installer when Docker is present).
|
|
2. Ensure `peardata` can read the socket (`usermod -aG docker peardata` + unit `SupplementaryGroups=… docker`).
|
|
3. Charts: `docker.containers`, `docker.cpu.<shortId>`, `docker.mem.<shortId>` (stable ids); **titles/families** use human names (`dozzle · CPU`).
|
|
4. Discovery: cgroup v2 `docker-*.scope` / `libpod-*.scope`; names via `loadContainerNameMap` (unix HTTP API → `docker ps` → filesystem) + Compose labels (`shared/container-names.js`).
|
|
5. Cgroups collector reuses the same name map so `cgroup.*` cards are not bare hashes.
|
|
6. UI: [user-guide/containers.md](../user-guide/containers.md).
|
|
|
|
### Process top-N collector
|
|
|
|
1. Default **on** for Linux (`PEARDATA_PROCESSES=0` to disable charts). Optional `PEARDATA_PROCESSES_TOP=8`.
|
|
2. Charts: `processes.top_cpu` / `top_rss` / `top_io` / `top_threads` (dimensions = process comm names).
|
|
3. Desktop **Processes** tab + RPC `listProcesses` / `GET /api/v3/processes` — per-PID live table (not just top-N charts).
|
|
4. Linux `/proc` only; safe no-op on other platforms.
|
|
|
|
### Nginx stub_status plugin
|
|
|
|
1. Set `PEARDATA_NGINX=1` and `PEARDATA_NGINX_URL=…`.
|
|
2. Charts: `nginx.connections`, `nginx.requests`.
|
|
3. Base class: `server/services/collectors/plugin.js` (`CollectorPlugin`).
|
|
|
|
### Redis INFO plugin
|
|
|
|
1. Set `PEARDATA_REDIS=1` and optional `PEARDATA_REDIS_URL`.
|
|
2. Charts: `redis.memory`, `redis.clients`, `redis.stats`.
|
|
|
|
### Postgres plugin
|
|
|
|
1. Set `PEARDATA_POSTGRES=1` (+ host/port).
|
|
2. Charts: `postgres.up` (TCP probe); optional `postgres.stats` via `PEARDATA_POSTGRES_STATS_URL`.
|
|
|
|
### Export / Prometheus push
|
|
|
|
- Job `exportSnapshot` / RPC `exportSnapshot` / REST `GET /api/v3/export`
|
|
- Job `prometheusPush` → `PEARDATA_PUSHGATEWAY_URL`
|
|
- Optional file write: `PEARDATA_EXPORT_DIR`
|
|
|
|
### Webhook notifications
|
|
|
|
1. Set `PEARDATA_WEBHOOK_URL=https://…` and optional `PEARDATA_WEBHOOK_SECRET`.
|
|
2. When a secret is set, requests include:
|
|
- `X-PearData-Timestamp`
|
|
- `X-PearData-Signature: sha256=<HMAC-SHA256(secret, `${ts}.${body}`)>`
|
|
3. Verify with `verifyWebhookSignature` from `server/services/notify.js`.
|
|
4. Desktop: toggle “Desktop notifications” in the Anomalies panel.
|
|
|
|
### z-score / retrain
|
|
|
|
1. `PEARDATA_ANOMALY_MODE=zscore|hybrid` for rolling z-score fires.
|
|
2. Job `retrainAnomaly` (operator) refits warn/crit from store history (`mean ± z·stdev`).
|
|
3. Helpers live in `server/services/zscore.js`.
|
|
|
|
### REST HyperDHT tunnel (holesail-style)
|
|
|
|
1. `PEARDATA_REST_TUNNEL=1` (+ optional `PEARDATA_REST_TUNNEL_SEED`).
|
|
2. Agent announces a HyperDHT key that proxies TCP → local REST.
|
|
3. Inspect: `GET /api/v3/tunnel` or `getServerInfo.restTunnel`.
|
|
|
|
### PearDock bridge
|
|
|
|
1. Set `PEARDATA_PEARDOCK=1` and `PEARDATA_PEARDOCK_PEERS=<dockOrAgentPk>,…`.
|
|
2. Bridge dials peers, reads `getAllMetrics`, remaps `docker.*` → `peardock.*`.
|
|
3. Prefer public APIs / your own modules when integrating with PearDock (both are AGPL-3).
|
|
|
|
## Parent peer (fleet aggregator)
|
|
|
|
Shipped opt-in spike:
|
|
|
|
1. Set `PEARDATA_PARENT=1` and `PEARDATA_PARENT_PEERS=<childPk>,…`.
|
|
2. Parent dials children over HyperDHT (`PearDataConnection`), polls health + metrics.
|
|
3. Emits `fleet.cpu`, `fleet.ram`, `fleet.children` into the local store.
|
|
4. REST: `GET /api/v3/nodes` (multi), `/api/v3/fleet`, `/api/v3/stream_path`.
|
|
5. RPC: `getFleetHealth`, `listChildPeers`.
|
|
|
|
## PearDock / PearVirt hooks
|
|
|
|
- Prefer **RPC adapters** over scraping: call dock/virt methods, map to PearData contexts.
|
|
- PearData is AGPL-3.0-only — see [LICENSE](../LICENSE). Depend on public APIs when integrating sibling projects.
|
|
|
|
## Desktop chrome
|
|
|
|
Keep `<pear-ctrl>`, titlebar drag regions, and `pear.gui.resizable`. See [DESKTOP.md](./DESKTOP.md).
|
|
|
|
## Rebrand (fork)
|
|
|
|
```bash
|
|
npm run rename -- my-monitor MyMonitor
|
|
```
|
|
|
|
Review invite prefix / env prefix, then `npm test`.
|