GitHub
Prototyppackages/prom-metrics-parser/src

Prometheus Metrics Parser

@ralphschuler/prom-metrics-parser

Zerlegt das Prometheus-Textformat in Familien, Metadaten, Labels und numerische Samples.

Prometheuslexertext format

01 · Problem

Wofür braucht man das?

Menschenlesbare Metrics-Exposition muss für Analyse oder Transformation strukturiert und ohne stille Teilakzeptanz geparst werden.

02 · Denkmodell

Das mentale Modell

HELP und TYPE gehören zu einer benannten Familie; Sample-Zeilen besitzen eigenen Namen, quote-aware Labels, Wert und optional weitere Felder.

Im Repository

Keine Funktion wird exportiert. parseLine trennt '# HELP' so, dass Direktiven nie erkannt werden; alle Samples landen in einer einzigen leeren Familie und das Modul loggt Demoausgabe beim Import.

03 · Kontrollfluss

Was passiert in welcher Reihenfolge?

  1. Eingabe zeilenweise lesen und Leerzeilen überspringen.
  2. HELP- und TYPE-Direktiven nach Familienname speichern.
  3. Samplekopf mit einem quote- und escape-aware Lexer zerlegen.
  4. Sample seiner Familie zuordnen und vollständigen Zahlenwert validieren.

04 · Bauteile

Die entscheidenden Verträge

parsePrometheusMetrics (intern) Nicht exportierte Hauptfunktion über den gesamten Text.
parseSample (intern) Liest Namen, einfachen Labelblock und Wert.
parseLabels (intern) Teilt stumpf an Komma und Gleichheitszeichen; Escapes fehlen.

05 · Build it yourself

Selbst implementieren

Unterstütze zunächst einen klar begrenzten Subset und lehne alles außerhalb davon sichtbar ab.

  1. Direktiven vor Samples erkennen und pro Familienname zwischenspeichern.
  2. Sample-Zeilen am Value-Feld trennen und den Kopf separat lexen.
  3. Labels zeichenweise innerhalb von Quotes und Escape-Sequenzen lesen.
minimal.ts · unabhängig vom Package
type Sample = { name: string; value: number };

function parseSimpleSample(line: string): Sample {
  const split = line.lastIndexOf(" ");
  if (split < 1) throw new Error("Incomplete sample");
  const head = line.slice(0, split).trim();
  const raw = line.slice(split + 1).trim();
  const value = Number(raw);
  if (Number.isNaN(value)) throw new Error("Invalid value");
  const brace = head.indexOf("{");
  const name = head.slice(0, brace < 0 ? head.length : brace);
  if (!name) throw new Error("Missing metric name");
  return { name, value };
}

06 · Verifizieren

Was du testen solltest

  • Mehrere Familien behalten eigene HELP-, TYPE- und Sample-Daten.
  • Escaped Quotes, Kommas und Gleichheitszeichen in Labelwerten werden korrekt gelesen.
  • NaN, +Inf, -Inf, Timestamp und ungültige Restzeichen folgen dem dokumentierten Subset.

07 · Grenzen

Kompromisse und Stolperfallen

  • Split-basierter Code ist kurz, akzeptiert aber komplexe Labelsyntax falsch.
  • Ein Lexer ist robuster, muss dafür präzise Zustände und Fehlerspannen pflegen.
  • Vollständige OpenMetrics-Unterstützung ist wesentlich größer als ein einfacher Prometheus-Subset.
Wichtig

parseFloat akzeptiert auch teilweise numerische Strings. Ein Parser sollte die gesamte Value-Komponente validieren.

08 · Weiterdenken

Quellcode und Nachbarn

Originalcode auf GitHub ansehen