需求:日誌根據級別不同,分別打印到不同的日誌文件裏。
其實這裏主要使用過濾器來實現這個需求。
我們以打印一個HTTP請求的URL(request_path)、參數(request_params)、IP(request_ip)爲例:
- 添加過濾器及中間件
假設包路徑爲:middleware.logging_middleware.LogMiddleware
class LogFilter(logging.Filter):
def filter(self, record):
record.request_path = getattr(local, 'request_path', None)
record.request_params = getattr(local, 'request_params', None)
record.request_ip = getattr(local, 'request_ip', None)
return True
class LogMiddleware(MiddlewareMixin):
def process_request(self, request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0] # 這裏是真實的ip
else:
ip = request.META.get('REMOTE_ADDR') # 這裏獲得代理ip
local.request_path = request.path
local.request_params = json.dumps(request.POST)
local.request_ip = ip
def process_response(self, request, response):
return response
中間件LogMiddleware需要註冊到配置文件settings. py,LogMiddleware類用於從request獲取請求URL、參數、IP,保存到local對象,LogFilter類用於日誌從local對象獲取請求URL、參數、IP
- settings.py配置中間件
MIDDLEWARE = [
' middleware.logging_middleware.LogMiddleware ',
]
以上爲配置中間件方法,具體配置以本地包路徑爲準
- settings.py配置過濾器
def debug_filter(record):
if record.levelname == 'DEBUG':
return True
return False
def info_filter(record):
if record.levelname == 'INFO':
return True
return False
def warning_filter(record):
if record.levelname == 'WARNING':
return True
return False
def error_filter(record):
if record.levelname == 'ERROR':
return True
return False
上面配置了4個過濾器,分別過濾日誌四個級別,如果日誌級別符合要求,則打印(返回True),否則忽略(返回False)
- settings.py日誌相關配置
LOGGING = {
'version': 1,
'filters': {
'request_path': { # 此字段爲第1步配置的過濾器的record對象的屬性
'()': 'middleware.logging_middleware.LogFilter',
},
'request_params': {
'()': 'middleware.logging_middleware.LogFilter',
},
'request_ip': {
'()': 'middleware.logging_middleware.LogFilter',
},
'debug_filter': { # 注意這裏的寫法,有一個回調函數,爲第3步配置的過濾器
'()': 'django.utils.log.CallbackFilter',
'callback': debug_filter,
},
'info_filter': {
'()': 'django.utils.log.CallbackFilter',
'callback': info_filter,
},
'warning_filter': {
'()': 'django.utils.log.CallbackFilter',
'callback': warning_filter,
},
'error_filter': {
'()': 'django.utils.log.CallbackFilter',
'callback': error_filter,
}
},
'formatters': {
'standard': {
'format': '%(request_path)s||%(request_params)s||%(request_ip)s'
}
},
'handlers': {
'debug': {
'level': 'DEBUG',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'log', 'debug.log'),
'filters': ['debug_filter', 'request_path', 'request_params', 'request_ip'],
'when': 'midnight',
'interval': 1,
'backupCount': 60,
'formatter': 'standard',
},
'info': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'log', 'info.log'),
'filters': ['info_filter', 'request_path', 'request_params', 'request_ip'],
'when': 'midnight',
'interval': 1,
'backupCount': 60,
'formatter': 'standard',
},
'warning': {
'level': 'WARNING',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'log', 'warning.log'),
'filters': ['warning_filter', 'request_path', 'request_params', 'request_ip'],
'when': 'midnight',
'interval': 1,
'backupCount': 60,
'formatter': 'standard',
},
'error': {
'level': 'ERROR',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'log', 'error.log'),
'filters': [' error_filter ', 'request_path', 'request_params', 'request_ip'],# 注意過濾器要寫全,不要遺漏
'when': 'midnight',
'interval': 1,
'backupCount': 60,
'formatter': 'standard',
}
},
'loggers': {
'log': {
'handlers': ['error', 'warning', 'info', 'debug'],
'level': 'DEBUG',# 此次必須是DEBUG
'propagate': False
}
}
}
5、 開發人員使用日誌
logging = logging.getLogger('log') # 定義日誌記錄器對象
logging.debug('debug') # 自定義不同級別和內容
logging.info('info')
logging.warning('warning')
logging.error('error')