记录程序运行情况的最简单的方法就是直接将log信息打印出来, 但是这样做有很多弊端: 1. 会有大量不相关的垃圾日志, 2. 只能通过修改大量的print语句来控制这些输出, 有可能会忘记删除某些无用的输出语句, 3. 打印出的日志会和其他输出到stdout的数据混淆.好在Python提供了负责标准模块Logging来进行日志管理. 一个简单示例如下:
import logging# 设定logger会处理的log的最低等级, CRITICAL > ERROR > WARNING > INFO > DEBUGlogging.basicConfig(level=logging.INFO)# 设定一个logger, 命名一般__name__logger = logging.getLogger(__name__)logger.info('Start reading database')# 读取数据库records = {'john': 55, 'tom': 66}logger.debug('Records: %s', records)logger.info('Updating records ...')# 更新记录logger.info('Finish updating records')
输出的结果为
INFO:__main__:Start reading databaseINFO:__main__:Updating records ...INFO:__main__:Finish updating records
通过上例我们发现可以通过给log设置不同的等级来过滤掉不太重要的log. 另外, 还可以将log输出到log文件中:使用合适的等级来记录日志logging模块本身提供很多种日志等级, 我们需要在不同的情况下使用合适的等级.Debug: 该等级一般用在debug时, 比如记录循环中的状态改变Info: 该等级一般用在输出一些一般重要的信息Warning: 该等级一般用在记录比较重要的信息, 比如用户登录时密码输入错误Error: 该等级一般用在记录一些错误信息使用__name__为logger命名通过将logger命名为__name__会有一些好处, 比如在foo.bar.my_module中调用
logger,getLogger(__name__)
?相当于调用
logger.getLogger("foo.bar.my_module")
?, 这样当你配置”foo”的logger时, 所有“foo”package中的模块都会共享这些配置.捕获异常并记录其traceback可以通过设置
exc_info=True
?来记录traceback
try: open('/path/to/does/not/exist', 'rb')except (SystemExit, KeyboardInterrupt): raiseexcept Exception, e: logger.error('Failed to open file', exc_info=True)
输出结果为
ERROR:__main__:Failed to open fileTraceback (most recent call last): File "example.py", line 6, in <module> open('/path/to/does/not/exist', 'rb')IOError: [Errno 2] No such file or directory: '/path/to/does/not/exist'
?通过Json配置logger示例代码
import osimport jsonimport logging.configdef setup_logging( default_path='logging.json', default_level=logging.INFO, env_key='LOG_CFG'): """Setup logging configuration """ path = default_path value = os.getenv(env_key, None) if value: path = value if os.path.exists(path): with open(path, 'rt') as f: config = json.load(f.read()) logging.config.dictConfig(config) else: logging.basicConfig(level=default_level)
配置文件为:
{ "version": 1, "disable_existing_loggers": false, "formatters": { "simple": { "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" } }, "handlers": { "console": { "class": "logging.StreamHandler", "level": "DEBUG", "formatter": "simple", "stream": "ext://sys.stdout" }, "info_file_handler": { "class": "logging.handlers.RotatingFileHandler", "level": "INFO", "formatter": "simple", "filename": "info.log", "maxBytes": "10485760", "backupCount": "20", "encoding": "utf8" }, "error_file_handler": { "class": "logging.handlers.RotatingFileHandler", "level": "ERROR", "formatter": "simple", "filename": "errors.log", "maxBytes": "10485760", "backupCount": "20", "encoding": "utf8" } }, "loggers": { "my_module": { "level": "ERROR", "handlers": ["console"], "propagate": "no" } }, "root": { "level": "INFO", "handlers": ["console", "info_file_handler", "error_file_handler"] }}
参考文献:[1]. Good logging practice in Python[2]. Logging HOWTO[3]. Logging Cookbook
779total views, no views today
原文地址:Python标准模块-Logging, 感谢原作者分享。 钱财何足贵,仁义值千金。