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 .
Vous pouvez trouver dans le dépôt GitHub qui exécute une instance et avec une application de démonstration pour générer des métriques qui ressembleront à ceci :

Vous trouverez également une liste des indicateurs dans 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 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):
passDans 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 statutflask_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 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 .
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: 5sVoir l'exemple complet dans . 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 ou .
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
— Cet exportateur Flask pour Prometheus
— Utilisation, exemples et paramètres de configuration
— Exemples de configuration de surveillance des applications Flask de différentes manières
— Ce projet sur PyPI
— La bibliothèque cliente officielle de Prometheus pour Python
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
