django开发日志配置
做django开发离不开 日志,这用于保存我门的服务器的日志信息,便于开发人员的维护。
直接上代码:
在setting.py文件里直接配置即可
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(module)s %(lineno)d %(message)s' }, }, 'filters': { 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { 'console': { 'level': 'DEBUG', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'file': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"), # 日志文件的位置 'maxBytes': 300 * 1024 * 1024, 'backupCount': 10, 'formatter': 'verbose' }, }, 'loggers': { 'django': { # 定义了一个名为django的日志器 'handlers': ['console', 'file'], 'propagate': True, }, } }
下面是一段重写 rest_framework 异常处理方式,并增加redis异常 和数据库异常
from rest_framework.views import exception_handler as drf_exception_handler import logging from django.db import DatabaseError from redis.exceptions import RedisError from rest_framework.response import Response from rest_framework import status # 获取在配置文件中定义的logger,用来记录日志 logger = logging.getLogger('django') def exception_handler(exc, context): ''' 修改Django REST framework的默认异常处理方法,补充处理数据库异常和Redis异常。 ''' """ 自定义异常处理 :param exc: 异常 :param context: 抛出异常的上下文 :return: Response响应对象 """ # 调用drf框架原生的异常处理方法 response = drf_exception_handler(exc, context) if response is None: view = context['view'] if isinstance(exc, DatabaseError) or isinstance(exc, RedisError): # 数据库异常 logger.error('[%s] %s' % (view, exc)) response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response
1. 日志级别
日志一共分成5个等级,从低到高分别是:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
说明:
- DEBUG:详细的信息,通常只出现在诊断问题上
- INFO:确认一切按预期运行
- WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
- ERROR:更严重的问题,软件没能执行一些功能
- CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行
这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在WARNING或之上时才被跟踪。
2. 日志输出
有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件。
2.1、将日志输出到控制台
比如,log1.py 如下:
import logging logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # 开始使用log功能 logging.info('这是 loggging info message') logging.debug('这是 loggging debug message') logging.warning('这是 loggging a warning message') logging.error('这是 an loggging error message') logging.critical('这是 loggging critical message') 运行结果 2017-11-06 23:07:35,725 - log1.py[line:9] - WARNING: 这是 loggging a warning message 2017-11-06 23:07:35,725 - log1.py[line:10] - ERROR: 这是 an loggging error message 2017-11-06 23:07:35,725 - log1.py[line:11] - CRITICAL: 这是 loggging critical message
说明
通过logging.basicConfig函数对日志的输出格式及方式做相关配置,上面代码设置日志的输出等级是WARNING级别,意思是WARNING级别以上的日志才会输出。另外还制定了日志输出的格式。
注意,只要用过一次log功能再次设置格式时将失效,实际开发中格式肯定不会经常变化,所以刚开始时需要设定好格式
2.2、将日志输出到文件
我们还可以将日志输出到文件,只需要在logging.basicConfig函数中设置好输出文件的文件名和写文件的模式。
log2.py 如下:
import logging logging.basicConfig(level=logging.WARNING, filename='./log.txt', filemode='w', format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # use logging logging.info('这是 loggging info message') logging.debug('这是 loggging debug message') logging.warning('这是 loggging a warning message') logging.error('这是 an loggging error message') logging.critical('这是 loggging critical message') 运行效果 python@ubuntu: cat log.txt 2017-11-06 23:10:44,549 - log2.py[line:10] - WARNING: 这是 loggging a warning message 2017-11-06 23:10:44,549 - log2.py[line:11] - ERROR: 这是 an loggging error message 2017-11-06 23:10:44,549 - log2.py[line:12] - CRITICAL: 这是 loggging critical message
2.3、既要把日志输出到控制台, 还要写入日志文件
这就需要一个叫作Logger 的对象来帮忙,下面将对他进行详细介绍,现在这里先学习怎么实现把日志既要输出到控制台又要输出到文件的功能。
import logging # 第一步,创建一个logger logger = logging.getLogger() logger.setLevel(logging.INFO) # Log等级总开关 # 第二步,创建一个handler,用于写入日志文件 logfile = './log.txt' fh = logging.FileHandler(logfile, mode='a') # open的打开模式这里可以进行参考 fh.setLevel(logging.DEBUG) # 输出到file的log等级的开关 # 第三步,再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 输出到console的log等级的开关 # 第四步,定义handler的输出格式 formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s") fh.setFormatter(formatter) ch.setFormatter(formatter) # 第五步,将logger添加到handler里面 logger.addHandler(fh) logger.addHandler(ch) # 日志 logger.debug('这是 logger debug message') logger.info('这是 logger info message') logger.warning('这是 logger warning message') logger.error('这是 logger error message') logger.critical('这是 logger critical message') 运行时终端的输出结果: 2017-11-06 23:14:04,731 - log3.py[line:28] - WARNING: 这是 logger warning message 2017-11-06 23:14:04,731 - log3.py[line:29] - ERROR: 这是 logger error message 2017-11-06 23:14:04,731 - log3.py[line:30] - CRITICAL: 这是 logger critical message 在log.txt中,有如下数据: 2017-11-06 23:14:04,731 - log3.py[line:27] - INFO: 这是 logger info message 2017-11-06 23:14:04,731 - log3.py[line:28] - WARNING: 这是 logger warning message 2017-11-06 23:14:04,731 - log3.py[line:29] - ERROR: 这是 logger error message 2017-11-06 23:14:04,731 - log3.py[line:30] - CRITICAL: 这是 logger critical message
3、日志格式说明
logging.basicConfig函数中,可以指定日志的输出格式format,这个参数可以输出很多有用的信息,如下:
%(levelno)s: 打印日志级别的数值 %(levelname)s: 打印日志级别名称 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s: 打印当前执行程序名 %(funcName)s: 打印日志的当前函数 %(lineno)d: 打印日志的当前行号 %(asctime)s: 打印日志的时间 %(thread)d: 打印线程ID %(threadName)s: 打印线程名称 %(process)d: 打印进程ID %(message)s: 打印日志信息 在工作中给的常用格式如下: format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
这个格式可以输出日志的打印时间,是哪个模块输出的,输出的日志级别是什么,以及输入的日志内容。