Files
HealthLog/prisma/migrations/0032_host_metric/migration.sql
T
Marc-André BombeckandClaude Opus 4.7 5d1ece1fd5 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>
2026-05-09 23:46:56 +02:00

32 lines
1.3 KiB
SQL

-- 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");