[英]Why Flask logger does not log in docker when using UWSGI in front?
我在Docker
中有一个Flask
应用程序,它在前面没有UWSGI
情况下运行时登录到UWSGI
docker logs
。 现在我已经使用UWSGI
和下面的配置在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
uwsgi_fantas.py
文件包含:
from fantas.fantas_app import FantasApp
app = FantasApp().setup()
setup
方法返回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
最后启动Flask
框架的部分在项目根目录的__init__.py
里面:
from flask import Flask
import logging
app = Flask(__name__)
s_handler = logging.StreamHandler()
s_handler.setLevel(logging.DEBUG)
app.logger.addHandler(s_handler)
由于UWSGI
直接与app
对象UWSGI
工作,我在__init__.py
配置了记录器,但问题是它在运行时不会将任何内容记录到Docker
,它只记录UWSGI
请求。
app.logger 配置过程中出现了什么问题?
问题已解决,但现在日志重复了!
EDIT-1:我设置了app.logger.setLevel(logging.DEBUG)
并且Flask
似乎成功登录到Docker
。 奇怪的是它记录了 3 次! 我删除了所有记录器配置和处理程序,只使用了:
app.logger.setLevel(logging.DEBUG)
但现在它记录了 2 次:
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...
为什么会这样?
编辑-2:
app.logger.handlers
的输出是[<logging.StreamHandler object at 0x7f0f430ca8d0>]
。 它只显示我之前初始化的 StreamHandler,仅此而已。
编辑 3:
Docker
中ps -ef
命令的输出:
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
Docker
内部没有其他进程在运行。
首先,最近 Flask 日志的初始化方式发生了变化,例如从 0.9 版本到当前稳定的 1.0.2。 你可以在这里查看。 我假设您的 docker 镜像使用最新版本。
如果是这种情况,即使没有任何自定义日志记录配置,实际上它也在为您的输出流记录日志,但它过滤掉的日志低于警告日志(调试和信息)。 当您依赖 Flask 为您初始化日志并且您没有设置 --debug 标志(uwsgi 案例)时,就会发生这种情况。
配置日志记录时可以查看多种策略。 一个建议是在定义应用程序之前,在 uwsgi master 上使用库本身提到的 dictConfig 初始化,然后分叉。 按照你的例子,在__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__)
您在EDIT-1 中提到的问题看起来像 python 日志传播问题。 有一个独立的情况下,更容易调试, 在这里。
即使您只设置了一个 Stream Handler,如您的日志所示,它也可能附加了一个父级。 如果您检查其父级,它可能会附加一个与您在EDIT-2 中提到的不同的处理程序:
print logger.handlers
[<logging.StreamHandler object at 0x7f15669c1550>]
print logger.parent.handlers
[<logging.StreamHandler object at 0x7f15669c1610>]
当启用日志传播并且在其他地方发生了一些日志初始化时,就会发生这种情况。 您可以通过查看python 源代码中的callHandlers
来检查传播是如何工作的:
...
hdlr.handle(record)
if not c.propagate:
c = None #break out
else:
c = c.parent
...
回到你的案例(Flask),通过查看日志中的痕迹,有一个名为flask.app
的记录器,它是由Flask 本身创建的。 分别有格式化版本和未格式化版本( logging.BASIC_FORMAT )。 因此,它可能在您的代码或您导入的库之一中的某处进行了初始化。
有多种方法可以解决这个问题:
我有一个类似的问题(特别:我想使用系统日志)。 首先,我必须向 Dockerfile 添加一条规则:
RUN apt-get install -y rsyslog
service rsyslog start
Flask 带有内置日志记录,所以我只需要添加一些树枝
from flask import Flask
import logging
import logging.handlers
handler = logging.handlers.SysLogHandler(address = '/dev/log')
handler.setFormatter(logging.Formatter('flask [%(levelname)s] %(message)s'))
app = Flask(__name__)
app.logger.addHandler(handler)
可以通过 syslog-daemon 处理其他设置
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.