Surveillance des microservices Flask avec Prometheus

Quelques lignes de code et votre application génère des métriques, wow !

Afin de comprendre comment fonctionne prometheus_ballon_exportateur, un exemple minimal suffit :

from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics

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

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

C'est tout ce dont vous avez besoin pour commencer ! En ajoutant un import et une ligne d'initialisation PrometheusMetrics, vous obtiendrez des métriques durée de la demande и compteurs de requêtes, affiché au point de terminaison /métrique l'application Flask avec laquelle il est enregistré, ainsi que toutes les métriques par défaut que vous obtenez de la base Bibliothèque cliente Prometheus.

tu peux trouver exemple facile à utiliser dans le dépôt GitHub qui exécute l'instance Prométhée и grafana ainsi qu'une application de démonstration pour générer des métriques qui ressembleront à ceci :

Surveillance des microservices Flask avec Prometheus

Vous trouverez également une liste d'indicateurs dans README exemples qui apparaissent dans le tableau de bord, ainsi que les requêtes Prometheus qui remplissent les tableaux de bord.

réglage

Il existe de nombreuses options de configuration dans la bibliothèque, regardez README projetez-en des exemples avec une brève explication.

La configuration de base est présentée ci-dessus. Créez simplement une instance PrometheusMetrics, appelons-le métrique, puis utilisez-le pour définir les métriques supplémentaires que vous souhaitez collecter en décorant les fonctions :

  • @metrics.counter(..)

  • @metrics.gauge(..)

  • @metrics.summary(..)

  • @metrics.histogram(..)

Les compteurs comptent les appels et d'autres collectent des mesures en fonction de la durée de ces appels. Vous pouvez définir des étiquettes pour chacun d'entre eux, éventuellement à l'aide de propriétés de requête ou de réponse. Par exemple:

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)

# group by endpoint rather than path
metrics = PrometheusMetrics(app, group_by='endpoint')

@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
    'cnt_collection', 'Number of invocations per collection', labels={
        'collection': lambda: request.view_args['collection_id'],
        'status': lambda resp: resp.status_code
    })
def get_item_from_collection(collection_id, item_id):
    pass

Dans l'exemple ci-dessus, en cliquant sur le point de terminaison /collection/10002/item/76 fera incrémenter le compteur, par exemple cnt_collection{collection = "10002", statut = "200"}, et vous obtiendrez les métriques par défaut (pour chaque point de terminaison dans cet exemple) de la bibliothèque par défaut :

  • flask_http_request_duration_seconds — Durée des requêtes HTTP en secondes pour toutes les requêtes Flask par méthode, chemin et statut

  • flask_http_request_total — Nombre total de requêtes HTTP par méthodes et statuts

Il existe des options pour ignorer le suivi de points de terminaison spécifiques, enregistrer des métriques par défaut supplémentaires ou ignorer celles répertoriées ci-dessus, ou appliquer la même métrique personnalisée à plusieurs points de terminaison. Vérifier README projet pour voir ce qui est disponible.

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

@app.route('/')
def main():
    pass  # requests tracked by default

@app.route('/skip')
@metrics.do_not_track()
def skip():
    pass  # default metrics are not collected

# custom metric to be applied to multiple endpoints
common_counter = metrics.counter(
    'by_endpoint_counter', 'Request count by endpoints',
    labels={'endpoint': lambda: request.endpoint}
)

@app.route('/common/one')
@common_counter
def endpoint_one():
    pass  # tracked by the custom and the default metrics

@app.route('/common/two')
@common_counter
def endpoint_two():
    pass  # also tracked by the custom and the default metrics

# register additional default metrics
metrics.register_default(
    metrics.counter(
        'by_path_counter', 'Request count by request paths',
        labels={'path': lambda: request.path}
    )
)

La bibliothèque dispose d'extensions pratiques pour les bibliothèques multitraitements populaires telles que uWSGI et Gunicorn. Vous pouvez également trouver de petits exemples de cas d’utilisation ciblés, notamment le multitraitement.

Collecte de métriques

Comme mentionné ci-dessus, la bibliothèque fournit un point de terminaison par défaut /métrique dans une application Flask, qui peut servir de cible à Constructeur de Prométhée.

Dans l'exemple de tableau de bord ci-dessus, vous pouvez cibler votre Prometheus vers une application Flask avec des paramètres par défaut avec cette configuration :

scrape_configs:
  - job_name: 'example'

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

Voir l'exemple complet sur Dépôts GitHub. Cela suppose que Prometheus puisse trouver vos instances d'application Flask sur http://app:5000/metrics, où le nom de domaine de l'application pourrait potentiellement être résolu en plusieurs adresses IP, par exemple lors d'une exécution dans Kubernetes ou Docker Swarm.

Si exposer le point de terminaison des métriques de cette manière ne vous convient pas, peut-être parce que vous ne souhaitez pas autoriser l'accès externe à celui-ci, vous pouvez facilement le désactiver en passant chemin=Aucun lors de la création d'une instance 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)

Ensuite, vous pouvez utiliser start_http_server(port)pour ouvrir ce point de terminaison sur un autre port HTTP, 5099 dans l'exemple ci-dessus. Alternativement, si vous êtes satisfait du fait que le point de terminaison se trouve dans la même application Flask, mais que vous devez modifier son chemin de /métrique, vous pouvez soit transmettre un autre URI comme paramètre de chemin, soit utiliser registre_endpoint(..)pour l'installer plus tard.

références

Si vous décidez de l'essayer, n'hésitez pas à ouvrir un ticket sur GitHub ou à laisser vos commentaires, retours et suggestions !

Je vous remercie!

Source: habr.com

Ajouter un commentaire