Skip to main content
 首页 » 编程设计

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

2024年09月03日35mengfanrong

答案中的评论here说你应该能够自定义 Django 中登录的日期格式:

Note that if you're using the dictConfig method of configuring logging (e.g. if you're using Django), you can set this using the 'datefmt' dict key for a formatter. See: Django Logging Configuration , logging module: Dictionary Schema Details

但是,它不起作用:

# 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' 
            } 
} 

这也不起作用:

# settings.py 
LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': False, 
    'formatters': { 
        'default': { 
            'datefmt' : '%Y-%m-%d %H:%M:%S' 
            }, 
} 

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

[13/Mar/2019 21:53:05] "GET / HTTP/1.1" 200 16808 

请注意,在源代码中,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': '{', 
        } 
} 

然后像这样编辑文件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) 

我在控制台中收到如下所示的消息,表明我实际上正在正确传播 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 

也许错误与 django/utils/log.py 中的这一行有关?

if self.uses_server_time() and not hasattr(record, 'server_time'): 
            record.server_time = self.formatTime(record, self.datefmt) 

^ 无论我做什么,看起来这个检查永远不会被触发,因为 not hasattr(record, 'server_time') 总是评估为 False,因为 record默认已经有了server_time,它似乎来自django/core/servers/basehttp.py中的这段Django代码:

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

simple_server.WSGIRequestHandler.log_date_time_string() 来自 wsgiref 包。但是,该包不包含对函数 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 

^ 此处的日期格式已硬编码到库中,似乎无法更改。

那么……这应该如何运作?我错过了什么吗?这是 Django 中的某种错误吗?除非我弄错了,否则没有办法基于此覆盖此 datefmt?

请您参考如下方法:

这是一个很好的、详细的调查。确保您的研究包括 Django 票务跟踪器。搜索 site:code.djangoproject.com datefmt 的第一个点击显示这是一个 known bug .

该票据显示了一个可能的解决方法——使用 asctime 而不是 server_time。