Lexikon · P

PromQL

Die funktionale Abfragesprache von Prometheus, um Zeitreihen auszuwählen, zu aggregieren und zu berechnen.

Von Obseria-RedaktionAktualisiert

Definition

PromQL (Prometheus Query Language) ist die funktionale Abfragesprache von Prometheus, mit der Sie Zeitreihen in Echtzeit auswählen und aggregieren. Sie arbeitet mit Instant Vectors, Range Vectors und Skalaren und bietet Funktionen wie rate() und histogram_quantile() sowie Aggregationsoperatoren wie sum by. PromQL steckt hinter Dashboards, Recording Rules und Alerting Rules.

Was ist PromQL?

PromQL ist die Abfragesprache von Prometheus und der De-facto-Standard, um Metriken in Cloud-native-Umgebungen abzufragen. Viele weitere Systeme wie Thanos, Cortex, Mimir, VictoriaMetrics und mehrere kommerzielle Backends verstehen PromQL oder einen nahen Dialekt. Jedes Grafana-Panel auf Prometheus-Daten, jede Alerting Rule und jede Recording Rule ist ein PromQL-Ausdruck.

PromQL ist funktional und nicht an SQL angelehnt: Sie schreiben kein SELECT ... FROM, sondern verschachteln Ausdrücke. Ein Ausdruck ergibt einen von vier Typen: einen Instant Vector (ein Wert pro Zeitreihe zu einem Zeitpunkt), einen Range Vector (ein Zeitfenster von Werten pro Zeitreihe), einen Skalar oder einen String.

Selektoren und Label-Matcher

Die einfachste Abfrage ist ein Metrikname. Sie liefert den aktuellen Wert jeder passenden Zeitreihe. Geschweifte Klammern filtern nach Labels:

http_requests_total{job="checkout", status=~"5..", method!="OPTIONS"}

Es gibt vier Matcher: = (gleich), != (ungleich), =~ (Regex passt) und !~ (Regex passt nicht). Reguläre Ausdrücke sind vollständig verankert, "5.." trifft also 500 bis 599, aber nicht 1500. Eine Dauer in eckigen Klammern wie [5m] macht aus einem Instant Vector einen Range Vector, den Funktionen wie rate() erwarten.

rate(), Aggregation und histogram_quantile()

Raten aus Countern

Counter steigen nur an und fallen bei einem Prozessneustart auf null zurück. Ihr Rohwert ist daher selten nützlich. rate() berechnet den durchschnittlichen Anstieg pro Sekunde über ein Zeitfenster und berücksichtigt Resets:

rate(http_requests_total{job="checkout"}[5m])

increase() liefert den Gesamtanstieg im Fenster (Rate mal Fensterlänge), irate() nutzt nur die letzten beiden Werte und reagiert damit schneller, aber unruhiger. Als Faustregel sollte das Fenster mindestens das Vierfache des Scrape-Intervalls betragen.

Aggregation mit sum by

Aggregationsoperatoren wie sum, avg, max, count und topk fassen Zeitreihen zusammen. by behält die genannten Labels, without entfernt sie:

sum by (service) (rate(http_requests_total[5m]))

Das Ergebnis ist der Durchsatz pro Service. Die Reihenfolge ist entscheidend: Erst rate(), dann sum. Wer rohe Counter summiert und danach die Rate bildet, verschleiert Resets und erhält falsche Werte.

Perzentile aus Histogrammen

Klassische Prometheus-Histogramme bestehen aus kumulativen _bucket-Zeitreihen mit dem Label le (kleiner oder gleich). histogram_quantile() schätzt daraus ein Quantil:

histogram_quantile(0.99,
  sum by (le, service) (rate(http_request_duration_seconds_bucket[5m])))

Behalten Sie le in der by-Klausel, sonst fehlen der Funktion die Buckets. Das Ergebnis ist eine Schätzung, so genau wie die Bucket-Grenzen. Native Histogramme in neueren Prometheus-Versionen verbessern das ohne manuelles Bucket-Design.

Beispiel: Fehlerquote für ein SLO

Binäre Operatoren verknüpfen Ausdrücke. Teilt man zwei aggregierte Raten, entsteht eine Fehlerquote pro Service, ein typisches Golden Signal und SLI:

sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
/
sum by (service) (rate(http_requests_total[5m]))

