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

Application Metrics with Prometheus

Application Metrics with Prometheus

Avatar for Daniel Heinrich

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