Surveillance des microservices Flask avec Prometheus

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

Pour comprendre comment fonctionne prometheus_flask_, 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 l'importation et la ligne pour l'initialisation PrometheusMetrics, vous obtiendrez des métriques de la durée des requêtes et des compteurs de requêtes, affichés à l'endpoint /metrics de l'application Flask où elle est enregistrée, ainsi que toutes les métriques par défaut que vous obtenez de la bibliothèque cliente de base Prometheus.

Vous pouvez trouver un exemple facile à utiliser dans le dépôt GitHub qui exécute une instance Prometheus et Grafana avec 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 des indicateurs dans README l'exemple, qui sont affichés sur le tableau de bord, ainsi que les requêtes Prometheus qui remplissent les panneaux.

Configuration

La bibliothèque offre de nombreuses options de configuration, consultez README le projet pour leurs exemples avec une brève explication.

La configuration de base est montrée ci-dessus. Il suffit de créer une instance PrometheusMetrics, appelons-la metrics, et ensuite, utilisez-la pour définir des 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, tandis que les autres collectent des métriques en fonction de la durée de ces appels. Vous pouvez définir des étiquettes pour chacun d'eux, potentiellement en utilisant des propriétés de la requête ou de la réponse. Par exemple :

from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics

app = Flask(__name__)

# regrouper par endpoint plutôt que par chemin
metrics = PrometheusMetrics(app, group_by='endpoint')

@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
    'cnt_collection', 'Nombre d'appels par 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, toucher l'endpoint /collection/10002/item/76 augmentera le compteur, par exemple cnt_collection{collection = "10002", status = "200"}, plus vous obtiendrez des métriques par défaut (pour chaque endpoint dans cet exemple) de la bibliothèque par défaut :

  • flask_http_request_duration_seconds — Durée de la requête 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 certains points de terminaison, enregistrer des métriques supplémentaires par défaut ou ignorer celles mentionnées ci-dessus, ou appliquer la même métrique personnalisée à plusieurs points de terminaison. Consultez README le projet pour savoir ce qui est disponible.

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

@app.route('/')
def main():
    pass  # requêtes suivies par défaut

@app.route('/skip')
@metrics.do_not_track()
def skip():
    pass  # les métriques par défaut ne sont pas collectées

# métrique personnalisée à appliquer à plusieurs points de terminaison
common_counter = metrics.counter(
    'by_endpoint_counter', 'Nombre de requêtes par points de terminaison',
    labels={'endpoint': lambda: request.endpoint}
)

@app.route('/common/one')
@common_counter
def endpoint_one():
    pass  # suivi par les métriques personnalisées et par défaut

@app.route('/common/two')
@common_counter
def endpoint_two():
    pass  # également suivi par les métriques personnalisées et par défaut

# enregistrer des métriques supplémentaires par défaut
metrics.register_default(
    metrics.counter(
        'by_path_counter', 'Nombre de requêtes par chemins de requête',
        labels={'path': lambda: request.path}
    )
)

La bibliothèque dispose d'extensions conviviales pour les bibliothèques multi-processus populaires telles que uWSGI et Gunicorn. Vous pouvez également trouver de petits exemples d'utilisations cibles, y compris multi-processus.

Collecte de métriques

Comme mentionné précédemment, la bibliothèque fournit par défaut un point de terminaison /metrics dans l'application Flask, qui peut servir de cible pour le collecteur Prometheus..

Dans l'exemple ci-dessus avec le tableau de bord, vous pouvez cibler votre Prometheus sur l'application Flask avec la configuration par défaut suivante :

scrape_configs:
  - job_name: 'exemple'

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

Voir l'exemple complet dans le dépôt GitHub. Cela suppose que Prometheus peut trouver vos instances d'application Flask sur http://app:5000/metrics, où le nom de domaine de l'application peut potentiellement se résoudre en plusieurs adresses IP, par exemple, lorsqu'il fonctionne dans Kubernetes ou Mais cela signifie-t-il que vous pouvez utiliser le même fichier docker-compose dans.

Si cette exposition du point de terminaison des métriques ne vous convient pas, peut-être parce que vous ne voulez pas permettre l'accès extérieur à celui-ci, vous pouvez facilement la désactiver en passant path=None lors de la création de l'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)

Vous pouvez ensuite 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 à l'aise avec le fait que le point de terminaison se trouve dans la même application Flask, mais que vous devez changer son chemin à partir de /metrics, vous pouvez soit fournir un autre URI en tant que paramètre de chemin, soit utiliser register_endpoint(..), pour le définir plus tard.

Liens

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

Merci!

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster