Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Application Metrics with Prometheus

Application Metrics with Prometheus

Daniel Heinrich

February 04, 2022
Tweet

More Decks by Daniel Heinrich

Other Decks in Programming

Transcript

  1. Ergebnisgröße, Dauer, Anzahl … von HTTP- Requests, Querries … Veränderliche

    Messwerte: CPU/Memory Verbrauch, Postfachgröße … Antwortzeiten Perzentil, Apdex Score Counter Gauges Histogramms
  2. App-Metriken mit Spring-Boot • Nutzt Micrometer für Instrumentalisierung (wie SLF4J

    für Logging) • Erhebt Metriken für: JVM, CPU, File desciptors, Logging, Uptime, Server/Client HTTP Requests, DB Connection-Pool • Konfigurierbar in application.yml
  3. Micrometer • Abstrahiert Metrikspeicher der verwendet wird (Nameskonvention, Basiseinheiten, Arten

    von unterstützten Metriken, Server vs. Client Aggregierung) • Wrapper u. Annotations um Metriken von Methoden zu sammeln • Micrometer Metriken sind zum Teil zusammengesetzte Metriken. Timer misst Ausführdauer einer Funktion 3 x Counter: Anzahl Aufrufe, Summe Ausführdauer, Maximale Ausführdauer 1 x Histogramm (Optional) LongTaskTimer Fortschritt einer langlaufenden Aufgabe 2 x Gauges: Anzahl laufender Task, bisherige Ausführdauer
  4. Micrometer Counter Erfassen var dbRetryCounter = Counter.builder("cqrs.dbRetry") .description("Retries von DB-Zugriffen");

    void countDbRetry(String updaterName, String error) { Counter retries = dbRetryCounter.tag("updater", updaterName) .tag("cause", error) .register(appMetrics.getRegistry()); retries.increment(); }
  5. Micrometer Timer Erfassen var updaterBuilder = Timer.builder("cqrs.updater") .description("Abarbeitungsdauer"); Timer getTimerForUpdate(AenderungsUpdater<?>

    updater) { return updaterBuilder.tags( "readmodel", updater.getConfig().readModel(), "type", "single" ).register(appMetrics.getRegistry()); } var timer = getTimerForUpdate(updater); updater.update(id) .transform(appMetrics.recordSuccess(timer));
  6. Prometheus •Pull basiert •Eine Executable •Unabhängige einzelne Instanz •Effiziente lokale

    Timeseries DB •Services anstatt Maschinen •Multidimensional (Name + Key/Value, http_request hat Dimension status_code)
  7. Zeitreihen 2019-10-14T13:53:03+00:00 102,42 timestamp Messwert Datenverbrauch in Byte des ES

    Index „kunden- suche“ auf dem Node 13.12.0.65 im Cluster „azure“ in der PROD Umgebung.
  8. Zeitreihen Metadaten Prometheus: Job (Konfiguration), Instance (IP Adresse) Kubernetes Pod

    Name, Docker-Image, Labels Metrikspezifisch URL, Memory Area, Readmodel Berechnet Umgebung (DEV, UAT, PROD)
  9. Zeitreihen Best-Practises •Anzahl u. Kardinalität von Labels gering halten Beispiel

    „http_requests“: 4 Methoden x 6 Status-Codes x 20 URLs x 3 Instanzen 1.440 Zeitreihen •Keine Konstanten Labels in App setzten
  10. Metrikvisualisierung • Dashboards mittels Grafana • Abfragen mittels PromQL max(time()

    - process_start_time_seconds{umgebung="prod"}) / 86400 Metrikname max(time() - process_start_time_seconds{umgebung="prod"}) / 86400 max(time() - process_start_time_seconds{umgebung="prod"}) / 86400 Label-Selektor max(time() - process_start_time_seconds{umgebung="prod"}) / 86400 BultIn-Funktion max(time() - process_start_time_seconds{umgebung="prod"}) / 86400 Aggregation Scalar Vector
  11. Selektieren von Zeitreihen •Auswahl anhand Labelwerten (Metrikname auch nur ein

    Label) •Gleichheit: =, != •Regex(RE2) Matches: =~, !~ Leider kein Support für: backreferences, look ahead/behind, recursion, conditional branches
  12. Reihenaggregierung sum, min, max, avg, stddev, stdvar, count, count_values, bottomk,

    topk, quantile Gruppierung mittels by(labels, …) / without avg(memory_used_bytes) by (image) sum(http_requests_total) without (instance, task_id)
  13. Range-Vectors !"#$%&#%'()*+,-./0/.!+&#1*-./2/ Gleiche Aggregierungsfunktionen wie von Instant-Vectors: avg, sum, min,

    max, … system_cpu_usage{instance="130.215.44.22:4034"}[1m] max_over_time(system_cpu_usage{instance="130.215.44.22:4034"}[3m])
  14. Range-Vectors 3&%*.411+*1&%"5#$6)#7%"5#. rate(v range-vector) calculates the per-second average rate of

    increase of the time series in the range vector. Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for • Nur für Counter • Für Gauges: deriv(v) nähert die Steigung • Zur visualisierung: increase(v) rate(v) * <Sekunden in der Zeitspanne v>
  15. Vektor-Binäroperationen filesystem_data_free_bytes / filesystem_data_size_bytes ? • Labels der Zeitreihe müssen

    sich exakt entsprechen. • Labels können optional ignoriert werden • Auch many-to-one & one-to-many möglich
  16. Lessions Learned • Spring-Konfiguration neuer Metriken • Marathon-Konfiguration um Metriken

    neuer Services einzusammeln • Metriken werden als Zeitreihen in Prometheus gespeichert • PromQL Abfragen • Unterschied von Instant & Range Vektoren • Welche Labels in Ergebnisreihen erhalten bleiben • Wie und wofür man die Rate Funktion verwendet
  17. Weitere Themen • PromQL • Histogramme • Offset (z.B. Vergleiche

    Metriken zum Vortag) • BuiltIn Funktionen • Prometheus Konfiguration • Alerts / Rules • Reporter • Silences
  18. Weiterführende Informationen PromQL: https://prometheus.io/docs/prometheus/latest/querying/basics/ Metrik Typen • https://prometheus.io/docs/concepts/metric_types/ • https://micrometer.io/docs/concepts#_meters

    Instrumentation • https://prometheus.io/docs/practices/instrumentation/ • https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-metrics Histogramme • https://prometheus.io/docs/practices/histograms/ • https://micrometer.io/docs/concepts#_histograms_and_percentiles