使用 Django、Nginx、Gunicorn 和主管进行空日志记录

Posted

技术标签:

【中文标题】使用 Django、Nginx、Gunicorn 和主管进行空日志记录【英文标题】:Empty logging with Django, Nginx, Gunicorn and supervisor 【发布时间】:2016-04-24 10:47:24 【问题描述】:

我在生产环境中的 django 登录有问题。我正在使用 nginx+Gunicorn+Supervisorctl 来运行我的 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 中注册得很好。现在,是时候将应用上传到生产环境了。

在生产中,我正在与主管一起运行 gunicorn。这是我使用主管运行 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,它是由主管生成的,仅包含有关进程启动的信息。 它是 /home/myuser/logs 中包含的唯一文件。

但是,HTTP 请求会显示在 /var/log/nginx/access.log 上,但即使 /var/log/nginx/errors.log 也不会显示来自我的任何错误或警告消息应用程序。

有什么想法吗?

【问题讨论】:

【参考方案1】:

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

nginx - access.log

这将记录任何来自 nginx 的请求,无论请求的性质或种类如何。

nginx - error.log

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

主管 - stdout_logfile 设置

此处提到的文件记录了主管在启动此条目时生成的任何消息。

主管 - stderr_logfile 设置

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

独角兽

gunicorn 有两个错误记录器 gunicorn.errorgunicorn.access,它们将记录在 gunicorn 下运行的应用程序的任何错误或标准输出/访问消息。

django 日志记录

这是第一个生成错误消息然后“向上移动”的地方。

因此,由于在堆栈的每一级都生成错误,它们要么由该组件处理,要么只是传递到下一个组件直到最后,如果 nothing 捕获到错误消息,它们可能会被全局操作系统错误记录器捕获,或者 - 在大多数情况下 - 被静默丢弃。

您的应用程序中的错误没有按照应有的方式执行的原因是因为您已使用 'disable_existing_loggers': True, 禁用了 django 配置中的所有其他记录器。

这也禁用了 gunicorn.errorgunicorn.access - 您的错误日志现在被丢弃,因为它们实际上是由 gunicorn 处理的,但是您的 django 配置禁用了记录器。

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

【讨论】:

非常感谢 Burhan,您的回答解决了我的问题。正如你提到的,我只需将disable_existing_loggers 设置为False。我尝试配置 gunicorn.errorgunicorn.access 日志但无法使它们工作......但不禁用现有记录器使我的日志现在可以顺利工作。再次感谢!【参考方案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

【讨论】:

以上是关于使用 Django、Nginx、Gunicorn 和主管进行空日志记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django、Nginx、Gunicorn 和主管进行空日志记录

django-gunicorn-nginx:502 网关错误

Django 不使用 NGINX + GUNICORN 提供静态文件

使用 nginx 和 gunicorn 运行多个 django 项目

如何使用 gunicorn 为 django 配置 nginx?

使用Nginx + Gunicorn + Django 方式部署django程序