Python Logging模块
鉴于最近接触的项目比较复杂,之前朴素的print调试法已经不能满足日益增长的bug,所以博主把目光转向了logging。
一、基本用法
可以直接当成print使用
# coding=utf-8
import logging
logging.debug("debug message")
logging.info("info message")
logging.warning("warning message")
logging.error("error message")
logging.critical("critical message")
'''
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
默认只有级别高于warning的才会被打印,默认的Logger实例名为root
'''
输出到文件
# coding=utf-8
import logging
# 指定输出文件和输出级别
logging.basicConfig(filename='root.log', level=logging.INFO)
logging.debug("debug message")
logging.info("info message")
logging.warning("warn message")
logging.error("error message")
logging.critical("critical message")
和上面的结果不同,命令行不再有标准输出(stdout),输出都写到了root.log
的日志文件
二、定制日志
默认的配置信息不够丰富,一般我们自己添加一些信息,logging可以使用conf文件、字典或者直接配置三种方式
首先介绍一下format格式,可以提供额外信息
格式 | 描述 |
---|---|
%(levelno)s | 打印日志级别的数值 |
%(levelname)s | 打印日志级别名称 |
%(pathname)s | 打印当前执行程序的路径 |
%(filename)s | 打印当前执行程序名称 |
%(funcName)s | 打印日志的当前函数 |
%(lineno)d | 打印日志的当前行号 |
%(asctime)s | 打印日志的时间 |
%(thread)d | 打印线程id |
%(threadName)s | 打印线程名称 |
%(process)d | 打印进程ID |
%(message)s | 打印日志信息 |
2.1 conf文件
[loggers]
keys = root
[handlers]
keys = stream_handler, file_handler
[formatters]
keys = formatter
[logger_root]
level = DEBUG
handlers = stream_handler, file_handler
[handler_stream_handler]
class = StreamHandler
level = DEBUG
formatter = formatter
args = (sys.stderr,)
[handler_file_handler]
class = FileHandler
level = DEBUG
formatter = formatter
args = ('root.log', 'a')
[formatter_formatter]
format = %(asctime)s - %(levelname)s - line %(lineno)d => %(message)s
# coding=utf-8
import logging
from logging.config import fileConfig
# 加载配置文件
fileConfig('log.ini')
logger = logging.getLogger()
logger.debug('a new log')
'''
2018-08-18 23:51:15,277 - DEBUG - line 8 => a new log
同时把结果写到root.log中
'''
2.2 字典配置
# coding=utf-8
import logging
from logging.config import dictConfig
logging_config = {
'version': 1,
'formatters': {
'f': {
'format': '%(asctime)s - %(levelname)s - line %(lineno)d => %(message)s'
}
},
'handlers': {
'h1': {
'class': 'logging.StreamHandler',
'formatter': 'f',
# 这里没有定义level就默认继承root的level
},
'h2': {
'class': 'logging.FileHandler',
'formatter': 'f',
'filename': 'hello.log',
'level': logging.WARNING
}
},
'root': {
'handlers': ['h1', 'h2'],
# 级别等级:debug、info、warning、error、critical
'level': logging.INFO # 定义处理的最低级别
}
}
dictConfig(logging_config)
logger = logging.getLogger()
logger.debug('debug')
logger.info('info')
logger.warning('warning')
'''
2018-08-19 00:10:35,831 - INFO - line 35 => info
2018-08-19 00:10:35,831 - WARNING - line 36 => warning
其中,warning的内容被记录在hello.log文件中
'''
2.3 直接配置
这个比较简单,直接贴代码
# coding=utf-8
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
logger.debug('hi')
'''
2018-08-19 00:13:31,109 root DEBUG hi
'''
三、小结
现在发现之外呢基于print和单步调试的方法好土……日志可以大大提高我们debug的效率,特别实在追踪大型项目中可以用到。