mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
feat(db): HostMetric model for host-load sampling
Adds the per-minute snapshot table that backs the new admin host-load
chart above /admin/system-status. One row per minute, captured by the
pg-boss sampler in the next commit, with 7-day retention enforced
inside the worker so the table stays under a few thousand rows.
Schema mirrors what the chart needs:
- load_avg_1/5/15 (DOUBLE PRECISION) — os.loadavg() output
- mem_used_bytes / mem_total_bytes — derived from os.totalmem() and
os.freemem(), kept as raw bytes so the API can compute either a
percent or a MiB delta downstream
- disk_read_bytes / disk_write_bytes — nullable cumulative byte
counters from /proc/diskstats. NULL on macOS/Windows dev hosts;
Linux production picks them up automatically. The API endpoint
converts deltas to bytes-per-second between samples
Indexed by captured_at so the "last 2 hours" query stays index-only.
Migration 0032_host_metric. integration setup.ts adds host_metrics to
the truncate list so testcontainers stays clean across runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
27f3933344
commit
5d1ece1fd5
3 files changed
+58
No files matched your search
@@ -0,0 +1,31 @@
|
||||
-- v1.4.16 phase B3: per-minute host-load snapshot table.
|
||||
--
|
||||
-- The admin /system-status section now renders a 2-hour host-load chart
|
||||
-- above the existing facts grid (Marc: "über dem Systemstatus vielleicht
|
||||
-- nochmal so ein Graf der Auslastung des Hosts der letzten zwei Stunden").
|
||||
--
|
||||
-- A pg-boss `host-metric-sample` job inserts one row per minute carrying
|
||||
-- `os.loadavg()` (1/5/15-minute) + `os.totalmem() - os.freemem()` and,
|
||||
-- on Linux, a rolling cumulative byte counter from /proc/diskstats.
|
||||
-- Disk fields are nullable so non-Linux dev hosts keep working.
|
||||
--
|
||||
-- Retention: 7 days, enforced inside the sampler at the end of each
|
||||
-- tick. Indexed by `captured_at` so the API's `WHERE captured_at >=
|
||||
-- now() - 2h ORDER BY captured_at` query is index-only.
|
||||
|
||||
CREATE TABLE "host_metrics" (
|
||||
"id" TEXT NOT NULL,
|
||||
"captured_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"load_avg_1" DOUBLE PRECISION NOT NULL,
|
||||
"load_avg_5" DOUBLE PRECISION NOT NULL,
|
||||
"load_avg_15" DOUBLE PRECISION NOT NULL,
|
||||
"mem_used_bytes" BIGINT NOT NULL,
|
||||
"mem_total_bytes" BIGINT NOT NULL,
|
||||
"disk_read_bytes" BIGINT,
|
||||
"disk_write_bytes" BIGINT,
|
||||
|
||||
CONSTRAINT "host_metrics_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX "host_metrics_captured_at_idx"
|
||||
ON "host_metrics" ("captured_at");
|
||||
@@ -757,3 +757,29 @@ model UserAchievement {
|
||||
@@index([userId])
|
||||
@@map("user_achievements")
|
||||
}
|
||||
|
||||
// ─── Host Metrics (admin system-status host-load chart) ──────
|
||||
|
||||
/// Per-minute snapshot of host-process load + memory captured by the
|
||||
/// pg-boss `host-metric-sample` job. Read by `/api/admin/host-metrics`
|
||||
/// to render the host-load trend above the system-status section.
|
||||
/// 7-day retention is enforced inside the sampler — we keep the table
|
||||
/// small enough that a single `findMany` over the last 2 hours stays
|
||||
/// well under 200 rows.
|
||||
model HostMetric {
|
||||
id String @id @default(cuid())
|
||||
capturedAt DateTime @default(now()) @map("captured_at")
|
||||
loadAvg1 Float @map("load_avg_1")
|
||||
loadAvg5 Float @map("load_avg_5")
|
||||
loadAvg15 Float @map("load_avg_15")
|
||||
memUsedBytes BigInt @map("mem_used_bytes")
|
||||
memTotalBytes BigInt @map("mem_total_bytes")
|
||||
// Optional rolling-window byte counters from /proc/diskstats. Null
|
||||
// outside Linux (macOS dev machines, Windows). The API endpoint
|
||||
// converts deltas into bytes-per-second client-side.
|
||||
diskReadBytes BigInt? @map("disk_read_bytes")
|
||||
diskWriteBytes BigInt? @map("disk_write_bytes")
|
||||
|
||||
@@index([capturedAt])
|
||||
@@map("host_metrics")
|
||||
}
|
||||
@@ -43,6 +43,7 @@ export async function truncateAllTables(client: PrismaClient): Promise<void> {
|
||||
"data_backups",
|
||||
"devices",
|
||||
"feedback",
|
||||
"host_metrics",
|
||||
"idempotency_keys",
|
||||
"integration_statuses",
|
||||
"measurements",
|
||||
|
||||
Reference in new issue
Block a user