首页 文章

uWSGI异步函数不需要't know about Django'的日志记录设置

提问于
浏览
3

我们正在使用uWSGI来为我们的Django应用程序提供服务 . 我们还利用uWSGI的mules和假脱机程序系统定期运行作业,并在请求/响应周期之外异步执行某些任务 .

处理HTTP请求的uWSGI部分使用Django logging configuration就好了 . 但是,当使用uWSGI的 cronmulefunc 功能时, Logger 通常会赢得't be configured at all -- you' ll调用log.error(),异常就会消失 . 我们发现了一个奇怪的解决方法,我将在下面解释 .

以下是我们的日志记录设置,在 settings.py 中 . 默认情况下,StreamHandler路由到stderr,因此我们应该看到任何级别为DEBUG且更高级别的日志都路由到stderr .

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'NOTSET',
        }
    }
}

这是一个不起作用的例子:

from uwsgidecorators import mulefunc

log = logging.getLogger(__name__)

@timer(10, target="mule")
def test_mule_logging(signum):
    log.error("You'll never see this message")

但是,有一个非常奇怪的解决方法 . 如果你导入Django的设置,并且访问它上面的一个键,那么 Logger 将神奇地工作 . 例如:

from django.conf import settings
getattr(settings, "doesntmatter", None)

from uwsgidecorators import timer
import logging

log = logging.getLogger(__name__)

@timer(10, target="mule")
def test_mule_logging(signum):
    log.error("I WILL see this log!")

这似乎是一个可怕的解决方法 .

1 回答

  • 0

    我认为你描述的行为是有道理的 .

    在普通工作者中,uwsgi加载一个WSGI应用程序,使django加载设置,并作为其中一部分配置全局Python日志记录系统 . 由django app运行并包含日志记录语句的库代码最终由日志记录配置处理(无需知道django存在或配置了日志记录系统) .

    在mule中,uwsgi只运行您提供的代码,而不是为常规worker定义的wsgi模块/脚本,因此没有任何内容正在配置日志系统 . 骡子仍然在相同的环境中运行(uid,gid,chdir,virtualenv,pythonpath,像DJANGO_SETTINGS_MODULE这样的env vars),因此调用 django.setup() (或 django.configure_settings )将导入您的设置并配置全局日志系统(全局到Python进程,是骡子 Worker ,修复你的记录电话 .

    最后一块拼图: django.conf.settings 模块是一个特殊的懒惰对象,因此在django完成自身配置之前可以通过各种模块导入它,并推迟真正加载设置,直到某些东西试图访问模块属性 . 在具有 django.setup() 的现代Django版本中可以更明确地获得此行为 .

相关问题