在生产环境中,将程序的运行日志输出保存到文件中是很必要的操作;当应用崩溃时,很容易通过查找日志来定位问题。下面介绍一下django开发中如何将日志输出到文件中。
首先看一下日志级别有哪些:
DEBUG:所有等级中最低,其信息一般用来作为调试的辅助信息
INFO:程序的一般信息
WARNING:警告,通常用来对某些可能出现的错误且不会影响程序正常运行的信息进行警告。
ERROR:错误,表示出现了某种错误。
CRITICAL:崩溃,出现了严重级别的错误。
在django项目中使用logging模块打印日志的步骤如下:
1.导入模块 import logging
2.设置日志等级 logging.basicConfig(level=logging.DEBUG)
3.获取logger对象 logger = logging.getLogger(__name__)
4.打印日志 logger.debug("logger日志"),还有logger.info(),logger.warning()等方法
下面介绍一下logging中的四个组件,如下:
1.Loggers
2.Handlers
3.Filters
4.Formatters
Loggers(日志记录器),系统中的每一条日志都是由该组件进行记录的,每一个记录器都应该有其自己的名称并标记其最低记录的等级;当一条日志给到logger时,logger会对该条信息的级别与自身的级别进行比较,如果该日志级别不低于本身级别,logger就会进行下一步操作。如果日志的信息级别比logger的低,那么就会忽略这条日志。
当logger经过级别的比较之后决定要对某条日志进行处理时,就将该条日志交给了Handlers
Handlers(处理器),用来处理具体每条信息,例如是将日志打印到屏幕还是记录到文件或者发送至某个网络连接;它自己的记录级别,如果日志级别低于handler的级别,handler同样会忽略掉该条日志。
Filter(过滤器):提供了传递给handler之前的附加功能。在通常情况下,一条日志信息只要达到logger的级别之后就会传递给handler处理,但是我们可以通过使用filter来对日志进行额外的过滤。
例如我们可以使用某个filter来控制只允许某个特定的源的ERROR级别的日志。
Filter还运行咱们在处理之前修改日志,例如降低或者提高日志的级别。
Filter可以在logger和handler中同时使用,而且多个filter会同时工作。
Formatter(格式化):定义了怎么显示内容,因为最终的日志都会是以文本的形式展现,formatter就是描述怎么来做这件事。formatter通常都是使用python格式化字符串的方法来对日志进行格式化
最后看一个日志配置的例子:
setting.py:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_LOG_DIR = os.path.join(BASE_DIR, "logs")
LOGGING = {
'version': 1, # 保留的参数,默认是1
'disable_existing_loggers': False, # 是否禁用已经存在的logger实例
# 日志输出格式的定义
'formatters': {
'standard': { # 标准的日志格式化
'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
},
'error': { # 错误日志输出格式
'format': '%(levelname)s %(asctime)s %(pathname)s %(module)s %(message)s'
},
'simple': {
'format': '%(levelname)s %(asctime)s %(message)s'
},
'collect': {
'format': '%(message)s'
}
},
# 处理器:需要处理什么级别的日志及如何处理
'handlers': {
# 将日志打印到终端
'console': {
'level': 'DEBUG', # 日志级别
'class': 'logging.StreamHandler', # 使用什么类去处理日志流
'formatter': 'simple' # 指定上面定义过的一种日志输出格式
},
# 默认日志处理器
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "xx.log"), # 日志文件路径
'maxBytes': 1024 * 1024 * 100, # 日志大小 100M
'backupCount': 5, # 日志文件备份的数量
'formatter': 'standard', # 日志输出格式
'encoding': 'utf-8',
},
# 日志处理级别warn
'warn': {
'level': 'WARN',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "warn.log"), # 日志文件路径
'maxBytes': 1024 * 1024 * 100, # 日志大小 100M
'backupCount': 5, # 日志文件备份的数量
'formatter': 'standard', # 日志格式
'encoding': 'utf-8',
},
# 日志级别error
'error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "error.log"), # 日志文件路径
'maxBytes': 1024 * 1024 * 100, # 日志大小 100M
'backupCount': 5,
'formatter': 'error', # 日志格式
'encoding': 'utf-8',
},
},
'loggers': {
# 默认的logger应用如下配置
'': {
'handlers': ['default', 'warn', 'error'],
'level': 'DEBUG',
'propagate': True, # 如果有父级的logger示例,表示不要向上传递日志流
},
'collect': {
'handlers': ['console', 'default', 'warn', 'error'],
'level': 'INFO',
}
},
}