7.3 Prometheus

Inhalt

Intro

Im ersten Kapitel dieses Labs haben wir bereits kurz angeschaut, was Prometheus ist. Hier nochmals eine kurze Zusammenfassung der wichtigsten Punkte:

  • Prometheus ist eine Software, welche zur Überwachung von Systemen und Applikationen verwendet wird.
  • Prometheus ist ein metrikenbasiertes System, welches mit Time Series arbeitet.
  • Prometheus arbeitet immer pull basiert (Prometheus holt die Metriken beim zu überwachenden System).
  • Prometheus speichert die Metriken in einer Time Series Datenbank (TSDB) ab. Diese TSDB ist integraler Bestandteil des Prometheus Servers (es ist also nicht eine externe Datenbank).
  • Prometheus verfügt über ein Webinterface, um mit dem Prometheus Server zu interagieren (z.B. Abfragen ausführen).

Installation

Damit wir Hands on Erfahrung sammeln können, installieren wir Prometheus auf unserem lokalen Gerät. Dazu laden wir Prometheus über die Download-Seite herunter und entpacken die Dateien.

Die Befehle, Konfigurationen und Beschreibungen in diesem Lab beziehen sich auf die Prometheus Version 3.2.0. Um die gleichen Resultate zu erzielen empfehle ich dir, ebenfalls diese Version zu verwenden.

1
2
3
4
5
6
cd ~/Downloads
mkdir monitoring_lab
cd monitoring_lab
wget https://github.com/prometheus/prometheus/releases/download/v3.2.0/prometheus-3.2.0.linux-amd64.tar.gz
tar xzf prometheus-3.2.0.linux-amd64.tar.gz
cd prometheus-3.2.0.linux-amd64

Bearbeite nun die Konfigurationsdatei von Prometheus prometheus.yml und ersetze den Inhalt mit folgender Konfiguration:

1
2
global:
  scrape_interval: 15s

Starte Prometheus nun über folgenden Befehl:

1
./prometheus

Prometheus sollte nun starten und einige Logzeilen ausgeben:

1
2
3
4
rkupferschmid@fedora~/Downloads/monitoring_lab/prometheus-3.2.0.linux-amd64  ./prometheus
time=2025-02-21T07:30:59.996Z level=INFO source=main.go:640 msg="No time or size retention was set so using the default time retention" duration=15d
time=2025-02-21T07:30:59.996Z level=INFO source=main.go:687 msg="Starting Prometheus Server"
# hier folgen weitere Zeilen

Du kannst nun in einem Webbrowser auf die Seite http://localhost:9090/ navigieren und solltest folgende Ansicht erhalten:

Prometheus WebUI

Im Beispiel oben haben wir Prometheus mit folgender Konfiguration gestartet:

1
2
global:
  scrape_interval: 15s

Im letzten Kapitel Zeitreihen haben wir in unserem Gedankenexperiment die Raumtemperatur alle 10 Minuten gemessen. Das scrape_interval in dieser Konfiguration beschreibt genau dieses Intervall. Anstelle von 10 Minuten weisen wir Prometheus an, seine Messungen alle 15 Sekunden durchzuführen. Was in der Konfiguration nun noch fehlt, sind Anweisungen, was Prometheus messen soll. Bevor wir die Konfiguration mit den nötigen Zeilen ergänzen, schauen wir uns an, wie Prometheus mit den zu überwachenden Systemen kommuniziert.

Prometheus exposition format

Die Kommunikation zwischen Prometheus und den zu überwachenden Systemen erfolgt über HTTP(S) Aufrufe. Jedes zu überwachende System muss also über eine Art Webseite seine Metriken zur Verfügung stellen. Prometheus ruft anschliessend in regelmässigen Abständen (dem scrape_interval) diese Webseiten auf und speichert die darauf publizierten Metriken in der TSDB.

