Überwachung von Flask-Mikrodiensten mit Prometheus

Ein paar Zeilen Code und Ihre Anwendung generiert Metriken, wow!

Um zu verstehen, wie prometheus_ funktioniert,flask_, benötigt man ein minimales Beispiel:

from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)
metrics = PrometheusMetrics(app)

@app.route('/')
def main():
    return 'OK'

Das ist alles, was Sie für den Anfang brauchen! Fügen Sie den Import und die Initialisierungszeile hinzu für PrometheusMetrics, dann erhalten Sie Metriken zur Dauer von Anfragen und Anfragerate, die am Endpunkt /metrics der Flask-Anwendung, in der es registriert ist, sowie alle Standardmetriken angezeigt werden, die Sie von der grundlegenden Prometheus-Clientbibliothek.

Sie können ein benutzerfreundliches Beispiel finden im GitHub-Repository, das eine Instanz startet Prometheus und Grafana zusammen mit einer Demoversion zur Generierung von Metriken, die etwa so aussehen werden:

Überwachung von Flask-Mikrodiensten mit Prometheus

Sie finden auch eine Liste der Metriken in README dem Beispiel, die im Dashboard angezeigt werden, zusammen mit den Prometheus-Anfragen, die die Panels füllen.

Einstellungen

Die Bibliothek bietet viele Konfigurationsoptionen, schauen Sie in README die Projektbeispiele mit kurzen Erklärungen.

Die Grundkonfiguration ist oben gezeigt. Erstellen Sie einfach eine Instanz PrometheusMetrics, nennen wir sie Metriken, und definieren Sie dann mit ihm die zusätzlichen Metriken, die Sie sammeln möchten, indem Sie Funktionen dekorieren:

  • @metrics.counter(..)

  • @metrics.gauge(..)

  • @metrics.summary(..)

  • @metrics.histogram(..)

Zähler zählen Aufrufe, während die anderen Metriken basierend auf der Dauer dieser Aufrufe sammeln. Sie können Labels für jedes von ihnen definieren, indem Sie eventuell Eigenschaften der Anfrage oder Antwort verwenden. Zum Beispiel:

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)

# Gruppiere nach Endpunkt statt nach Pfad
metrics = PrometheusMetrics(app, group_by='endpoint')

@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
    'cnt_collection', 'Anzahl der Aufrufe pro Sammlung', labels={
        'collection': lambda: request.view_args['collection_id'],
        'status': lambda resp: resp.status_code
    })
def get_item_from_collection(collection_id, item_id):
    pass

Im obigen Beispiel führt ein Aufruf des Endpunkts /collection/10002/item/76 zu einer Erhöhung des Zählers, zum Beispiel cnt_collection{collection = «10002», status = «200»}, zudem erhalten Sie Standardmetriken (für jeden Endpunkt in diesem Beispiel) aus der Standardbibliothek:

  • flask_http_request_duration_seconds — Dauer des HTTP-Requests in Sekunden für alle Flask-Anfragen nach Methode, Pfad und Status

  • flask_http_request_total — Gesamtzahl der HTTP-Anfragen nach Methoden und Status

Es gibt Optionen, um das Tracking bestimmter Endpunkte zu überspringen, zusätzliche Standardmetriken zu registrieren oder die oben genannten zu überspringen oder dieselbe benutzerdefinierte Metrik auf mehrere Endpunkte anzuwenden. Informieren Sie sich über README das Projekt, um herauszufinden, was verfügbar ist.

app = Flask(__name__)
metrics = PrometheusMetrics(app)

@app.route('/')
def main():
    pass  # Anfragen werden standardmäßig verfolgt

@app.route('/skip')
@metrics.do_not_track()
def skip():
    pass  # Standardmetriken werden nicht gesammelt

# benutzerdefinierte Metrik, die auf mehrere Endpunkte angewendet wird
common_counter = metrics.counter(
    'by_endpoint_counter', 'Anzahl der Anfragen nach Endpunkten',
    labels={'endpoint': lambda: request.endpoint}
)

@app.route('/common/one')
@common_counter
def endpoint_one():
    pass  # verfolgt durch die benutzerdefinierten und die Standardmetriken

@app.route('/common/two')
@common_counter
def endpoint_two():
    pass  # ebenfalls verfolgt durch die benutzerdefinierten und die Standardmetriken

# zusätzliche Standardmetriken registrieren
metrics.register_default(
    metrics.counter(
        'by_path_counter', 'Anzahl der Anfragen nach Anfragepfaden',
        labels={'path': lambda: request.path}
    )
)

Die Bibliothek bietet praktische Erweiterungen für gängige Multiprozessorbibliotheken wie uWSGI und Gunicorn. Sie finden auch kleine Beispiele für Anwendungsfälle, einschließlich multiprozessorer Anwendungen.

Metriken sammeln

Wie oben erwähnt, bietet die Bibliothek standardmäßig einen Endpunkt /metrics in der Flask-Anwendung, der als Ziel für den Prometheus-Sammler dienen kann..

In dem oben genannten Beispiel mit dem Dashboard können Sie Ihren Prometheus auf die Flask-Anwendung mit den Standardkonfigurationen mit folgender Konfiguration richten:

scrape_configs:
  - job_name: 'example'

    dns_sd_configs:
      - names: ['app']
        port: 5000
        type: A
        refresh_interval: 5s

Siehe das vollständige Beispiel in dem GitHub-Repository. Das setzt voraus, dass Prometheus Ihre Instanzen der Flask-Anwendung unter http://app:5000/metrics, wo der Domänenname der Anwendung potenziell auf mehrere IP-Adressen aufgelöst werden kann, z. B. im Betrieb in Kubernetes oder Docker Swarm.

Wenn ein solches Offenlegen des Metriken-Endpunkts Ihnen nicht zusagt, möglicherweise weil Sie keinen externen Zugriff darauf erlauben möchten, können Sie es leicht deaktivieren, indem Sie path=None beim Erstellen der Instanz übergeben. PrometheusMetrics.

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)
metrics = PrometheusMetrics(app, path=None)

...

metrics.start_http_server(5099)

Anschließend können Sie start_http_server(port), um diesen Endpunkt auf einem anderen HTTP-Port zu eröffnen, 5099 im obigen Beispiel. Alternativ, wenn Sie damit einverstanden sind, dass der Endpunkt in derselben Flask-Anwendung bleibt, aber seinen Pfad ändern müssen von /metrics, Sie können entweder eine andere URI als Pfadparameter übergeben oder verwenden register_endpoint(..), um dies später festzulegen.

Links

Wenn Sie es ausprobieren möchten, zögern Sie nicht, ein Issue auf GitHub zu eröffnen oder Ihre Kommentare, Feedback und Vorschläge zu hinterlassen!

Danke!

Quelle: habr.com

60GB SSD 8Gb DDR4