Dans cet article, un simple [Flask](http :) fonctionnant sur uWSGI + nginx //flask.pocoo.org/) Je vais vous expliquer comment j'ai fait cela avec un exemple qui rend l'application pleinement fonctionnelle dans la surveillance.
Prometheus était à l'origine un outil de surveillance dérivé de Google's Borgmon.
Dans un environnement natif, Borgmon s'appuie sur une découverte de services omniprésente et facile. Les services surveillés sont gérés par Borg et devraient être faciles à trouver. Par exemple, toutes les tâches sont exécutées dans un cluster d'utilisateurs spécifiques ou, pour des déploiements plus complexes, toutes les sous-tâches qui composent la tâche ensemble.
Chacun de ceux-ci pourrait être une cible unique pour que Borgmon récupère les données du point de terminaison
/ varz '', ainsi que du `` / metrics '' de Prometheus. Il s'agit généralement d'un serveur multithread écrit en C ++, Java, Go ou (moins fréquemment) Python.
Prométhée hérite de nombreuses hypothèses de Borgman sur son environnement. En particulier, la bibliothèque client suppose que les métriques proviennent de différentes bibliothèques et sous-systèmes de plusieurs threads d'exécution s'exécutant dans un espace d'adressage partagé, et du côté serveur, Prometheus a une cible. Supposons que vous soyez (probablement) un programme multithread.
Ces hypothèses ont été brisées dans de nombreux déploiements non Google, en particulier dans le monde Python. Ici, nous distribuons la requête à plusieurs travailleurs (en utilisant, par exemple, Django ou Flask). WSGI Il est courant de s'exécuter sur un serveur d'applications (chaque worker est un processus, pas un thread).
Dans un déploiement simple du client Prometheus Python pour les applications Flask exécutées sous uWSGI, chaque requête du serveur Prometheus à `` / metrics '' atteint un processus de travail différent, chacun avec son propre compteur, Exportez l'histogramme, etc. Par conséquent, les données de surveillance deviennent des ordures.
En fait, chaque éraflure sur un compteur particulier renvoie la valeur d'un ouvrier, pas la totalité du travail. La valeur doit sauter et vous dire que rien n'est utile pour l'ensemble de l'application.
Amit Saha a le même problème et Various Solutions -with-prometheus.html) est discuté dans un article détaillé. Comme décrit dans l'un des articles, le client Prometheus Python comprend un mode multi-processus destiné à gérer cette situation, et un exemple de motivation du serveur d'application est gunicorn.
Cela fonctionne en partageant le répertoire mmap () 'd dictictionaries entre tous les processus de l'application. Faire. Chaque processus effectue ensuite un calcul pour renvoyer une vue partagée de la métrique à l'échelle de l'application lorsqu'elle est récupérée par Prometheus.
Cela a quelques «en-têtes» inconvénients mentionnés dans la documentation. Les exemples incluent le manque de métriques Python gratuites par processus, le manque de prise en charge complète de certains types de métriques et les types de jauge légèrement plus complexes.
Les configurations de bout en bout sont également difficiles. Voici ce dont vous avez besoin et comment vous avez réalisé chaque partie de votre environnement. Espérons que cet exemple complet sera utile à quiconque effectuera un travail similaire à l'avenir.
Le répertoire partagé doit être passé au processus comme variable d'environnement
prometheus_multiproc_dir```
Passez en utilisant l'option uWSGI env. Voir uwsgi.ini.
Le répertoire partagé du client doit être effacé après le redémarrage de l'application. C'est un peu difficile à comprendre, mais dans les [Hardcoded Hooks] d'uWSGI (https://uwsgi-docs.readthedocs.io/en/latest/Hooks.html#the-hookable-uwsgi-phases) Utilisez un exec-asap
pour exécuter le script shell immédiatement après avoir lu le fichier de configuration et avant de faire quoi que ce soit d'autre (https: //uwsgi-docs.readthedocs. io / en / latest / Hooks.html # exec-run-shell-commands). Voir uwsgi.ini.
Ce script supprime et recrée le répertoire de données partagé du client Prometheus (https://github.com/hostedgraphite/pandoras_flask/blob/master/bin/clear_prometheus_multiproc).
Pour vérifier les autorisations appropriées, exécutez uwsgi en tant que `` root '' sous Supervisor (http://supervisord.org/) et supprimez privs dans uwsgi (https :: //github.com/hostedgraphite/pandoras_flask/blob/master/conf/uwsgi.ini#L18).
L'application doit définir le mode multi-processus du client Python. Cela a été fait principalement via Documents. https://github.com/prometheus/client_python#multiprocess-mode-gunicorn). Voir metrics.py. Il comprend également un middleware soigné (https://github.com/hostedgraphite/pandoras_flask/blob/master/pandoras_flask/metrics.py#L17) qui exporte les métriques Prometheus pour l'état de réponse et la latence. Veuillez noter que
uWSGI doit configurer l'environnement de l'application pour que l'application soit chargée après fork (). Par défaut, uWSGI tente d'économiser de la mémoire en chargeant l'application puis `` fork () ''. Cela a certainement l'avantage de Copy on Write (https://en.wikipedia.org/wiki/Copy-on-write), qui peut économiser beaucoup de mémoire. Cependant, il semble interférer avec le fonctionnement en mode multi-processus du client. C'est peut-être parce que Lock before fork () est appliqué comme ça. [option paresseux-apps] de uWSGI (https://uwsgi-docs.readthedocs.io/en/latest/articles/TheArtOfGracefulReloading.html?highlight=lazy-apps#preforking-vs-lazy-apps-vs-lazy) Vous pouvez l'utiliser pour charger l'application après la fourche, ce qui crée un environnement plus propre.
Celles-ci permettront aux points de terminaison `` / metrics '' des applications Flask exécutées sous uWSGI de fonctionner et d'être entièrement fonctionnels dans la démo pandoras_flask. Je pense que tu peux le faire.
Notez que la démo expose le point de terminaison métrique pour un autre port (https://github.com/hostedgraphite/pandoras_flask/blob/master/conf/nginx.conf#L28) à l'application appropriée. S'il vous plaît. Cela facilite l'accès à la surveillance sans que l'utilisateur n'y ait accès.
Dans votre déploiement, vous devriez pouvoir utiliser uwsgi_exporter pour obtenir plus de statistiques d'uWSGI lui-même.
Dans le billet de blog de Saha (https://echorand.me/your-options-for-monitoring-multi-process-python-applications-with-prometheus.html), la solution recommandée est locale [statsd]( Il décrit un ensemble d'alternatives en poussant des métriques via (https://github.com/etsy/statsd). Ce n'est pas vraiment ce que nous aimons.
En fin de compte, tout exécuter sous une orchestration de conteneur comme kubernetes fournit un environnement natif où Prometheus brille, qui est le Python existant. C'est un grand pas vers l'obtention d'autres avantages dans la pile d'applications.
L'étape intermédiaire la plus prométhéenne consiste peut-être à enregistrer chaque sous-processus individuellement en tant que cible de grattage. Il s'agit de [django-prometheus](https://github.com/korfuri/django-prometheus/blob/master/documentation/exports.md#exporting-metrics-in-a-wsgi-application-with-multiple-processes- L'approche adoptée par processus), mais l'approche proposée par «plage de ports» est un peu plus compliquée.
Dans notre environnement, vous pouvez mettre en œuvre cette idée de la manière suivante (vous pouvez toujours l'avoir):
Je ne pense pas que cette approche soit plus compliquée que l'utilisation du mode multi-processus du client Python, mais elle a sa propre complexité.
Gardez à l'esprit que le fait d'avoir une cible par travailleur provoque une explosion de séries chronologiques. Par exemple, dans ce cas, une seule métrique d'histogramme par défaut qui suit les temps de réponse des clients Python sur huit travailleurs générera environ 140 séries temporelles individuelles avant de les multiplier par d'autres étiquettes à inclure. Ce n'est pas un problème que Prometheus gère, mais sachez que la mise à l'échelle peut augmenter (ou augmenter).
Pour le moment, exporter des métriques de la pile d'applications Web Python standard vers Prometheus est un peu compliqué. Nous espérons que cet article sera utile à tous ceux qui souhaitent se familiariser avec l'application nginx + uwsgi + Flask existante.
Lors de l'exécution de plus de services sous l'orchestration de conteneurs (ce que nous essayons de faire), nous nous attendons à ce qu'il soit plus facile d'intégrer la surveillance Prometheus avec eux.
Un utilisateur bien établi de Prometheus est [Hosted Prometheus](https://try.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Pandora's%20Flask%3A%20Monitoring%20a%20Python%20 Nous vous recommandons de jeter un œil aux services de 20 avec% 20 Prométhée). [Démo](https://calendly.com/metricfire-chatwithus/chat?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Pandora's%20Flask%3A%20Monitoring%20a%20Python%20web%20app%20with% nécessaire) N'hésitez pas à nous le dire.
Recommended Posts