In der Terminologie von Prometheus bezeichnen wir diese Webseiten mit den Metriken als Targets. Der Vorgang vom Abfragen der Metriken bei einem Target bezeichnen wir als Scrape.

Damit Prometheus die Daten verarbeiten kann, müssen die Metriken im definierten Format zur Verfügung gestellt werden. Dieses Format wird hier im Detail beschrieben. Das Format sollte dir aus dem vorherigen Kapitel bekannt vorkommen.

Im Prometheus exposition format existieren einige optionale Parameter wie z.B. Kommentare (Zeilen welche mit # beginnen) oder Timestamps (Zeitstempel welche auf den Value einer Metrik folgen). Diese optionalen Parameter schauen wir uns später an. Für den Moment kannst du sie ignorieren.

Targets

Wir fügen nun ein erstes Target zur Prometheus Konfiguration hinzu. Prometheus stellt unter /metrics Metriken zur Verfügung. Wir können das überprüfen, indem wir im Browser folgende URL öffnen: http://localhost:9090/metrics . Du solltest unter dieser URL eine lange Liste von Metriken im oben beschriebenen Format erhalten.

Prometheus WebUI

Nun passen wir die Prometheus Konfiguration (prometheus.yml) wie folgt an:

1
2
3
4
5
6
7
8
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "prometheus"
    metrics_path: "/metrics"
    static_configs:
      - targets: ["localhost:9090"]

Wir definieren unter scrape_configs einen neuen Job mit dem Namen prometheus und unter static_configs eine Liste mit den Targets welche gescraped werden sollen. Mit metrics_path definieren wir, unter welchem Pfad die Metriken zur Verfügung gestellt werden. Der Wert /metrics ist dabei der Default, wir könnten in diesem Fall metrics_path theoretisch auch weglassen.

Jobs dienen dazu, zusammengehörige Targets zusammenzufassen. Wenn wir mehrere Prometheus Server hätten, könnten wir diese somit alle in der Liste der Targets eintragen (z.B. ["prometheus01:9090","prometheus02:9090"])

Damit die Änderungen angewendet werden, müssen wir den Prometheus Server Prozess beenden und neu starten. Falls Prometheus bei dir aktuell noch läuft, kannst du diesen über die Tastenkombination CTRL+C stoppen und anschliessend über ./prometheus neu starten. Navigiere anschliessend auf folgende URL http://localhost:9090/targets . Dort solltest du nun ein Target im State UP erkennen können:

Prometheus Targets

Falls das geklappt hat, scraped Prometheus nun alle 15 Sekunden seine eigenen Metriken.

Metrik Typen

Bevor wir zum Ende dieses Kapitels gelangen, widmen wir uns noch einem sehr wichtigen Thema: den unterschiedlichen Typen von Metriken. Öffne dazu nochmals die /metrics Seite von Prometheus . Dort findest du viele Kommentare mit folgender Syntax:

# TYPE <metric_name> gauge
...
# TYPE <metric_name> counter
...
# TYPE <metric_name> histogram
...
# TYPE <metric_name> summary

Es existieren also vier grundlegende Typen von Metriken. Wir beschränken uns in diesem Lab auf die zwei wichtigsten Typen counter und gauge.

⚠️ Die Metriken sämtlicher Typen verwenden immer float64 (64 bit Gleitkommazahl) als Datentyp. Die Metrik Typen haben also keinen Einfluss darauf, in welchem Format die Values der jeweiligen Metriken gespeichert werden. Der Metrik Typ ist eine rein theoretischer Wert, welcher definiert, wie sich eine Metrik verhält. Man sieht anhand des Namens oder des Values einer Metrik/Time Series also nicht zwingend, um welchen Typ es sich dabei handelt. Es gibt aber einige best practices, auf welche wir nun genauer eingehen.

Gauge

Gauges sind Metriken, deren Values sich sowohl nach oben als auch nach unten bewegen können. Ein klassisches Beispiel dafür ist eine Temperatur. Diese kann sich sowohl erhöhen als auch verringern. Auf der metrics Seite von Prometheus findest du z.B. die Metrik process_open_fds. Diese beschreibt, wie viele Dateien Prometheus aktuell gerade geöffnet hat. Wenn Prometheus zwei Dateien schliesst, verringert sich diese Metrik um zwei.

Counter

Counter sind Metriken, die ausschliesslich steigen und nicht abnehmen können. Ein typisches Beispiel ist eine Metrik, die die Anzahl der Aufrufe einer Anwendung oder Webseite zählt. Wenn du eine Webseite besuchst, wird dein Besuch in der Metrik erfasst. Selbst wenn du die Seite schliesst, bleibt der Zähler unverändert, da das Schliessen der Seite den bereits registrierten Besuch nicht rückgängig macht.

Gemäss den best practices von Prometheus sollten Counter Metriken immer eine Suffix von _total besitzen.

Counter reset

Counter stellen uns vor ein Problem. Angenommen, wir zählen die Besucher einer Webseite. Was passiert, wenn wir diesen Webserver rebooten? Wir haben grundsätzlich zwei Möglichkeiten:

  1. Wir merken uns vor dem Reboot, wie viele Requests wir bisher gezählt haben. Beim nächsten Request nach dem Reboot, erhöhen wir die Zahl vor dem Reboot um eins.
  2. Wir beginnen nach dem Reboot mit dem Zählen wieder bei 0.

Zuvor haben wir gelernt, dass Counter ausschliesslich steigen können. Das legt die Vermutung nahe, dass grundsätzlich Variante 1 verwendet wird. Das ist jedoch falsch. Auch Counter beginnen beim Start der Applikation immer bei 0. Dies bezeichnen wir als Counter Reset. Ein Counter Reset ist immer dann gegeben, wenn der Value einer Counter Metrik geringer ist, als der vorherige Value. Prometheus erkennt solche Counter Resets und kompensiert diese.

Folgende Grafiken sollen das Verhalten visualisieren:

(Quelle: Julius Volz, https://www.youtube.com/watch?v=7uy_yovtyqw ) Counter Reset 1

In diesem Bild sehen wir eine Counter Metrik mit Resets zwischen Minute 4 und 5 sowie 6 und 7. Führen wir nun ein PromQL Query (z.B. rate(<metric_name>[5m]), mehr dazu später im Kapitel 7.5) über diesen Zeitraum aus (grüner Bereich in der Grafik), korrigiert Prometheus die Samples:

(Quelle: Julius Volz, https://www.youtube.com/watch?v=7uy_yovtyqw ) Counter Reset 2

Die rate() wird anschliessend über die korrigierten Samples berechnet.

Die Kompensation von Counter Resets erfolgt immer erst zum Zeitpunkt des Abfragens einer Metrik.

Fazit

  • Das scrape_interval in der Prometheus Konfiguration definiert das Intervall, in welchem Metriken abgefragt werden
  • Die Targets sind die zu überwachenden Systeme. Diese Systeme stellen über HTTP(S) Metriken zur Verfügung.
  • Die Targets werden in der Prometheus Konfiguration definiert.
  • Änderungen an der Prometheus Konfiguration erfordern einen Neustart oder Reload (pkill -HUP prometheus) von Prometheus.
  • Prometheus kennt insgesamt vier Metriktypen (gauges, counter, histogram und summary). Alle Typen verwenden als Sample Wert immer float64 Gleitkommazahlen.
  • gauges sind Metriken, welche sich sowohl nach oben als auch nach unten bewegen können (z.B. Temperatur).
  • counter sind Metriken, welche ausschliesslich steigen (z.B. Anzahl HTTP Requests).

Wir haben nun ein Target konfiguriert und einige Metriken in unserem Prometheus. Im nächsten Kapitel schauen wir uns an, wie wir diese Daten mit PromQL abfragen können.

Zuletzt geändert March 11, 2025: fiy tpos (b06157f)