J'ai une application Flask
à l'intérieur de Docker
qui se connectait à docker logs
Lorsqu'elle s'exécutait sans UWSGI
devant. Maintenant, j'ai utilisé UWSGI
avec la configuration ci-dessous pour exécuter mon application à l'intérieur de Docker
:
[uwsgi]
master = true
processes = 5
threads = 2
socket = 127.0.0.1:3031
chmod-socket = 664
stats=0.0.0.0:30310
chdir = /etc/fantas
uid = root
gid = root
wsgi-file=uwsgi_fantas.py
callable=app
vacuum = true
Le fichier uwsgi_fantas.py
Contient:
from fantas.fantas_app import FantasApp
app = FantasApp().setup()
La méthode setup
renvoie app
:
from flask_restful import Api
from fantas import app
class FantasApp(object):
def setup(self):
api = Api(app)
api.add_resource(Token, '/users')
return app
Enfin la partie qui initie le framework Flask
est à l'intérieur de __init__.py
Dans le répertoire racine du projet:
from flask import Flask
import logging
app = Flask(__name__)
s_handler = logging.StreamHandler()
s_handler.setLevel(logging.DEBUG)
app.logger.addHandler(s_handler)
Comme UWSGI
fonctionne directement avec l'objet app
, j'ai configuré l'enregistreur à l'intérieur de __init__.py
, Mais le problème est qu'il ne se connecte à rien dans Docker
quand il est exécuté, il enregistre simplement les requêtes UWSGI
.
Qu'est-ce qui ne va pas dans le processus de configuration de app.logger?
Le problème a été résolu, mais maintenant les journaux sont dupliqués!
EDIT-1: J'ai défini app.logger.setLevel(logging.DEBUG)
et il semble que Flask
se connecte avec succès à Docker
. La partie bizarre est qu'il se connecte 3 fois! J'ai supprimé toutes les configurations et les gestionnaires d'enregistreurs et j'ai simplement utilisé:
app.logger.setLevel(logging.DEBUG)
Mais maintenant, il se connecte 2 fois:
proj_fantas.1.huagnqqpzo1n@linuxkit-025000000001 | [2018-07-13 07:02:38,008] DEBUG in token: [Token] authenticating user...
proj_fantas.1.huagnqqpzo1n@linuxkit-025000000001 | DEBUG:flask.app:[Token] authenticating user...
Pourquoi c'est comme ça?
EDIT-2:
La sortie de app.logger.handlers
Est [<logging.StreamHandler object at 0x7f0f430ca8d0>]
. Cela montre simplement le StreamHandler que j'ai initialisé plus tôt, rien de plus.
EDIT-3:
La sortie de la commande ps -ef
À l'intérieur de Docker
:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 10 1 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 12 1 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 13 1 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 15 1 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 16 1 0 15:26 ? 00:00:00 uwsgi uwsgi_coconuty.ini
root 20 0 0 15:27 pts/0 00:00:00 /bin/bash
root 112 20 0 15:28 pts/0 00:00:00 ps -ef
Aucun autre processus n'est en cours d'exécution à l'intérieur de Docker
.
Tout d'abord, il y a eu des changements récents dans la façon dont Flask sont initialisés de la version 0.9 à la version stable 1.0.2, par exemple. Vous pouvez vérifier cela ici Je suppose que votre image Docker utilise la version la plus récente.
Si tel est le cas, même sans configuration de journalisation personnalisée, il s'agit en fait de la journalisation de votre flux de sortie, mais il est filtré plus bas que les journaux WARNING (DEBUG et INFO). Cela se produit lorsque vous comptez sur Flask initialisant le journal pour vous et que vous ne définissez pas d'indicateur --debug (cas uwsgi).
Il existe plusieurs stratégies qui peuvent être examinées lorsque vous configurez la journalisation. Une suggestion est d'utiliser l'initialisation dictConfig mentionnée par la bibliothèque elle-même , au niveau du maître uwsgi, avant de définir l'application, qui bifurque ensuite. En suivant votre exemple, à __init__.py
:
from flask import Flask
from logging.config import dictConfig
dictConfig({
'version': 1,
'formatters': {'default': {
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
}},
'handlers': {'wsgi': {
'class': 'logging.StreamHandler',
'formatter': 'default'
}},
'root': {
'level': 'DEBUG',
'handlers': ['wsgi']
}
})
app = Flask(__name__)
Le problème que vous mentionnez dans EDIT-1 ressemble à un python problème de propagation de la journalisation . Il existe un cas autonome, plus facile à déboguer, ici .
Même si vous n'avez défini qu'un seul gestionnaire de flux, comme le montre votre journal, il a probablement un parent attaché. Si vous vérifiez son parent, un gestionnaire sera probablement attaché différent de celui que vous avez mentionné dans EDIT-2 :
print logger.handlers
[<logging.StreamHandler object at 0x7f15669c1550>]
print logger.parent.handlers
[<logging.StreamHandler object at 0x7f15669c1610>]
Cela se produit lorsque la propagation de la journalisation est activée et qu'une initialisation de la journalisation s'est produite ailleurs. Vous pouvez vérifier le fonctionnement de la propagation en regardant callHandlers
in le code source de python :
...
hdlr.handle(record)
if not c.propagate:
c = None #break out
else:
c = c.parent
...
De retour à votre cas (Flask), en regardant les traces dans vos logs, il y a un logger nommé flask.app
, qui est celui créé par Flask lui-même . Il y a la version formatée et la version non formatée ( logging.BASIC_FORMAT ), respectivement. Il est donc probablement en cours d'initialisation quelque part dans votre code ou dans l'une des bibliothèques que vous importez.
Il existe plusieurs façons de résoudre ce problème: