
Bei der Arbeit an verschiedenen Mikrodiensten (und nicht so), die mit Symfony geschrieben wurden, stieß ich jedes Mal auf die Notwendigkeit, Metriken für Prometheus zu exportieren. Zuerst haben wir einfach denselben Code zwischen Projekten kopiert, aber als es mehr als drei davon gab, dachte ich, dass ich so nicht weitermachen könnte (ich werde nicht erklären, warum dies unpraktisch ist; ich denke, jeder versteht das selbst).
Es wurde beschlossen, diese gesamte Wirtschaft in ein separates Bündel
aufzuteilen :
ArtprimaPrometheusMetricsBundle .
Ich wählte gemeinsame Metriken für alle Anwendungen und begann ein Bundle zu schreiben. Der
Client wurde als
Jimdo / prometheus_client_php-Client ausgewählt , mit dem Sie als Statistikspeicher verwenden können: Redis (über ext-redis), APCu (über ext-apcu) und InMemory (im PHP-Speicher, nur für die Dauer des Prozesses). Ich werde sofort reservieren, dass nur APCu in der Praxis getestet wird (ich brauchte Statistiken pro Instanz, während es in Redis gemeinsame Statistiken gibt, es sei denn, Redis wird für jede Instanz bereitgestellt). Und InMemory im Allgemeinen, IMHO, kann nur für Tests verwendet werden.
Es gab sofort ein Problem mit Jimdo / prometheus_client_php - es gab lange Zeit keine Version und die erforderlichen Funktionen (APCu) sind nicht als Version verfügbar. In dieser Hinsicht habe ich
meine Abzweigung zum Client gemacht , was sich nur dadurch unterscheidet, dass er das richtige Tag zum Generieren der Version hat.
Das zweite Problem, auf das ich gestoßen bin, sind die Rezepte für Symfony. Sie müssen sich nicht einmal in das offizielle Repo einmischen, und Community-Anfragen für Pull-Anfragen werden sehr lange dauern (derzeit ist das Bundle fast einen Monat alt und das
PR-Rezept wird noch geprüft). In diesem Zusammenhang müssen Sie während der Installation die erforderlichen Einstellungen manuell vornehmen. Zum Glück gibt es nicht viele von ihnen.
Eigentlich müssen Sie die Hauptkonfiguration konfigurieren:
#config/packages/prometheus-metrics.yaml artprima_prometheus_metrics: # namespace prometheus namespace: myapp # type: in_memory # : in_memory, apcu, redis # , ignored_routes: [some_route_name, another_route_name] # "redis" ( ) redis: host: 127.0.0.1 port: 6379 timeout: 0.1 read_timeout: 10 persistent_connections: false password: ~
Dann müssen Sie die Route exportieren:
Oder Sie können die Route manuell konfigurieren:
app_metrics: path: /mypath/mymetrics controller: Artprima\PrometheusMetricsBundle\Controller\MetricsController::prometheus
Fertig. Infolgedessen sind Ihre Metriken unter http [s]: // your_host / metrics / prometheus verfügbar (wenn Sie den Pfad nicht geändert haben). Und nach einiger Zeit bekommen Sie so etwas:
Beispiel für Metriken# HELP myapp_http_2xx_responses_total total 2xx response count
# TYPE myapp_http_2xx_responses_total counter
myapp_http_2xx_responses_total{action="GET-app_ep1"} 3911
myapp_http_2xx_responses_total{action="GET-app_ep2"} 29974
myapp_http_2xx_responses_total{action="GET-app_ep3"} 323
myapp_http_2xx_responses_total{action="GET-app_ep4"} 18
myapp_http_2xx_responses_total{action="GET-app_ep5"} 3627
myapp_http_2xx_responses_total{action="GET-app_search"} 5962
myapp_http_2xx_responses_total{action="GET-app_ep8"} 42967
myapp_http_2xx_responses_total{action="GET-app_variants"} 641
myapp_http_2xx_responses_total{action="all"} 87423
# HELP myapp_http_4xx_responses_total total 4xx response count
# TYPE myapp_http_4xx_responses_total counter
myapp_http_4xx_responses_total{action="GET-app_ep2"} 71
myapp_http_4xx_responses_total{action="GET-app_ep8"} 2584
myapp_http_4xx_responses_total{action="all"} 2660
# HELP myapp_http_requests_total total request count
# TYPE myapp_http_requests_total counter
myapp_http_requests_total{action="GET-app_ep1"} 3922
myapp_http_requests_total{action="GET-app_ep2"} 30098
myapp_http_requests_total{action="GET-app_ep3"} 468
myapp_http_requests_total{action="GET-app_ep4"} 18
myapp_http_requests_total{action="GET-app_ep5"} 3631
myapp_http_requests_total{action="GET-app_search"} 5964
myapp_http_requests_total{action="GET-app_ep8"} 45556
myapp_http_requests_total{action="GET-app_variants"} 644
myapp_http_requests_total{action="all"} 90301
# HELP myapp_instance_name app instance name
# TYPE myapp_instance_name gauge
myapp_instance_name{instance="myapp-77c4d96744-cf9nz"} 1
# HELP myapp_request_durations_histogram_seconds request durations in seconds
# TYPE myapp_request_durations_histogram_seconds histogram
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.025"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.05"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.075"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.1"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.25"} 59
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.5"} 1915
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="0.75"} 3115
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="1"} 3553
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="2.5"} 3879
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="5"} 3911
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="7.5"} 3911
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="10"} 3911
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep1",le="+Inf"} 3911
myapp_request_durations_histogram_seconds_count{action="GET-app_ep1"} 3911
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep1"} 2413.185
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.025"} 50
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.05"} 62
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.075"} 63
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.1"} 72
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.25"} 914
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.5"} 2761
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="0.75"} 14326
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="1"} 23571
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="2.5"} 29569
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="5"} 30045
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="7.5"} 30045
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="10"} 30045
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep2",le="+Inf"} 30045
myapp_request_durations_histogram_seconds_count{action="GET-app_ep2"} 30045
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep2"} 26552.86
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.005"} 141
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.01"} 144
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.025"} 144
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.05"} 144
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.075"} 145
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.1"} 145
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.25"} 145
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.5"} 199
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="0.75"} 408
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="1"} 442
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="2.5"} 468
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="5"} 468
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="7.5"} 468
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="10"} 468
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep3",le="+Inf"} 468
myapp_request_durations_histogram_seconds_count{action="GET-app_ep3"} 468
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep3"} 216.495
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.025"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.05"} 4
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.075"} 10
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.1"} 13
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.25"} 16
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.5"} 17
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="0.75"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="1"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="2.5"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="5"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="7.5"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="10"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep4",le="+Inf"} 18
myapp_request_durations_histogram_seconds_count{action="GET-app_ep4"} 18
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep4"} 2.291
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.025"} 1
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.05"} 16
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.075"} 97
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.1"} 269
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.25"} 2308
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.5"} 3351
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="0.75"} 3566
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="1"} 3612
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="2.5"} 3627
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="5"} 3627
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="7.5"} 3627
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="10"} 3627
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep5",le="+Inf"} 3627
myapp_request_durations_histogram_seconds_count{action="GET-app_ep5"} 3627
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep5"} 959.773
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.025"} 18
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.05"} 547
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.075"} 968
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.1"} 1387
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.25"} 3784
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.5"} 5377
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="0.75"} 5811
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="1"} 5913
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="2.5"} 5959
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="5"} 5960
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="7.5"} 5960
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="10"} 5960
myapp_request_durations_histogram_seconds_bucket{action="GET-app_search",le="+Inf"} 5962
myapp_request_durations_histogram_seconds_count{action="GET-app_search"} 5962
myapp_request_durations_histogram_seconds_sum{action="GET-app_search"} 1516.982
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.025"} 2724
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.05"} 8348
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.075"} 18828
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.1"} 28811
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.25"} 39709
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.5"} 43958
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="0.75"} 45161
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="1"} 45436
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="2.5"} 45541
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="5"} 45549
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="7.5"} 45549
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="10"} 45549
myapp_request_durations_histogram_seconds_bucket{action="GET-app_ep8",le="+Inf"} 45551
myapp_request_durations_histogram_seconds_count{action="GET-app_ep8"} 45551
myapp_request_durations_histogram_seconds_sum{action="GET-app_ep8"} 6125.712
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.005"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.01"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.025"} 0
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.05"} 252
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.075"} 451
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.1"} 511
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.25"} 583
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.5"} 631
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="0.75"} 640
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="1"} 641
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="2.5"} 641
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="5"} 641
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="7.5"} 641
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="10"} 641
myapp_request_durations_histogram_seconds_bucket{action="GET-app_variants",le="+Inf"} 641
myapp_request_durations_histogram_seconds_count{action="GET-app_variants"} 641
myapp_request_durations_histogram_seconds_sum{action="GET-app_variants"} 62.744
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.005"} 145
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.01"} 148
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.025"} 2942
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.05"} 9378
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.075"} 20567
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.1"} 31213
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.25"} 47523
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.5"} 58214
myapp_request_durations_histogram_seconds_bucket{action="all",le="0.75"} 73050
myapp_request_durations_histogram_seconds_bucket{action="all",le="1"} 83191
myapp_request_durations_histogram_seconds_bucket{action="all",le="2.5"} 89707
myapp_request_durations_histogram_seconds_bucket{action="all",le="5"} 90224
myapp_request_durations_histogram_seconds_bucket{action="all",le="7.5"} 90224
myapp_request_durations_histogram_seconds_bucket{action="all",le="10"} 90224
myapp_request_durations_histogram_seconds_bucket{action="all",le="+Inf"} 90228
myapp_request_durations_histogram_seconds_count{action="all"} 90228
myapp_request_durations_histogram_seconds_sum{action="all"} 37850.074
Natürlich gibt es möglicherweise bald nicht mehr genügend grundlegende Metriken, sodass Sie immer die Möglichkeit haben, Ihren eigenen Metrikgenerator (zusätzlich zu dem vorhandenen) zu schreiben und wie folgt zu exportieren:
# config/services.yaml App\Metrics\MyMetricsGenerator: tags: - { name: prometheus_metrics_bundle.metrics_generator }
Gleichzeitig sollte Ihr Generator die
Artprima\PrometheusMetricsBundle\Metrics\MetricsGeneratorInterface
. Sie können sehen, wie der Generator unter
Artprima\PrometheusMetricsBundle\Metrics\AppMetrics
aussehen könnte. Das Wichtigste, was Sie hier wissen müssen, ist, dass die Methode
kernel.request
Ereignis
kernel.request
und die Methode
kernel.request
Ereignis
collectResponse
.
Ich akzeptiere Kritik im Wesentlichen. Sowohl in Form von Tipps als auch PR :-)
PS Warnung vor den Kommentaren, dass wir das Fahrrad erfunden haben: Ja, ich weiß, dass es Alternativen gibt. Und höchstwahrscheinlich sind sie sicherlich besser. Eines davon ist insbesondere das
TweedeGolfPrometheusBundle . Leider kann ich mich nicht erinnern, warum wir diese Lösung nicht gewählt haben, aber vor etwas mehr als sechs Monaten haben wir sie ausprobiert und abgelehnt. Auf die eine oder andere Weise glaube ich, dass es immer gut ist, eine Wahl zu haben, weshalb unser Bundle in OpenSource veröffentlicht wurde.