需求:
1)要求将所有级别的所有日志都写入磁盘文件中
2)all.log文件中记录所有的日志信息,日志格式为:日期和时间 - 日志级别 - 日志信息
3)error.log文件中单独记录error及以上级别的日志信息,日志格式为:日期和时间 - 日志级别 - 文件名[:行号] - 日志信息
4)要求all.log在每天凌晨进行日志切割
代码实现:
import logging
import logging.handlers
import datetime
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))
logger.addHandler(rf_handler)
logger.addHandler(f_handler)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
all.log文件输出
2018-05-13 16:12:40,612 - DEBUG - debug message
2018-05-13 16:12:40,612 - INFO - info message
2018-05-13 16:12:40,612 - WARNING - warning message
2018-05-13 16:12:40,612 - ERROR - error message
2018-05-13 16:12:40,613 - CRITICAL - critical message
error.log文件输出
2018-05-13 16:12:40,612 - ERROR - log.py[:81] - error message
201-05-13 16:12:40,613 - CRITICAL - log.py[:82] - critical message
#########################
## Django Logging BEGIN
#########################
#LOGGING_DIR 日志文件存放目录
LOGGING_DIR = "/home/xxt/logs"
if not os.path.exists(LOGGING_DIR):
os.mkdir(LOGGING_DIR)
import logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s][%(funcName)s][%(lineno)d] > %(message)s'
},
'simple': {
'format': '[%(levelname)s]> %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file_handler': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': '%s/django.log' % LOGGING_DIR,
'formatter':'standard',
'encoding': 'utf-8'
}, # 用于文件输出
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'formatter':'standard'
},
},
'loggers': {
'mdjango': {
# 一个记录器中可以使用多个处理器
'handlers': ['console','file_handler'],
'level':'DEBUG',
'propagate': True,
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
}
}
logger = logging.getLogger("mdjango")
#########################
## Django Logging END
#########################
配置文件logging.conf内容如下:
[loggers]
keys=root,simpleExample
[handlers]
keys=fileHandler,consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=fileHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=FileHandler
args=('logging.log', 'a')
level=ERROR
formatter=simpleFormatter
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
代码如下:
# 读取日志配置文件内容
logging.config.fileConfig('logging.conf')
# 创建一个日志器logger
logger = logging.getLogger('simpleExample')
# 日志输出
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
结果如下:
2017-05-15 11:32:16,539 - simpleExample - DEBUG - debug message
2017-05-15 11:32:16,555 - simpleExample - INFO - info message
2017-05-15 11:32:16,555 - simpleExample - WARNING - warn message
2017-05-15 11:32:16,555 - simpleExample - ERROR - error message
2017-05-15 11:32:16,555 - simpleExample - CRITICAL - critical message
关于fileConfig()函数的说明:
该函数实际上是对configparser模块的封装,关于configparser模块的介绍请参考<>。
函数定义:
该函数定义在loging.config模块下:
logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)
参数:
fname:表示配置文件的文件名或文件对象
defaults:指定传给ConfigParser的默认值
disable_existing_loggers:这是一个布尔型值,默认值为True(为了向后兼容)表示禁用已经存在的logger,除非它们或者它们的祖先明确的出现在日志配置中;如果值为False则对已存在的loggers保持启动状态。
配置文件格式说明:
上面提到过,fileConfig()函数是对ConfigParser/configparser模块的封装,也就是说fileConfig()函数是基于ConfigParser/configparser模块来理解日志配置文件的。换句话说,fileConfig()函数所能理解的配置文件基础格式是与ConfigParser/configparser模块一致的,只是在此基础上对文件中包含的section和option做了一下规定和限制,比如:
1)配置文件中一定要包含loggers、handlers、formatters这些section,它们通过keys这个option来指定该配置文件中已经定义好的loggers、handlers和formatters,多个值之间用逗号分隔;另外loggers这个section中的keys一定要包含root这个值;
2)loggers、handlers、formatters中所指定的日志器、处理器和格式器都需要在下面以单独的section进行定义。seciton的命名规则为[logger_loggerName]、[formatter_formatterName]、[handler_handlerName]
3)定义logger的section必须指定level和handlers这两个option,level的可取值为DEBUG、INFO、WARNING、ERROR、CRITICAL、NOTSET,其中NOTSET表示所有级别的日志消息都要记录,包括用户定义级别;handlers的值是以逗号分隔的handler名字列表,这里出现的handler必须出现在[handlers]这个section中,并且相应的handler必须在配置文件中有对应的section定义;
4)对于非root logger来说,除了level和handlers这两个option之外,还需要一些额外的option,其中qualname是必须提供的option,它表示在logger层级中的名字,在应用代码中通过这个名字得到logger;propagate是可选项,其默认是为1,表示消息将会传递给高层次logger的handler,通常我们需要指定其值为0,这个可以看下下面的例子;另外,对于非root logger的level如果设置为NOTSET,系统将会查找高层次的logger来决定此logger的有效level。
5)定义handler的section中必须指定class和args这两个option,level和formatter为可选option;class表示用于创建handler的类名,args表示传递给class所指定的handler类初始化方法参数
,它必须是一个元组(tuple)的形式,即便只有一个参数值也需要是一个元组的形式;level与logger中的level一样,而formatter指定的是该处理器所使用的格式器,这里指定的格式器名称必须出现在formatters这个section中,且在配置文件中必须要有这个formatter的section定义;如果不指定formatter则该handler将会以消息本身作为日志消息进行记录,而不添加额外的时间、日志器名称等信息;
6)定义formatter的sectioin中的option都是可选的,其中包括format用于指定格式字符串,默认为消息字符串本身;datefmt用于指定asctime的时间格式,默认为'%Y-%m-%d %H:%M:%S';class用于指定格式器类名,默认为logging.Formatter;
首先需要安装PyYAML模块:
pip install PyYAML
logging.yml配置文件的内容:
---
version: 1
disable_existing_loggers: false
formatters:
simple:
format: "%(asctime)s - %(levelname)s - %(filename)s : %(message)s"
special:
format: "%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s : %(message)s"
handlers:
basic_console:
class: logging.StreamHandler
level: INFO
formatter: special
stream: ext://sys.stdout
debug_file:
class: logging.handlers.TimedRotatingFileHandler
level: DEBUG
formatter: special
filename: debug.log
when: D
interval: 1
backupCount: 1
info_file:
class: logging.handlers.TimedRotatingFileHandler
level: INFO
formatter: special
filename: info.log
when: D
interval: 1
backupCount: 1
warning_file:
class: logging.handlers.TimedRotatingFileHandler
level: WARNING
formatter: special
filename: warnning.log
when: D
interval: 1
backupCount: 1
error_file:
class: logging.handlers.TimedRotatingFileHandler
level: ERROR
formatter: special
filename: error.log
when: D
interval: 1
backupCount: 1
normal_app_request:
class: logging.handlers.TimedRotatingFileHandler
level: WARNING
formatter: special
filename: warnning.log
when: D
interval: 1
backupCount: 1
error_app_request:
class: logging.handlers.TimedRotatingFileHandler
level: ERROR
formatter: special
filename: error.log
when: D
interval: 1
backupCount: 1
loggers:
django_1:
level: INFO
handlers:
- basic_console
- error_file
propagate: 'no'
代码如下:
import logging
import logging.config
import yaml
with open('logging.yml', 'r') as f_conf:
dict_conf = yaml.load(f_conf)
logging.config.dictConfig(dict_conf)
logger = logging.getLogger('django_1')
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
1.关于logging.getLogger('django_1')
name参数与定义的loggers有关,一一对应,即可以实现将不同功能模块的log,使用不同的logger记录到不同的log文件中
参考文档: https://docs.python.org/3.5/library/logging.config.html
参考文档: https://www.cnblogs.com/yyds/p/6885182.html