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

Empty logging with Django, Nginx, Gunicorn and supervisor

我的生产环境中的 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 中注册良好。现在,是时候将应用程序上传到生产环境了。

在生产中,我 运行ning 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,它是由主管生成的,只包含有关进程的信息启动。 它是 /home/myuser/logs.

中唯一包含的文件

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

有什么想法吗?

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

  • nginx - access.log

    这将记录所有到达 nginx 的请求,无论请求的性质或种类如何。

  • nginx - error.log

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

  • 主管 - stdout_logfile 设置

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

  • 主管 - stderr_logfile 设置

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

  • 独角兽

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

  • django 日志记录

    这是首先生成错误消息的地方,然后是 "moved up the chain"。

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

在您的应用程序中,您的错误没有按照应有的方式执行的原因是您已使用 'disable_existing_loggers': True,.

禁用了 django 配置中的所有其他记录器

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

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

刚刚配置的 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