无法使用settings.py中定义的给定日志格式设置额外的上下文,并且如果我们从格式中删除%(classname)s()] %(token)s %(router_macid)s %(user_email)s %(device_macid)s
,那么我正在使用API进行响应,甚至在日志文件中生成日志,也可以正常工作没有错误,我正在使用django == 2.1,djangorestframework == 3.10.3
错误
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib/python3.6/logging/__init__.py", line 994, in emit
msg = self.format(record)
File "/usr/lib/python3.6/logging/__init__.py", line 840, in format
return fmt.format(record)
File "/usr/lib/python3.6/logging/__init__.py", line 580, in format
s = self.formatMessage(record)
File "/usr/lib/python3.6/logging/__init__.py", line 549, in formatMessage
return self._style.format(record)
File "/usr/lib/python3.6/logging/__init__.py", line 391, in format
return self._fmt % record.__dict__
KeyError: 'classname'
Call stack:
File "/usr/lib/python3.6/threading.py", line 884, in _bootstrap
self._bootstrap_inner()
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/usr/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/usr/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 154, in handle
handler.run(self.server.get_app())
File "/usr/lib/python3.6/wsgiref/handlers.py", line 138, in run
self.finish_response()
File "/usr/lib/python3.6/wsgiref/handlers.py", line 183, in finish_response
self.close()
File "/usr/lib/python3.6/wsgiref/simple_server.py", line 35, in close
self.status.split(' ',1)[0], self.bytes_sent
File "/usr/lib/python3.6/http/server.py", line 536, in log_request
self.requestline, str(code), str(size))
File "/usr/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 124, in log_message
level(format, *args, extra=extra)
Message: '"%s" %s %s'
settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'formatter': {
'format' : '[%(asctime)s] %(levelname)s [%(pathname)s:%(lineno)s:%(classname)s()] %(token)s %(router_macid)s %(user_email)s %(device_macid)s %(message)s',
'datefmt' : "%d/%b/%Y %H:%M:%S"
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'my_django.log',
'formatter': 'formatter'
},
},
'loggers': {
'django': {
'handlers':['file'],
'propagate': True,
'level':'DEBUG',
},
'backend': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
}
}
views.py
import logging
from rest_framework import views
from rest_framework.response import Response
logging.basicConfig(level=logging.INFO)
log = logging.getLogger('backend')
log_dict = {
'classname': 'NA',
'router_macid':'NA',
'token':'NA',
'device_macid':'NA',
'user_email':'NA'
}
class MyView(views.APIView):
def post(self, request):
extra_dict = log_dict.copy()
extra_dict['classname'] = self.__class__.__name__
response=codes['200'].copy()
response['message']= “Success”
log.info(" ".join(["Request received with =",str(request.data),"response=",str(response)]), extra= extra_dict)
return Response(response)
答案 0 :(得分:2)
您当前的日志记录配置将覆盖其他库的日志记录配置。因此,出现错误的原因(请参阅错误回溯)。
我建议仅对django项目覆盖日志记录配置。
创建一个单独的格式化程序条目,并保留默认状态下的“格式化程序”条目。您还可以重命名“格式化程序”条目以使其特定于您的项目
'formatters': {
'backend': {
'format' : '[%(asctime)s] %(levelname)s [%(pathname)s:%(lineno)s:%(classname)s()] %(token)s %(router_macid)s %(user_email)s %(device_macid)s %(message)s',
'datefmt' : "%d/%b/%Y %H:%M:%S"
},
},
然后输入一个条目,以仅为使用上述已配置格式器的项目配置处理程序。不要覆盖Django的记录器。外部库应配置自己的日志记录。
'handlers': {
'backend': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'my_django.log',
'formatter': 'backend'
},
},
最后为使用处理程序的项目配置记录器。
'loggers': {
'backend': {
'handlers': ['backend'],
'level': 'DEBUG',
'propagate': False,
},
}
请记住将propagate设置为False
,以防止事件传递给祖先记录器。
获取已配置的记录器,并像以前一样在项目中使用它。
log = logging.getLogger('backend')