Skip to main content

Victoriametrics

@magistr/victoriametricsv2026.09.02.1· 8d agoMODELS
01README

VictoriaMetrics query API for swamp — instant/range PromQL, scrape-target health, a node-exporter system overview, container memory rankings, and a metrics push.

Model:

  • @magistr/victoriametrics — queries a VictoriaMetrics (or Prometheus- compatible) HTTP endpoint via /api/v1/query and /api/v1/query_range, and writes to it via /api/v1/import/prometheus. Methods: query (instant PromQL), query-range (range PromQL over a time window), health (scrape-target up/down from the up metric), system-overview (CPU/memory/load/disk/network stats plus anomaly detection from node-exporter), container-memory (top-N container memory usage rankings), and push (import Prometheus exposition text so a job can record its own outcome as a series vmalert can alert on).
02Release Notes

2026.09.02.1

Restores the push method and its pushResult resource.

push existed on the 2026.08.08.1 model — it POSTs Prometheus exposition text to /api/v1/import/prometheus so a job can record its own outcome as a series vmalert can alert on. It was dropped when the model was rewritten for the 11-bug fix batch and never made it into git, so every published version since has been missing it while one deployed copy of the old file kept using it. The gap surfaced on 2026-09-02: swamp-fleet-update's publish-metrics step succeeded on the server (still on the stale 2026.08.08.1 file) and failed swamp workflow validate on the laptop with Method 'push' not found on model type '@victoriametrics/query'. Syncing the two copies in either direction would have silently killed the metrics.

  • pushlines (exposition text, blank lines and # comments allowed) and optional extraLabels (comma-separated key=value) → pushResult.
  • Three pure helpers are now exported so they can be property-tested directly: sampleLines, metricNames, extraLabelParams. Before this release the model exported no parsing helpers at all.
  • A failed push writes pushResult with ok:false before throwing. A method that throws without writing leaves no record of what it tried to send, and the attempt that failed is the one worth keeping.
  • A transport failure records httpStatus: 0 rather than inventing a status, and a server error body is truncated to 300 characters so an unbounded response cannot become an unbounded resource.
  • The success body is read even on VM's empty 204, so the connection is not left dangling.

One real defect found while writing the tests

extraLabelParams trimmed each whole key=value pair, which silently rewrote any value with leading or trailing whitespace — a= was sent as a=, so the label VictoriaMetrics stored differed from the one the caller passed. Property f2 (round-tripping arbitrary pairs back through URLSearchParams) shrank it to {key:"a", value:" "}. Now only the key is trimmed, so "job=x, instance=y" still parses while a value keeps every character it was given; the split is at the first =, so an = inside a value survives, and a pair whose key is empty is dropped rather than sent malformed.

Tests

15 new tests across four suites, all green (105 total):

  • methods (5) — happy path pinning verb, endpoint, text/plain content type and the exact body; extraLabels → percent-encoded params; non-2xx and transport-failure paths asserting the resource is written and the error thrown; empty-payload rejection before any request is made.
  • adversarial (8) — HELP/TYPE and blank lines are not samples; a name ends at the first { or whitespace (a naive split(" ")[0] reports a_metric{label="value); malformed pairs dropped; an injected &extra_label= cannot break out of the query string; a 200-with-error-body is still success (VM signals import failure with a non-2xx — characterization, not a bug); 300-char error truncation; the two whitespace/= regressions above.
  • coverage (4) — the port || 8428 fallback; no dangling ? when there are no labels; exactly one trailing newline after trimming; the success-path body read (asserted via bodyUsed).
  • property (2) — metricNames returns exactly the distinct emitted names in first-seen order and sampleLines counts exactly the emitted samples, both oracled from the generator's own record rather than a re-parse; every extraLabels pair round-trips as one param decoded by URLSearchParams.

No existing test changed. No existing resource schema changed; pushResult is additive and the upgrades[] entry is an identity.

03Models1
@magistr/victoriametricsv2026.09.02.1extensions/models/victoriametrics.ts

Global Arguments

ArgumentTypeDescription
hoststringVictoriaMetrics host (IP or hostname)
portnumberVictoriaMetrics HTTP port

Resources

queryResult(infinite)— Result of a PromQL query
health(infinite)— Scrape target health status
overview(infinite)— System metrics overview
containerMemory(infinite)— Container memory usage rankings
pushResult(infinite)— Result of importing metrics in Prometheus exposition format
04Previous Versions6
2026.08.30.1

2026.08.30.1

system-overview now counts each physical disk once.

node_exporter exports every layer of the block stack. On Unraid an encrypted array slot is dm-N -> mdXp1 -> one physical sdX, so the disk view listed the same spindle two or three times and a dm-*/sd* pair reporting the same utilisation looked like two independent disks corroborating each other. On Tower, 2026-08-30, dm-3 and sdl were flagged together as a disk-saturation watch item: dm-3 = md4p1 = disk4 = /dev/sdl, one 14.6TB drive, and neither layer was near saturation (7d mean 20%, peak 52%).

  • DISK_IO_QUERY (new export) adds {device!~"(dm-|md|loop|sr|zram|ram|nbd|drbd|zd).*"} so VictoriaMetrics drops the virtual layers at query time.
  • isPhysicalDiskDevice() (new export) re-checks each returned series client-side, so a server that ignores the matcher still cannot double-count.
  • Both derive from one VIRTUAL_DISK_PREFIXES list, so the PromQL string and the client-side check cannot drift apart. Tests import DISK_IO_QUERY instead of restating it.
  • Unlabelled series still normalise to "unknown" and are kept — an unattributable series must not be silently dropped.

No resource schema change; identity upgrades[] entry appended.

2026.08.19.1
2026.08.02.1

2026.08.02.1

Real fixes for all 11 latent bugs tracked in the LOCAL victoriametrics-latent-bugs issue-lifecycle model (NEVER filed to the swamp.club Lab — see CLAUDE.md's anti-bypass rule). model.version and manifest.yaml both bump 2026.07.16.2 -> 2026.08.02.1, with an identity upgrades[] entry appended (no resource schema change).

  • VM2 (HIGH, multi-series collapse): extractValues now flatMaps EVERY series in result.data.result (result.data.result.flatMap((s) => s.values ?? []).map(...)) instead of reading only result.data.result[0]. system-overview's CPU/memory/load stats now characterize the FULL set of series a range query returns, not just the first one. Single-series results are byte-identical (flatMap of one series equals that series). The flatten's inter-series timestamp boundary is a backward jump by construction and never trips the >600s forward-gap "Metric gap" reboot detector.
  • VM1 (MED, health has no notion of expected targets): health gains a new backward-compatible method argument, expectedTargets (default []). Any name in that list not seen in the up vector is appended with status:"unknown" instead of being silently omitted. An empty/default list is a no-op — existing callers see no change.
  • VM3 (MED, absent metric indistinguishable from idle 0%): system-overview now pushes a distinct "<CPU|Memory|Load> metric absent (no series returned)" anomaly whenever a metric's range query returns zero series. The numeric fields still report {0,0,0,0} (unchanged) — only the anomalies array gains the flag.
  • VM4 (MED, boot-time epoch fallback): an empty node_boot_time_seconds result no longer falls back to bootTs=0 (the 1970 epoch, with an enormous computed uptime). uptime.bootTime is now the string "unknown", uptime.uptimeMinutes is 0, and a "Boot time unavailable" anomaly is pushed. A real boot time is completely unaffected.
  • VM5 (MED, scalar query garbage-mapping): query now dispatches on data.resultType: a "scalar" result ([ts, "<value>"]) maps to a single [{metric:{}, value:<parsed number>}] row instead of the old two-row [{metric:undefined,value:null},{metric:undefined,value:null}] garbage. Vector results are unaffected (same r.value ? parseFloat(r.value[1]) : null mapping as before); a matrix body fed into query still maps every series to value:null (matrix support was never in scope for query, and stays a documented, intentional gap).
  • VM6 + VM11 (MED, uninspected {status:"error"} responses): a new shared vmData(result) helper is called by the three direct single-query methods (query, query-range, health) right after the HTTP round-trip. It throws Error("VM query error: <result.error | 'response missing data'>") when result.status==="error" or result.data.result isn't an array, instead of letting a partial/hostile 200 body crash several frames down with an uncaught TypeError. system-overview and container-memory deliberately do NOT go through vmData — they keep their existing lenient degrade-to-zero behavior on missing/empty data.
  • VM7 (MED, query-range vector-shaped-body crash): query-range's series mapper now does (r.values ?? []).map(...) — a series missing values (e.g. a vector body mistakenly fed to query-range) degrades to values:[] instead of throwing.
  • VM8 (MED, unguarded inner .values/.value access): the disk loop, container-memory's series loop, and health's per-target status now all guard their inner access instead of crashing on a partial/hostile response: disk pre-filters series via Array.isArray(r.values) && r.values.length>0 before mapping; container-memory uses (r.values ?? []) and r.metric?.name; health uses r.value ? (...) : "unknown".
  • VM9 (MED, disk NaN/-Infinity): folds into the VM8 disk pre-filter — a series with values:[] (present, empty) is now dropped BEFORE the Math.max/reduce computation runs, instead of computing NaN/-Infinity and relying on the >10 threshold filter to silently absorb it. The observable result (disk:[]) is unchanged.
  • VM10 (LOW, negative topN): container-memory's topN is now clamped via Math.max(0, args.topN) before .slice(0, ...). A negative topN now yields [] instead of slice(0, -n) silently dropping from the END of the already-desc-sorted array. topN:0 is unaffected (Math.max(0,0)===0).
  • Tests: all 11 latent-bug pins in victoriametrics_adversarial_test.ts flip from characterizing the bug (title prefixed pin:) to asserting the fix (title prefixed fix (VMn):), reusing the existing fixtures plus a handful of new inline hostile bodies. New adversarial coverage: two multi-series regressions for VM2 (a LOAD spike
2026.07.16.2

Release 2026.07.16.2 — align model versions with manifests

Maintenance release across the @magistr extensions. For most packages this carries no functional change: the only edit is the model's version: field, brought back in line with its manifest version so the published model type version and the package version no longer drift.

Functional changes in this release are limited to:

  • anime-cron: normalizeTitle now strips a ": subtitle" suffix and a trailing parenthesized year before comparison, fixing dedup false-misses where the torrent title carries a subtitle or year that the AniList romaji does not.

  • arckit: first publish. Standalone ArcKit port — a 12-phase architecture governance state machine with 65 bundled templates, driven by a bundled skill.

Also tracks three extensions (kaiten, observability-agent, music-library) that previously existed only as untracked working-tree directories, recovered from stashes.

2026.07.16.1

Maintenance version bump. No functional changes.

Added 1 models

2026.05.25.1

Merge pull request #5 from umag/extensions/jscad-stl-pair

extensions: add 15 more @magistr extensions + auto-discover CI

05Stats
A
100 / 100
Downloads
4
Archive size
16.1 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
06Platforms
07Labels