logging是Python标准库中用于记录日志的模块,它提供了灵活的日志记录系统,可以帮助开发者跟踪程序运行状态、调试问题以及记录重要信息。
基本使用 #
1. 最简单的日志记录 #
import logging
logging.warning('这是一个警告信息')
logging.error('这是一个错误信息')输出:
WARNING:root:这是一个警告信息
ERROR:root:这是一个错误信息2. 日志级别 #
Python logging定义了5个标准级别(按严重程度递增):
- DEBUG:详细信息,通常用于调试
- INFO:确认程序按预期运行
- WARNING:表示意外情况或潜在问题
- ERROR:由于更严重的问题,程序无法执行某些功能
- CRITICAL:严重错误,程序可能无法继续运行
默认级别是WARNING,只有达到或超过该级别的日志才会被记录。
import logging
logging.debug('调试信息') # 不会输出
logging.info('普通信息') # 不会输出
logging.warning('警告信息') # 会输出
logging.error('错误信息') # 会输出
logging.critical('严重错误') # 会输出高级配置 #
1. 基本配置 #
import logging
logging.basicConfig(
level=logging.DEBUG, # 设置日志级别
filename='app.log', # 日志文件
filemode='a', # 追加模式
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logging.debug('这是一条调试信息')2. 日志格式说明 #
常用的格式字段:
%(asctime)s:日志创建时间%(levelname)s:日志级别%(message)s:日志消息%(name)s:日志记录器名称%(lineno)d:调用日志记录的行号%(funcName)s:调用日志记录的函数名
3. 记录异常信息 #
import logging
try:
1 / 0
except ZeroDivisionError:
logging.error("发生了除零错误", exc_info=True)
# 或者简写为
logging.exception("发生了除零错误")日志记录器(Logger) #
对于更复杂的应用,建议使用Logger对象而不是模块级函数。
1. 创建和使用Logger #
import logging
# 创建Logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)
# 创建Handler(控制台输出)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 创建Formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 将Formatter添加到Handler
ch.setFormatter(formatter)
# 将Handler添加到Logger
logger.addHandler(ch)
# 使用Logger记录日志
logger.debug('调试信息')
logger.info('普通信息')2. 多个Handler #
可以为一个Logger添加多个Handler,比如同时输出到控制台和文件:
# 创建文件Handler
fh = logging.FileHandler('app.log')
fh.setLevel(logging.WARNING)
fh.setFormatter(formatter)
logger.addHandler(fh)日志过滤器(Filter) #
可以创建自定义过滤器来控制哪些日志记录会被处理:
class MyFilter(logging.Filter):
def filter(self, record):
# 只允许包含"important"的消息通过
return "important" in record.getMessage()
logger.addFilter(MyFilter())
logger.info("这是一条普通信息") # 不会被记录
logger.info("这是一条important信息") # 会被记录日志配置方式 #
1. 字典配置(Python 3.2+) #
import logging.config
config = {
'version': 1,
'formatters': {
'detailed': {
'format': '%(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s'
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'INFO',
},
'file': {
'class': 'logging.FileHandler',
'filename': 'app.log',
'mode': 'w',
'formatter': 'detailed',
}
},
'root': {
'level': 'DEBUG',
'handlers': ['console', 'file']
},
}
logging.config.dictConfig(config)2. 文件配置 #
可以创建一个配置文件(如logging.conf):
[loggers]
keys=root
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log', 'a')
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S然后在代码中加载:
import logging.config
logging.config.fileConfig('logging.conf')最佳实践 #
不要使用root logger:为每个模块创建自己的logger
logger = logging.getLogger(__name__)合理设置日志级别:生产环境通常使用INFO或WARNING,开发环境使用DEBUG
记录异常时使用exception方法:它会自动包含堆栈信息
避免在日志消息中拼接字符串:使用格式化方式
# 推荐 logger.debug('User %s logged in', username) # 不推荐 logger.debug('User ' + username + ' logged in')为长期运行的应用配置日志轮转:
from logging.handlers import RotatingFileHandler handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=5)
logging模块功能强大且灵活,合理使用可以大大提高应用程序的可维护性和可调试性。