PromQL: Einführung
PromQL steht als Abkürzung für Prometheus Query Language und erlaubt es uns die von Prometheus erhobenen und gespeicherten Metriken abzufragen und zu analysieren.
Arten von Metriken
Hierzu muss man zunächst zwischen verschiedenen Arten von Metriken unterscheiden können, denn verschiedene Metriken erlauben verschiedenartige Analysen und Operationen:
- Gauge (Pegelstand): Hierbei handelt es sich um Momentaufnahmen, die den Stand zu einem bestimmten Zeitpunkt festhalten. Diese Metriken sind für sich alleine wenig hilfreich. Ihr Nutzen entsteht dadurch, dass man sie aggregiert, d.h. statistische Auswertungen mit ihnen anstellt oder die Metrik im zeitlichen Verlauf analysiert. Die Namen solcher Metriken enden oft auf eine Einheit wie
_bytesoder_seconds.- Beispiel:
node_filesystem_size_bytes, die Grösse eines Dateisystems in Bytes.
- Beispiel:
- Counter (Zähler): Hiermit werden Werte aufsummiert, wodurch die Metrik im zeitlichen Verlauf immer ansteigt. Interessanter als der absolute Wert, der für sich alleine schon eine aussagekräftige Kennzahl sein kann, ist die Wachstumsrate, die sich über eine bestimmte Zeitspanne berechnen lässt. Wendet man eine Ratenfunktion auf einen Zähler an, erhält man einen Pegelstand. Die Namen von Zählern haben oftmals die Endung
_total.- Beispiel:
node_network_receive_bytes_total, die Gesamtzahl der übers Netzwerk empfangenen Bytes.
- Beispiel:
- Summary (Statistiken): Diese Metriken trifft man i.d.R. paarweise an; die eine mit der Endung
_sum, die andere mit der Endung_count. Im Gegensatz zu Zählern ist nicht nur die Gesamtsumme und deren Zustandekommen von Interesse, sondern auch wie viele Ereignisse zu dieser Gesamtsumme beitragen. Wie ein Zähler lassen sich diese Metriken über die Anwendung einer Rate in einen Pegelstand umwandeln.- Beispiel:
http_response_size_bytes_sumundhttp_response_size_bytes_countgeben an, wie wiele HTTP-Antworten Prometheus abgeliefert hat und wie gross diese waren.
- Beispiel:
- Histogram (Histogramme): Diese Art von Metrik gruppiert Messwerte in sogenannte Buckets (Eimer), wodurch sich Erkenntnisse über die Verteilung der Daten gewinnen lassen. Für sie stehen spezielle Statistikfunktionen zur Verfügung. Die Namen der Metriken haben das Suffix
_bucket.- Beispiel:
prometheus_http_request_duration_seconds_bucketgibt die Verteilung der HTTP-Antwortzeiten von Prometheus mit Grenzwerten an.
- Beispiel:
Hierzu ein Überblick zum Nachschlagen:
| Art | Bedeutung | Suffixe | Beispiel |
|---|---|---|---|
| Gauge | Momentaufnahme | _[Einheit] | node_filesystem_size_bytes |
| Counter | kumulierte Werte | _total | node_network_receive_bytes_total |
| Summary | Statistiken | _sum & _count | http_response_size_bytes_[sum/count] |
| Histogramm | gruppierte Messwerte | _bucket | prometheus_http_request_duration_seconds_bucket |
Eine gute Informationsquelle für die Bedeutung einzelner Metriken ist Promhub.
Arten von Labels
Zu jeder Metrik wird neben dem Messwert und dem Zeitstempel eine Reihe von Labels miterhoben. Hierbei ist es wichtig, zwischen zwei Arten von Labels zu unterscheiden – denn PromQL behandelt diese exakt gleich:
- Target Labels: Diese Labels markieren, was gemonitored wird, d.h. speichern das Monitoring-Ziel. Die Labels
jobundinstance, die sich in der Prometheus-Konfiguration finden lassen, geben an, welches System gemonitored wird. Sie dienen der Unterscheidung der Objekte, die unter Überwachung stehen. - Instrumentation Labels: Hierbei handelt es sich um Kontextinformationen, die spezifisch für die jeweiligen Metriken sind. Die Metrik
node_filesystem_size_bytesverfügt beispielsweise über die Angabendevice(Gerät),mountpoint(Einhängepunkt) undfstype(Dateisystemtyp).
Für Aggregationen ist es nun wichtig, dass man nach gewissen Labels unterscheidet – und nach anderen nicht. Ein Beispiel illustriert dies am einfachsten.
Die folgende Abfrage bildet die Summe der Dateisystemgrössen:
Im Ergebnis wird nicht mehr nach den Targets (d.h. nach den Servern) unterschieden, sondern nur nach den verschiedenen Arten von Dateisystemen.
| Element | Value |
|---|---|
{device="/dev/vda1",fstype="ext4",mountpoint="/"} | 20712292352 |
{device="/dev/vda15",fstype="vfat",mountpoint="/boot/efi"} | 259436544 |
{device="tmpfs",fstype="tmpfs",mountpoint="/tmp"} | 487276544 |
Im Gegensatz dazu wird in der nächsten Abfrage wiederum die Summe der Dateisystemgrössen ermittelt:
Im Ergebnis wird nun nicht mehr nach den Metrik-Kontextinformationen (d.h. nach den Dateisystemen) unterschieden, sondern nur nach den einzelnen Instanzen:
| Element | Value |
|---|---|
{instance="159.100.250.46:9100",job="epimetheus"} | 10729502720 |
{instance="localhost:9100",job="localhost"} | 10729502720 |
Beide Server verfügen also in der Summe über exakt gleich grosse Dateisysteme.
Das Gegenteil von without ist by, welches aussagt, welche Labels beibehalten werden sollen:
Diese beiden Abfrage sind äquivalent.
Abfragetechniken
PromQL ist eine umfassende Abfragesprache, die verschiedene Techniken wie Filterung, Zeitfensterbildung, Berechnungen und Funktionsanwendungen unterstützt. Nicht jede Abfragetechnik lässt sich auf alle Arten von Metriken anwenden.
Filterung
Alle Metriken lassen sich anhand ihrer Labels filtern. Hierzu verwendet man Label-Wert-Paare in geschweiften Klammern, die einer Metrik hintenangestellt werden, z.B. {device="eth0"}.
Folgende Abfrage liefert die Grösse sämtlicher Dateisysteme auf allen Targets zurück:
Folgende Abfrage schränkt nach dem Dateisystemtyp (fstype) ext4 ein:
Dies erlaubt einen Vergleich aller ext4-Dateisysteme über die verschiedenen Server.
Folgende Abfrage schränkt nach einer bestimmten Instanz (instance) ein:
Dies erlaubt einen Vergleich aller Dateisysteme auf der jeweiligen Instanz.
Zur genauen Recherche lassen sich auch mehrere Filter kombinieren:
Die verschiedenen Kriterien werden mittels UND-Logik verknüpft.
Neben der Gleicheit (=) lässt sich auch auf Ungleichheit (!=) sowie auf das Passen (=~) bzw. Nichtpassen (!~) auf einen regulären Ausdruck prüfen.
Zeitfenster und Raten
Counter- und Summary-Metriken lassen sich zur Auswertung in Zeitfenster unterschiedlicher Grössen aufteilen, auf welche sich dann Raten mit der rate-Aggregierung berechnen lassen. Zeitfenster werden als Suffix in eckigen Klammern mit einem Zeitausdruck angegeben, z.B. [5m].
Der Zähler node_network_receive_bytes_total gibt die Anzahl der empfangenen Bytes zurück. Diese Metrik ist wenig aussagekräftig. Betrachtet man aber die Wachstumsrate, lassen sich Erkenntnisse über die Netzwerkauslastung gewinnen:
Die 5m bedeuten hier, dass eine Momentaufnahme der letzten 5 Minuten zurückgegeben werden soll. Es lassen sich u.a. folgende Suffixe verwenden:
s: Sekundenm: Minutenh: Stundend: Tage
Bei Summary-Metriken ist oftmals das Verhältnis zwischen der Summe und der Anzahl von Interesse:
Damit wird die durchschnittliche Antwortgrösse in den letzten 5 Minuten errechnet.
Möchte man nur die Metriken einer gerade vergangenen Zeitperiode betrachten, lässt sich dies mit der Funktion last_over_time bewerkstelligen:
Die obige Abfrage gibt die Anzahl der Prometheus-Metric-Requests der letzten vier Stunden (4h) zurück.
Quantile
Für Histogramme lassen sich die sogenannten Quantile ermitteln. Ein Beispiel: Die Histogramm-Metrik go_gc_heap_allocs_by_size_bytes_bucket sagt aus, wie viel Bytes Arbeitsspeicher pro Allokation reserviert werden. Das neunzigste Quantil dieser Metrik ermittelt nun einen Grenzwert mit folgender Aussagekraft:
- 90% der Allokationen reservieren weniger Speicher.
- 10% der Allokationen reservieren mehr Speicher.
Das Quantil lässt sich über die histogram_quantile-Funktion ermitteln:
Dadurch lassen sich Extremwerte ermitteln. Den Median errechnet man über das fünfzigste Quantil:
Aggregationen
Auf Momentaufnahmen und extrahierte Raten von Zählern und Statistiken lassen sich Aggregationsfunktionen wie die folgenden anwenden:
| Funktion | Bedeutung |
|---|---|
sum | Summe |
count | Anzahl verschiedener Ergebnisse |
avg | arithmetisches Mittel |
min | Minimum (kleinster Wert) |
max | Maximum (grösster Wert) |
quantile | Bestimmtes Quantil |
Hierzu einige Anwendungsbeispiele:
Operatoren: arithmetische und logische
Abfrageergebnisse lassen sich mit arithmetischen und logischen Funktionen weiterverarbeiten. Die folgende Abfrage rechnet die Dateisystemgrösse von Bytes in GB um:
Es stehen u.a. folgende Rechenoperationen zur Verfügung:
| Operator | Bedeutung |
|---|---|
+ | Addition |
- | Subtraktion |
* | Multiplikation |
/ | Division |
% | Modulo |
^ | Potenzierung |
Die folgende Abfrage gibt nur Dateisysteme zurück, die mindestens 1GB gross sind:
Es stehen u.a. folgende logische Operatoren zur Verfügung:
| Operator | Bedeutung |
|---|---|
== | Gleichheit |
!= | Ungleichheit |
> | grösser als |
< | kleiner als |
>= | grösser gleich |
<= | kleiner gleich |
Funktionen
Operatoren werden oft zusammen mit Funktionsergebnissen verwendet. Der aktuelle Zeitstempel lässt sich beispielsweise mit time() ermitteln. Auf frühere Zeitpunkte gelangt man, indem man von diesem Ergebnis subtrahiert:
Informationen über das aktuelle Datum enthält man über die folgenden Funktionen:
| Funktion | Rückgabewert |
|---|---|
year() | aktuelles Kalenderjahr |
month() | aktueller Kalendermonat |
day_of_month() | aktueller Kalendertag |
day_of_week() | aktueller Wochentag |
day_of_year() | aktueller Jahrestag |
days_in_month() | Anzahl Tage im aktuellen Monat |
hour() | aktuelle Stunde |
minute() | aktuelle Minute |
Solche Abfragetechniken lassen sich kombinieren, um sehr spezifische Erkenntnisse über das System zu gewinnen. Die folgende Abfrage ermittelt die Anzahl der CPU-Sekunden, die für den Benutzer und das System in den letzten dreissig Minuten auf dem Node localhost verwendet worden sind:
- Die Abfrage basiert auf der Metrik
node_cpu_seconds_total. - Es wird nach den Modi
userundsystemgefiltert, wozu ein regulärer Ausdruck verwendet wird. - Weiter wird auf die Instanz
localhost:9100gefiltert. - Es wird die Rate der letzten dreissig Minuten berücksichtigt.