使用 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.error
和 gunicorn.access
,它们将记录 gunicorn 下 运行 应用程序的任何错误或 stdout/access 消息。
django 日志记录
这是首先生成错误消息的地方,然后是 "moved up the chain"。
因此,由于在堆栈的每一层都会产生错误,它们要么由该组件处理,要么简单地传递到下一个组件,直到最后,如果 nothing 捕获错误消息,它们可能会被全局 OS 错误记录器捕获,或者 - 在大多数情况下 - 被静默丢弃。
在您的应用程序中,您的错误没有按照应有的方式执行的原因是您已使用 'disable_existing_loggers': True,
.
禁用了 django 配置中的所有其他记录器
这也禁用了 gunicorn.error
和 gunicorn.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
我的生产环境中的 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.error
和gunicorn.access
,它们将记录 gunicorn 下 运行 应用程序的任何错误或 stdout/access 消息。django 日志记录
这是首先生成错误消息的地方,然后是 "moved up the chain"。
因此,由于在堆栈的每一层都会产生错误,它们要么由该组件处理,要么简单地传递到下一个组件,直到最后,如果 nothing 捕获错误消息,它们可能会被全局 OS 错误记录器捕获,或者 - 在大多数情况下 - 被静默丢弃。
在您的应用程序中,您的错误没有按照应有的方式执行的原因是您已使用 'disable_existing_loggers': True,
.
这也禁用了 gunicorn.error
和 gunicorn.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