Django、Nginx、Gunicorn和supervisor出现空日志记录问题

4

我在生产环境中使用Nginx+Gunicorn+Supervisorctl运行我的Django网站,但是在Django日志记录方面遇到了问题。我已经尝试了两天几乎所有的方法,但没有任何结果。

我的想法是在我的Django应用程序中定义两个日志文件。一个用于存储所有的日志记录(messages.log),另一个用于存储WARNING、ERROR和CRITICAL级别的日志记录(errors.log)。

LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
    'verbose': {
        'format': ' [%(asctime)s] [%(levelname)s] [%(name)s] %(message)s'
    },
    'simple': {
        'format': ' %(levelname)s %(message)s'
    },
},
'handlers': {
    'console': {
        'level': 'DEBUG',
        'class': 'logging.StreamHandler',
        'formatter': 'verbose'
    },
    'file': {
        'level': 'DEBUG',
        'class': 'logging.FileHandler',
        'formatter': 'verbose',
        'filename': '/home/myuser/logs/messages.log'
    },
    'file_errors': {
        'level': 'WARNING',
        'class': 'logging.FileHandler',
        'formatter': 'verbose',
        'filename': '/home/myuser/logs/errors.log'
    },
    'mail_admins': {
        'level': 'ERROR',
        'class': 'django.utils.log.AdminEmailHandler',
        'include_html': True
    }
},
'loggers': {
    'main': {
        'handlers': ['console', 'file', 'file_errors', 'mail_admins'],
        'level': 'DEBUG'
    },
    'caching': {
        'handlers': ['console', 'file', 'file_errors'],
        'level': 'DEBUG'
    }
}

使用这个日志配置,我可以通过以下命令在我的Django应用程序中注册日志记录:
logger = logging.getLogger("main")
logger.info("INFO message")
logger.critical("CRITICAL message")

这些命令在我的开发环境中已经注册成功,详细信息可以在messages.log和errors.log中查看。现在,是时候将应用程序上传到生产环境了。

在生产环境中,我使用supervisor运行gunicorn。以下是我使用supervisor运行gunicorn的配置:

[program:gunicorn_app]
command=gunicorn --bind 172.31.19.71:8000 -c /home/myuser/app/gunicorn.conf.py -p /home/myuser/app/gunicorn.pid wsgi:application
directory=/home/myuser/app
user=myuser
autostart=true
stdout_logfile = /home/myuser/logs/app_supervisor
stderr_logfile = /home/myuser/logs/app_error_supervisor
autorestart=true
redirect_stderr=true

如您所见,我正在使用一个gunicorn的配置文件,其内容如下:

from __future__ import unicode_literals 
import multiprocessing

bind = "unix:%(proj_path)s/gunicorn.sock"
workers = 4
proc_name = "app_proc"

最终的Nginx配置如下:

server {

    listen 80;
    server_name www.myapp.com;
    client_max_body_size 10M;
    keepalive_timeout    15;
    error_log /home/myser/logs/app_error_nginx.log info;

    ...
}

当我运行我的应用程序时,唯一生成的日志文件是/home/myuser/logs/app_supervisor,这是由supervisor生成的,仅包含有关进程启动的信息。它是/home/myuser/logs中唯一的文件。
但是,HTTP请求显示在/var/log/nginx/access.log上,但即使/var/log/nginx/errors.log也不显示来自我的应用程序的任何错误或警告消息。
有什么想法吗?
2个回答

12

我认为了解所有组件以及它们实际记录的内容是很有好处的。

  • nginx - access.log

    此日志将记录到达nginx的任何请求,无论请求的性质或种类如何。

  • nginx - error.log

    此日志将记录来自您已配置的任何后端(在nginx语言中称为“上游”)服务器的错误;如果它们未处理这些错误。换句话说,如果上游服务器未配置日志并将所有日志发送到stderr,则最终将捕获并记录在error.log中。

  • supervisor - stdout_logfile 设置

    此文件记录了supervisor启动此条目时生成的任何消息。

  • supervisor - stderr_logfile 设置

    如果supervisor在启动配置的进程时遇到错误,则会在此处记录。

  • gunicorn

    gunicorn有两个错误记录器gunicorn.errorgunicorn.access,将记录在gunicorn下运行的应用程序的任何错误或stdout/access消息。

  • django记录

    这是错误消息生成的第一个位置,然后将其“向上移动”。

因此,当您的堆栈的每个级别生成错误时,它们会由该组件处理,或者仅向上传递到下一个组件,直到最后,如果没有捕获错误消息,则可能被全局操作系统错误记录器捕获或 - 在大多数情况下 - 静默丢弃。

您的应用程序中错误未能正常运行的原因是因为您使用'disable_existing_loggers': True,在django配置中禁用了所有其他记录器。

这也禁用了gunicorn.errorgunicorn.access - 您的错误日志现在正在被gunicorn处理,但您的django配置已禁用了记录器。

只需在您的settings.py中添加这两个记录器的适当配置,或将disable_existing_loggers设置为False,然后重新启动gunicorn进程,一切都应该正常工作。


1
非常感谢Burhan,你的回答解决了我的问题。正如你所提到的,我只需要将disable_existing_loggers设置为False即可。我尝试配置gunicorn.errorgunicorn.access日志,但无法使它们工作...但是不禁用现有的记录器现在使我的日志平稳运行。再次感谢! - educalleja

2
我刚刚配置了Django(1.10.6),以便将服务器错误(500)重定向。
# settings.py
from django.utils.log import DEFAULT_LOGGING

# Use defaults as the basis for our logging setup
LOGGING = DEFAULT_LOGGING

# Used to log on supervisor
LOGGING['handlers']['console']['filters'] = ['require_debug_false']
LOGGING['loggers']['django.server']['propagate'] = True

接着查看服务器错误(500):

tailf /home/myuser/logs/app_supervisor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接