简单的输出,用于快捷操作
import logging
import time
# filemode="a" ,才能在文件末尾追加
# 在循环中,logging 相对于 open(file,'w').write的优点:不需要等到循环执行完成log日志才有内容
logging.basicConfig(filename="test.log", filemode="w",format="%(asctime)s %(name)s:%(levelname)s: %(message)s", \
datefmt="%Y-%M-%d %H:%M:%S", level=logging.INFO)
a = 5
b = 0
for i in range(1):
try:
c = a / b # 如果有异常需要捕获异常,下面有3中方式将具体异常写入log文件
except Exception as e:
logging.exception("Exception occurred")
#logging.error("Exception occurred", exc_info=True) # 要写exc_info=True,才能把ZeroDivisionError: division by zero的具体错误信息写入log文件
#logging.log(level=logging.INFO, msg="Exception occurred", exc_info=True) # 这里的level写成debug,无法写入文件,因为basicConfig设置了INFO ; logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
操作更多样
# 下面的方式会把”信息“累加到test.log日志中
import logging
import logging.handlers
logger = logging.getLogger("logger") # %(name)s 日志对象名称 logger(括号中的名称"logger")
handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")
logger.setLevel(logging.DEBUG) # 这个设置总的级别,handler的级别>=这个级别
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s", datefmt="%Y-%M-%d %H:%M:%S") # %message :下面debug,warning等括号中的内容
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
logger.addHandler(handler1)
logger.addHandler(handler2)
#分别为 30、10、10
# print(handler1.level)
# print(handler2.level)
# print(logger.level)
logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
输出
# #控制台输出结果为:
2018-10-13 23:24:57,832 logger WARNING This is a customer warning message
2018-10-13 23:24:57,832 logger ERROR This is an customer error message
2018-10-13 23:24:57,832 logger CRITICAL This is a customer critical message
# 文件中输出内容为:
2018-10-13 23:44:59,817 logger DEBUG This is a customer debug message
2018-10-13 23:44:59,817 logger INFO This is an customer info message
2018-10-13 23:44:59,817 logger WARNING This is a customer warning message
2018-10-13 23:44:59,817 logger ERROR This is an customer error message
2018-10-13 23:44:59,817 logger CRITICAL This is a customer critical message
注意点
# 创建了自定义的 Logger 对象,就不要在用 logging 中的日志输出方法了,这些方法使用的是默认配置的 Logger 对象,否则会输出的日志信息会重复。
# 比如下面写了 logging.info,那么会在>info等级输出(warning,error,critical)重复信息
import logging
import logging.handlers
logger = logging.getLogger("logger")
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
# handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug('This is a customer debug message')
logging.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
输出
This is a customer warning message
WARNING:logger:This is a customer warning message
This is an customer error message
ERROR:logger:This is an customer error message
This is a customer critical message
CRITICAL:logger:This is a customer critical message
使用文件导入配置
config.py文件
from datetime import datetime
config = {
'version': 1,
'formatters': {
'simple': {
'format': '%(filename)s - %(asctime)s - %(name)s - %(levelname)s - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
# 其他的 formatter
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple'
},
'info_file_time': {
'class': 'logging.handlers.TimedRotatingFileHandler',
# 还有时间分割handler:logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)
'filename': '{}.log'.format("test"), # 生成以日期为名称的日志文件
'level': 'INFO',
'formatter': 'simple',
'when': "H",
'interval': 1,
'backupCount': 2000,
'encoding': 'utf-8'
},
'info_file_size': {
'class': 'logging.handlers.RotatingFileHandler',
# 还有时间分割handler:logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)
'filename': '{}.log'.format(log_filename), # 生成以日期为名称的日志文件
'level': 'INFO',
'formatter': 'simple',
'maxBytes': 2000000,
'backupCount': 2000,
# 假设200kb为3行内容,filename=logging.log,logging.log文件写满3行,将早期的3行移入logging.log.1文件,logging.log文件再写满3行,将早期3行已入logging.log.1文件,将logging.log.1的3行内容移入logging.log.2文件
'encoding': 'utf-8',
'mode': 'a+' # 'w', 'a' 都是追加写入
},
# 其他的 handler
# 其他的 handler
'error_file_rotatingFileHandler': {
'class': 'logging.handlers.RotatingFileHandler',
# 还有时间分割handler:logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)
'filename': '{}.log'.format(log_filename + ".error"), # 生成以日期为名称的日志文件
'level': 'ERROR',
'formatter': 'simple',
'maxBytes': 200000,
'backupCount': 2000,
# 假设200kb为3行内容,filename=logging.log,logging.log文件写满3行,将早期的3行移入logging.log.1文件,logging.log文件再写满3行,将早期3行已入logging.log.1文件,将logging.log.1的3行内容移入logging.log.2文件
'encoding': 'utf-8',
'mode': 'a+' # 'w', 'a' 都是追加写入
}
},
'loggers':{
'StreamLogger': {
'handlers': ['console'],
'level': 'DEBUG',
},
'FileLogger': {
# 既有 console Handler,还有 file Handler
'handlers': ['console', 'file'],
'level': 'DEBUG',
},
# 其他的 Logger
}
}
# 先经过loggers的级别处理,再经过handlers的级别处理,根据实际情况使用StreamLogger或FileLogger。可以也只使用FileLogger,在handlers的console或file中设置相应的级别,比如console设置DEBUG,file设置INFO,这样fileLogger能打印>=DEBUG的信息,文件会写入>=INFO的信息
# # TimedRotatingFileHandler,不能添加mode='a'
# # when:日志文件按什么维度切分。'S'-秒;'M'-分钟;'H'-小时;'D'-天;'W'-周
# # 这里需要注意,如果选择 D-天,那么这个不是严格意义上的'天',而是从你
# # 项目启动开始,过了24小时,才会从新创建一个新的日志文件,
# # 如果项目重启,这个时间就会重置。所以这里选择'MIDNIGHT'-是指过了午夜
# # 12点,就会创建新的日志。
# # interval:是指等待多少个单位 when 的时间后,Logger会自动重建文件。
# # backupCount:是保留日志个数。默认的0是不会自动删除掉日志。
导入config配置
import logging
import logging.config
from config import config
logging.disable(logging.DEBUG) # > debug级别才能被输出
logging.disable = True
logging.config.dictConfig(config)
StreamLogger = logging.getLogger("StreamLogger")
FileLogger = logging.getLogger("FileLogger")
#StreamLogger.info('aaa')
FileLogger.info('pppp') # 在文件和控制台都输出
# 省略日志输出
PS:
handler和logger设置的级别都是 >=就能输出;但是“注意点”下的logging.info 和 “使用文件导入配置” 的 logging.disable 的相关设置需要 > 对应级别才能输出。Logger's level 的默认等级为warning,所以如果没有设置logger.setLevel(logging.DEBUG),那么所有输出将>=warning才能输出,不管你的handler已经设置了debug级别