如何更改 Django 日志记录的日期格式?

use*_*531 5 python django logging

此处答案中的注释说您应该能够自定义登录 Django 的日期格式:

请注意,如果您使用 dictConfig 方法来配置日志记录(例如,如果您使用的是 Django),您可以使用格式化程序的“datefmt”字典键来设置它。请参阅:Django 日志配置,日志模块:字典架构详细信息

但是,它不起作用:

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'django.server': { # duplicate of default for django.server
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
            'datefmt' : '%Y-%m-%d %H:%M:%S'
            }
}
Run Code Online (Sandbox Code Playgroud)

这也不起作用:

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'default': {
            'datefmt' : '%Y-%m-%d %H:%M:%S'
            },
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我仍然得到默认的日志日期格式:

[13/Mar/2019 21:53:05] "GET / HTTP/1.1" 200 16808
Run Code Online (Sandbox Code Playgroud)

请注意,在源代码中,datefmt应该已经传递并使用了,但似乎并非如此:

https://github.com/django/django/blob/782d85b6dfa191e67c0f1d572641d8236c79174c/django/utils/log.py#L190

使用 Python 3.6 和 Django 2.1


更新:

当我将其包含在我settings.py的描述中时:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'datefmt' : '%Y-%m-%d %H:%M:%S',
            'style': '{',
        }
}
Run Code Online (Sandbox Code Playgroud)

然后conda//lib/python3.6/site-packages/django/utils/log.py像这样编辑文件:

class ServerFormatter(logging.Formatter):
    def __init__(self, *args, **kwargs):
        self.style = color_style()
        super().__init__(*args, **kwargs)
        print("self.datefmt", self.datefmt)
Run Code Online (Sandbox Code Playgroud)

我在控制台中收到如下消息,表明我实际上正在datefmt正确传播:

$ python manage.py runserver
self.datefmt %Y-%m-%d %H:%M:%S
self.datefmt %Y-%m-%d %H:%M:%S
Performing system checks...

System check identified no issues (0 silenced).
March 13, 2019 - 23:43:50
Django version 2.1.2, using settings 'webapp.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[13/Mar/2019 23:45:14] "GET / HTTP/1.1" 200 16808
Run Code Online (Sandbox Code Playgroud)

也许错误与此行有关django/utils/log.py

if self.uses_server_time() and not hasattr(record, 'server_time'):
            record.server_time = self.formatTime(record, self.datefmt)
Run Code Online (Sandbox Code Playgroud)

^ 不管我做什么,似乎这个检查永远不会被绊倒,因为not hasattr(record, 'server_time')总是评估为False,因为默认情况下record已经有server_time,并且它似乎来自 Django 代码的这一部分django/core/servers/basehttp.py

class WSGIRequestHandler(simple_server.WSGIRequestHandler):
...
...
    def log_message(self, format, *args):
        extra = {
            'request': self.request,
            'server_time': self.log_date_time_string(),
        }
Run Code Online (Sandbox Code Playgroud)

simple_server.WSGIRequestHandler.log_date_time_string()从即将到来的wsgiref包。但是,该包不包含对 function 的任何引用log_date_time_string(),它似乎直接来自 Python 内置http库 ( conda//lib/python3.6/http/server.py):

def log_date_time_string(self):
    """Return the current time formatted for logging."""
    now = time.time()
    year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
    s = "%02d/%3s/%04d %02d:%02d:%02d" % (
            day, self.monthname[month], year, hh, mm, ss)
    return s
Run Code Online (Sandbox Code Playgroud)

^ 此处的日期格式是硬编码到库中的,似乎不可更改。

那么......这应该如何工作?我错过了什么吗?这是 Django 中的某种错误吗?除非我弄错了,否则无法datefmt基于此覆盖它?

Kev*_*nry 4

这是一次很好、详细的调查。确保您的研究包括 Django 票务跟踪器。搜索的第一个结果site:code.djangoproject.com datefmt表明这是一个已知的错误

\n\n

该票证显示了一种可能的解决方法\xe2\x80\x94useasctime而不是server_time.

\n