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

问题描述 投票:0回答:3

我有一个基于 Flask 的应用程序。当我在本地运行它时,我从命令行运行它,但是当我部署它时,我使用带有多个工作人员的gunicorn来启动它。

我想使用

logging
模块来记录到文件。我为此找到的文档是herehere

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

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

如果我将日志记录

FileHandler
附加到记录器以便记录到文件,如何避免在不同的工作人员中多次执行此操作?

我的理解(可能是错误的)是,如果我只是调用

logger.setLevel(logging.DEBUG)
,这将通过根记录器发送消息,根记录器可能具有更高的默认日志记录级别,并且可能会忽略调试消息,因此我also需要调用
logging.basicConfig(logging.DEBUG)
为了让我的调试消息能够通过。但文档说不要从线程中调用
logging.basicConfig()
。使用gunicorn时如何正确设置根日志记录级别?还是我不需要?

python logging gunicorn
3个回答
12
投票

这是我典型的 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)

编辑 2020 年 2 月,对于较新版本的 werkzeug,请使用以下内容并根据需要将参数调整为

ProxyFix

from werkzeug.middleware.proxy_fix 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, x_for=1, x_host=1)

Flask应用工厂

create_app

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

    if logger_override:

        # working solely with the flask logger
        app.logger.handlers = logger_override.handlers
        app.logger.setLevel(logger_override.level)

        # OR, working with multiple loggers

        # for logger in (app.logger, logging.getLogger('sqlalchemy')):
        #     logger.handlers = logger_override.handlers
        #     logger.setLevel(logger_override.level)

    # more

    return app

supervisor 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

2
投票

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

您的代码在这些工作人员内部运行,因为主进程只关心管理工作人员。

主进程是一个简单的循环,用于监听各种进程 发出信号并做出相应反应。它管理正在运行的工人列表 通过监听 TTIN、TTOU 和 CHLD 等信号。 TTIN 和 TTOU 告诉 master增加或减少正在运行的worker的数量。

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

  • 同步
  • 异步

所以这与线程不同,这是多处理。

但是从 Gunicorn 19 开始,可以使用线程选项来处理请求 多线程。使用线程假定使用 gthread 工作线程。

考虑到这一点,日志记录代码将编写一次,并在每次创建新工作人员时调用多次。您可以使用 Singelton 模式来确保同一工作线程内使用相同的记录器实例。


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

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

如果根记录器已为其配置了处理程序,则此函数不会执行任何操作。

要显式设置 root 的级别,请执行以下操作

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

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

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

您可以检查此类似答案以获取记录相关详细信息 设置日志记录级别

更多资源:

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


0
投票

默认情况下,Gunicorn 仅配置

gunicorn.error
记录器。您可以使用
logconfig_dict
选项或其等效项
来更改此设置。

创建文件

gunicorn.conf.py
:

logconfig_dict = {
    "root": {"handlers": ["error_console"], "level": "INFO"},
    "loggers": {},
}

这将配置根记录器以记录到 stderr。使用

gunicorn.glogging.CONFIG_DEFAULTS
中配置的默认处理程序。
loggers
必须指定为空字典,以避免在加载
logconfig_dict
之前覆盖gunicorn的记录器。

如果该文件位于当前工作目录中,Gunicorn 将自动加载该文件。或者,使用

-c /path/to/gunicorn.conf.py
选择配置文件。

如果您想避免创建单独的配置文件,请尝试以下命令行参数:

gunicorn --log-config-json <(echo '{"root": {"handlers": ["error_console"], "level": "INFO"}, "loggers": {}}')

您需要空

loggers
键以避免来自 Gunicorn 本身的重复日志消息。

© www.soinside.com 2019 - 2024. All rights reserved.