In einer Alerting Rule mit Schwellwert, etwa > 0.01 und for: 10m, alarmiert dieser Ausdruck erst, wenn zehn Minuten lang mehr als ein Prozent der Requests fehlschlagen. Für SLO-basiertes Alerting speist dieselbe Quote über mehrere Zeitfenster Multi-Window-Alarme auf die Burn Rate. Weitere nützliche Bausteine sind der offset-Modifier für Vergleiche mit der Vorwoche und Recording Rules, die teure Ausdrücke vorab berechnen.

Recording Rules und Alerting Rules

In Prometheus liegen Regeln in YAML-Dateien, die der Server in einem festen Intervall auswertet. Eine Recording Rule speichert das Ergebnis eines Ausdrucks als neue Zeitreihe. Eine Alerting Rule löst aus, sobald ihr Ausdruck länger als die unter for angegebene Dauer Zeitreihen zurückgibt:

groups:
  - name: checkout
    rules:
      - record: service:http_requests:rate5m
        expr: sum by (service) (rate(http_requests_total[5m]))
      - alert: CheckoutHighErrorRatio
        expr: |
          sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
          / sum by (service) (rate(http_requests_total[5m])) > 0.01
        for: 10m
        labels:
          severity: page

Recording Rules beschleunigen Dashboards und halten Alarmausdrücke kurz und lesbar, weil die teure Aggregation einmal pro Auswertung läuft statt bei jedem Seitenaufruf. Achten Sie darauf, dass Recording Rules und Alarme dieselben Labels verwenden, sonst passen Dashboards und Alarme nicht zusammen.

Best Practices

  • Erst die Rate, dann aggregieren, und erst aggregieren, dann Quoten oder Quantile bilden.
  • Recording Rules nutzen für Ausdrücke, die Dashboards und Alarme häufig auswerten, mit dem Namensschema level:metric:operations, etwa service:http_requests:rate5m.
  • Früh filtern. Enge Label-Matcher reduzieren die geladenen Zeitreihen und halten Abfragen schnell.
  • Auf Kardinalität achten. Eine Abfrage über ein Label mit Millionen Werten bleibt langsam, egal wie gut sie formuliert ist.
  • Vector Matching bewusst steuern. Beim Teilen von Zeitreihen mit unterschiedlichen Labels setzen Sie on(), ignoring() und group_left gezielt ein.

Typische Fehler

  • rate() auf ein Gauge anwenden oder den Rohwert eines Counters darstellen.
  • Vorberechnete Quantile aus Summaries über Instanzen mitteln.
  • Ein Fenster kürzer als zwei Scrape-Intervalle wählen, was leere oder sprunghafte Ergebnisse liefert.
  • le vor histogram_quantile() wegaggregieren.

Wie Obseria hilft

Obseria unterstützt PromQL neben OQL und SQL. Bestehende Prometheus-Dashboards und Alarmausdrücke funktionieren daher auch nach dem Umstieg weiter. Prometheus-Endpunkte lassen sich scrapen oder per Remote Write und OTLP anbinden, siehe Prometheus Monitoring. Metrik-Datenpunkte werden 13 Monate aufbewahrt, sodass PromQL-Vergleiche mit offset über Quartale hinweg möglich sind.

Häufig gestellte Fragen

rate() berechnet den durchschnittlichen Anstieg pro Sekunde über das gesamte Zeitfenster und ist die richtige Wahl für Alarme und die meisten Graphen. irate() nutzt nur die letzten beiden Werte, reagiert schneller, ist aber unruhig und kann kurze Spitzen zwischen zwei Auswertungen verpassen.

histogram_quantile() benötigt die Bucket-Grenzen aus dem Label le, um ein Quantil zu schätzen. Wird le wegaggregiert, fallen alle Buckets zu einer Zeitreihe zusammen, und die Funktion kann nichts Sinnvolles berechnen.

Nein. SQL arbeitet mit Tabellen und Zeilen, PromQL mit gelabelten Zeitreihen und liefert Vektoren. Joins im SQL-Sinn gibt es nicht; binäre Operatoren ordnen Zeitreihen stattdessen über ihre Labels einander zu.

Ja, sofern das Backend OpenTelemetry-Metriken Prometheus-kompatibel speichert. Metriknamen werden dabei übersetzt, etwa Punkte zu Unterstrichen, und Einheiten oder ein Suffix _total können ergänzt werden, sofern das Backend nicht wie Prometheus 3 UTF-8-Namen unterstützt.

Setzen Sie das Wissen in die Praxis um

Testen Sie Obseria 14 Tage kostenlos, mit OpenTelemetry und ohne proprietäre Agenten.