我在Flask
内部有一个Docker
应用程序,该应用程序在运行时没有前面的docker logs
时登录到UWSGI
。现在,我将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
内配置的__init__.py
对象一起工作,但是问题在于,当Docker
是UWSGI
时,它不会将任何内容记录到app.logger.setLevel(logging.DEBUG)
中运行,它只记录Flask
个请求。
app.logger配置过程中出了什么问题?
问题已解决,但现在日志已重复!
EDIT-1:
我设置了Docker
,看来app.logger.setLevel(logging.DEBUG)
已成功登录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...
。奇怪的是它记录了3次!我删除了所有记录器配置和处理程序,仅使用了它:
app.logger.handlers
但是现在它记录了2次:
[<logging.StreamHandler object at 0x7f0f430ca8d0>]
为什么会这样?
EDIT-2:
ps -ef
的输出为Docker
。它只是显示了我之前初始化的StreamHandler,仅此而已。
EDIT-3:
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
命令的输出:
HWND
if (pUIAutomation) {
IUIAutomationElement *e = nullptr;
auto hr = pUIAutomation->ElementFromHandle(hwnd, &e);
}
内部没有其他进程在运行。
答案 0 :(得分:2)
首先,例如,Flask日志从版本0.9初始化到当前稳定的1.0.2的方式发生了一些变化。您可以检查此here。我假设您的Docker映像使用最新版本。
如果是这种情况,即使没有任何自定义日志配置,实际上它正在为您的输出流进行日志记录,但它的过滤率低于警告日志(DEBUG和INFO)。当您依靠Flask为您初始化日志并且没有设置--debug标志(uwsgi情况)时,会发生这种情况。
配置日志记录时可以查看多种策略。一种建议是在定义应用程序之前,先在uwsgi主机上使用library itself提到的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 logging propagation issue。有一个独立的案例,here更易于调试。
即使您只设置了一个流处理程序,如您的日志所示,它也可能附加了一个父级。如果您检查其父级,则可能会与您在 EDIT-2 中提到的处理程序不同相连。 :
print logger.handlers
[<logging.StreamHandler object at 0x7f15669c1550>]
print logger.parent.handlers
[<logging.StreamHandler object at 0x7f15669c1610>]
当启用日志记录传播并且在其他地方发生了一些日志记录初始化时,会发生这种情况。您可以通过查看python's source code中的callHandlers
来检查传播方式:
...
hdlr.handle(record)
if not c.propagate:
c = None #break out
else:
c = c.parent
...
回到案例(Flask),通过查看日志中的踪迹,可以找到一个名为flask.app
的记录器,它是由Flask itself创建的。有格式化的版本和未格式化的版本(logging.BASIC_FORMAT)。因此,它可能已在代码中的某个位置或导入的库之一中初始化了。
有多种方法可以解决此问题:
答案 1 :(得分:0)
我有一个类似的问题(特殊:我想使用系统日志)。首先,我必须向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处理