Python 为什么Flask logger在前面使用UWSGI时不登录docker?

Python 为什么Flask logger在前面使用UWSGI时不登录docker?,python,docker,logging,flask,uwsgi,Python,Docker,Logging,Flask,Uwsgi,我在Docker中有一个Flask应用程序,当它在前面没有UWSGI的情况下运行时,它正在登录Docker日志。现在,我已经使用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

我在
Docker
中有一个
Flask
应用程序,当它在前面没有
UWSGI
的情况下运行时,它正在登录
Docker日志。现在,我已经使用
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
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
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
框架的部分位于项目根目录中的
\uuuu init\uuuuuuu.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
对象一起工作,我在
\uuu init\uuuuuuuuuupy
中配置了记录器,但问题是运行时它不会将任何内容记录到
Docker
,它只记录
UWSGI
请求

app.logger配置过程中出现了什么问题

问题已解决,但现在日志被复制


编辑-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
的输出是
[]
。它只显示了我之前初始化的StreamHandler,仅此而已


编辑-3:

ps-ef
命令在
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
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主机上使用所提到的dictConfig初始化,然后进行分叉。按照您的示例,在
\uuuu init\uuuuuu.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__)
您在编辑-1中提到的问题看起来像python。有一个独立的情况下,更容易调试

即使您只设置了一个流处理程序,如您的日志所示,它也可能附加了一个父处理程序。如果您检查其父级,它可能会附加一个与您在编辑-2中提到的处理程序不同的处理程序 :

回到您的案例(Flask),通过查看日志中的跟踪,有一个名为
Flask.app
的记录器,它是由创建的。分别有格式化版本和未格式化版本()。因此,它可能是在您的代码或导入的库中的某个地方初始化的

有多种方法可以解决此问题:

  • 将传播设置为false(简单的解决方案,但解决方法)
  • 搜索“无效”配置并将其删除
  • 按照Flask日志教程的建议,在实例化应用程序之前,使用dictConfig初始化
    • 我遇到了类似的问题(特别是:我想使用系统日志)。首先,我必须在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守护程序处理

      您是否有最小的docker映像/git repo或可以直接使用和调试的东西?短语“登录docker”值得指出的是,应用程序(uwsgi)只需要登录到STDOUT | STDERR,然后输出到docker日志。UWSGI我怀疑StreamHandler()正在写入一个文件或“类似文件”的文件,而容器并不在该文件中监视日志输出。@TarunLalwani目前没有日志输出,但我尝试在接下来的几天内创建一个。我在问题末尾提到的问题是,
      docker logs
      中有重复的日志。阅读编辑-2部分。@BoydHemphill第一个问题已经解决。如果你读了这个问题,你会发现我在docker日志中有重复日志的问题。阅读编辑-2部分plz。感谢@ALH的反馈,但是我看到了它标题的b/c,还没有找到答案。因此,我提供了一个原始问题的答案,以防其他人在这里找到他们的方式。如果你能提供原始问题的解决方案,那将非常有帮助!通过使用
      dictConfig
      ,app.logger可以按预期工作,我真的非常感谢。