如何在带有gunicorn的Python中使用日志记录模块

时间:2018-11-29 22:27:44

标签: python logging flask gunicorn

我有一个基于烧瓶的应用程序。在本地运行时,是从命令行运行的,但是在部署时,我是由具有多个工作人员的gunicorn启动的。

我想使用logging模块登录到文件。我为此找到的文档是https://docs.python.org/3/library/logging.htmlhttps://docs.python.org/3/howto/logging-cookbook.html

当我的应用程序可能与gunicorn一起启动时,我对使用日志记录的正确方法感到困惑。该文档解决了线程问题,但假设我可以控制主进程。困惑点:

logger = logging.getLogger('myapp')将在不同的gunicorn工作线程中返回相同的记录器对象吗?

如果我要将日志记录FileHandler附加到记录器以记录到文件,如何避免在不同的工作程序中多次执行此操作?

我的理解-可能是错误的-是,如果我只调用logger.setLevel(logging.DEBUG),它将通过root logger发送消息,该root logger的默认日志记录级别可能更高,并且可能会忽略调试消息,因此我还需要调用logging.basicConfig(logging.DEBUG)才能使调试消息通过。但是文档说不要从线程调用logging.basicConfig()。使用gunicorn时如何正确设置根日志记录级别?还是我不需要?

2 个答案:

答案 0 :(得分:1)

这是我典型的Flask / Gunicorn设置。注意Gunicorn是通过主管运行的。

wsgi_web.py。注意ProxyFix,以便从Nginx获取客户端的真实IP地址。

from werkzeug.contrib.fixers import ProxyFix
from app import create_app
import logging

gunicorn_logger = logging.getLogger('gunicorn.error')

application = create_app(logger_override=gunicorn_logger)
application.wsgi_app = ProxyFix(application.wsgi_app, num_proxies=1)

烧瓶应用程序工厂create_app

def create_app(logger_override=None):
    app = Flask(__name__)

    if logger_override:
        app.logger.handlers = logger_override.handlers
        app.logger.setLevel(logger_override.level)

    # more

    return app

主管conf中的Gunicorn命令(第4行),请注意,在这种情况下,--log-level参数已设置为info。请注意X-REAL-IP已通过访问权限--access-logformat

[program:web]
directory = /home/paul/www/example
environment = APP_SETTINGS="app.config.ProductionConfig"
command = /home/paul/.virtualenvs/example/bin/gunicorn wsgi_web:application -b localhost:8000 --workers 3 --worker-class gevent --keep-alive 10 --log-level info --access-logfile /home/paul/www/logs/admin.gunicorn.access.log --error-logfile /home/paul/www/logs/admin.gunicorn.error.log --access-logformat '%%({X-REAL-IP}i)s %%(l)s %%(u)s %%(t)s "%%(r)s" %%(s)s %%(b)s "%%(f)s" "%%(a)s"'
user = paul
autostart=true
autorestart=true

答案 1 :(得分:1)

每个工作程序都是一个独立的进程,具有自己的内存,因此您无法真正在不同工作程序之间共享同一记录器。

您的代码在这些工作程序中运行,因为主流程只关心管理工作程序。

  

主进程是一个侦听各种进程的简单循环   发出信号并做出相应反应。它管理正在运行的工人列表   通过收听诸如TTIN,TTOU和CHLD之类的信号。 TTIN和TTOU告诉   主人增加或减少在职工人的数量。

在Gunicorn本身中,有两种主要的运行模式

  • 同步
  • 异步

因此与线程处理不同,这是多处理。

  

但是,自Gunicorn 19起,线程选项可用于处理以下内容中的请求:   多线程。使用线程假定使用了gthread worker。

牢记这一点,记录代码将被编写一次,并且每次创建新工作程序时将被多次调用。您可以使用Singelton模式来确保在同一工作程序中使用同一记录器实例。


对于配置记录器本身,您只需要遵循设置根记录器级别和不同记录器级别的正常过程即可。

basicConfig()不会影响根处理程序(如果已设置):

  

如果根记录器已经为其配置了处理程序,则此功能不起作用。

要在根目录上显式设置级别

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(name)

然后可以在处理程序或记录器级别上设置级别。

handler = logging.handlers.TimedRotatingFileHandler(log_path, when='midnight', backupCount=30)                                                                                                             
handler.setLevel(min_level)

您可以检查此类似答案以记录相关的详细信息 Set logging levels

更多资源:

http://docs.gunicorn.org/en/stable/design.html