python logging模块
logging全局函数
通过调用logging模块级别函数进行日志记录,本质上是内部创建了一个root logger来进行操作。
import logging
logging.basicConfig(level=logging.INFO, format='[%(asctime)s][%(name)s][%(levelname)s]: %(message)s')
logging.info('INFO LOG')
logging.warning('WARN LOG')
logging.error('ERROR LOG')
# result
[2019-04-15 14:54:37,098][root][INFO]: INFO LOG
[2019-04-15 14:54:37,098][root][WARNING]: WARN LOG
[2019-04-15 14:54:37,098][root][ERROR]: ERROR LOG
logging levels
Logger Object
Logger是logging模块中的操作句柄,我们可以对其进行各种配置然后执行记录操作。
常见操作就是addHandler, addFilter等配置操作和info(),error()等记录操作
import logging
logger = logging.getLogger(__name__) # 通常使用模块名称命名logger避免重复,相同命名的logger会彼此覆盖
##常用操作
logger.setLevel() # 虽然Handler也会配置level,这里是全局配置
logger.addHandler()
logger.removeHandler()
logger.addFilter()
logger.removeFilter()
logger.debug()
logger.info()
logger.warning()
logger.error()
logger.exception() # level是error,但会记录traceback信息
Formatter Object
Formatter用于定义日志输出格式,通常填入Handler使用。Formatter使用格式化字符串进行配置,格式是standard Python %-style mapping keys ,默认是'%(message)s'
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
常见参数:
%(name)s: 打印logger的名称
%(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:打印日志信息
详细见:https://docs.python.org/3/library/logging.html#logging.LogRecord
Handler Object
Handler是一个处理对象,我们通过对其设置决定以什么样的方式处理和记录日志,Handler一般不直接使用,它作为一个基础类,更多地使用他的子类比如RotatingFileHandler, TimedRotatingFileHandler
RotatingFileHandler
RotatingFileHandler将按照文件大小进行日志文件回滚, 基本使用步骤为实例化,设置等级,设置格式,添加入logger即可
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
file_handler = RotatingFileHandler(filename="test.log", maxBytes=1 * 1024, backupCount=10, encoding='utf8')
file_handler.setLevel(logging.INFO)
formatter = logging.Formatter('[%(asctime)s][%(name)s][%(levelname)s]: %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info('INFO LOG')
logger.warning('WARN LOG')
logger.error('ERROR LOG')
回滚步骤:日志总是会写入test.log,当test.log的大小达到maxBytes,会被重命名为test.log.1,然后新建test.log继续写入日志。根据backupCount的值决定保留多少日志,命名依次为test.log.1, test.log.2 ... ,当日志文件数量达到backupCount的时候,test.log.1的文件会被删除,然后将test.log重新命名为test.log.1完成替换,依次类推。
TimedRotatingFileHandler
TimedRotatingFileHandler按照时间进行日志的切分和回滚,使用步骤和RotatingFileHandler相同
import logging
from logging.handlers import TimedRotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
file_handler = TimedRotatingFileHandler(filename="test.log", when='S', interval=1, backupCount=5, encoding='utf8')
# when的取值:
# S - Seconds
# M - Minutes
# H - Hours
# D - Days
file_handler.setLevel(logging.INFO)
formatter = logging.Formatter('[%(asctime)s][%(name)s][%(levelname)s]: %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info('INFO LOG')
logger.warning('WARN LOG')
logger.error('ERROR LOG')