将Django请求日志记录到文件而不是控制台

6
我正在尝试配置我的Django settings.py,以正确使用Python日志记录工具,但我遇到了一个非常奇怪的问题:
即使阅读了文档,我仍然无法找出如何将Django打印的控制台调试请求行重定向到我指定的文件;以下是我的日志记录配置的一部分。
LOGGING = {
    'version': 1,
    'formatters': {
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    }
    'handlers': {
        'file_http': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': r'C:\mysystem-http.log',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['file_http'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}

我经常在控制台看到以下格式的打印行:
[19/Dec/2014 11:48:03] "POST /api/v1/ HTTP/1.1" 200 10
如何使用日志记录功能将其重定向到文件?
提前致谢。

仅供参考:如果您有多进程设置,则记录到文件可能不是一个好主意,请参阅 https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes - bruno desthuilliers
3个回答

6

manage.py runserver没有使用日志系统来记录像[19/Dec/2014 11:48:03] "POST /api/v1/ HTTP/1.1" 200 10这样的消息。相反,runserver使用sys.stderr(和sys.stdout用于其他消息)。如果您确实需要将其重定向到文件,则可以覆盖settings.py中的sys.stderr设置。示例-将sys.stderr记录到文件和控制台:

import sys

class Logger(object):
    def __init__(self):
        self.console = sys.stderr
        self.file = open("runserver.log", "a", 0)

    def write(self, msg):
        self.console.write(msg)
        self.file.write(msg)

sys.stderr = Logger()

在write方法中,您可以使用日志系统通过LOGGING设置来处理此问题。
更新:
在Django 1.10中,runserver输出经过日志记录: https://docs.djangoproject.com/en/dev/releases/1.10/#runserver-output-goes-through-logging

这种方法比bash重定向更好吗? - Benjamin Toueg
简单来说,这并不是更好的选择(也许其中一个原因是你可以同时将日志记录到文件和控制台,并添加过滤器/格式化等功能)。 - dikamilo

3
这些输出由您的HTTP服务器处理(如果在开发模式下运行,则使用标准库中的WSGIServer)。
您的settings.py文件的配置与此无关。

好的。那么,有没有一种方法可以使用日志记录功能重定向该库的输出? - stratis
这取决于你的技术栈。 - Benjamin Toueg

0

@dikamilo的答案是正确的。

在Django 1.10之前,manage.py runserver运行的是Django自己的WSGIServer实现,该实现将日志记录到sys.stderr。

将以下代码添加到settings.py中将通过猴子补丁方式修改runserver使用的WSGIRequestHandler,以便所有请求都通过logging模块记录,并使用名称django.server,以大致模仿Django 1.10+的行为。

###############################################################################
# SUPER-JANK PATCH FOR DJANGO RUNSERVER LOGGING PRIOR TO VERSION 1.10
###############################################################################
#
# Add this to settings.py
#
import logging
from django.core.servers.basehttp import WSGIRequestHandler
logger = logging.getLogger('django.server')
def log_message(self, format, *args):
    # Don't bother logging requests for admin images or the favicon.
    if self.path.startswith(self.admin_static_prefix) or self.path == '/favicon.ico':
        return
    msg = format % args
    if args[1][0] in ['1', '4', '5']:
        logger.warn(msg)
    else:
        logger.info(msg)

WSGIRequestHandler.log_message = log_message

它替换了log_message方法,该方法负责实际写入stderr
添加此补丁后,您可以像通常在settings.py中使用LOGGING一样配置日志记录。

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