Python--日志模块Logging

日志在程序中是很重要且必要的,有良好日志记录的程序,在定位问题的时候能快速帮你找到问题的原因。
Python标准库的Logging提供了一些方便的函数,有debug()、info()、warning()、error()和critical()。可以很方便的在程序中使用它们。
执行的动作最好的方式
在一个命令行脚本或程序中显示使用说明到控制台print()
报告一个程序在正常操作时发生的事logging.info()(或logging.debug()输出更详细的信息为了诊断程序
运行时的问题警告logging.waring(),客户端不能做什么,但是这个事件需要被记录
报告运行式的错误抛出一个异常
报告一个错误发生时的处理建议logging.error()、logging.exception()或logging.critical()

标准的日志级别和它们的适用性描述如下:
LevelWhen it's used
DEBUG详细信息,诊断程序的时候使用
INFO证明程序如期望般运行着
WARNING表明某些事发生在意料之外或在不久的将发生问题
ERROR表明相对严重的问题,软件没有能力执行一些功能
CRITICAL很严重的问题,软件无法继续执行
默认级别是WARNING
简单的例子:
import logging
logging.warning('Watch out!')  # 将会输出
logging.info('I told you so')  # 将不会输出
记录日志到文件
常见的是把日志记录到文件中。
import logging
logging.basicConfig(filename='example.log', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this,too')
多个模块中使用logging
# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()

# mylib.py
import logging
def do_something():
    logging.info('Doing something')
当运行myapp.py,在myapp.log中将看到如下信息:
INFO:root:Started
INFO:root:Doing something
INFO:root:Finished
这只是 简单的用法,不能知道日志来自哪个模块。
日志中变量数据
import logging
logging.warning(' %s before you %s', 'Look', 'leap!')
输出:
WARNING:root:Look before you leap!
日志记录的格式
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should apear on the console')
logging.info('So should this')
logging.warning('And this,too')
在日志中显示时间
import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged')
输出:
2017-06-25 17:14:32,825 is when this event was logged
定制日期显示格式:
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
输出:
12/12/2010 11:46:36 AM is when this event was logged.
datefmt的参数和time.strftime()支持的一样
高级日志教程
logging库提供了一些模块方法和组件:loggers、handlers、filters和formatters。
  • Loggers暴露接口给应用直接使用
  • Handlers发送日志(loggers生成的)到正确的目的地
  • Filters决定哪些日志被记录输出
  • Formatters指定日志显示的格式
日志事件信息通过loggers,handlers,filters和formatters成为一个LogRecord实例。
一个好的习惯是使用模块级logger,定义如下:
logger = logging.getLogger(__name__)
Loggers
Loggers对象有三重作用
第一,暴露一些方法给应用代码,以便应用在运行时可以记录日志。
第二,logger对象决定了哪些日志信息在日志级别和过滤器之上。
第三,logger对象传递有关的日志信息给感兴趣的log handlers。

最广泛使用logger分为两类:配置和信息发送
下面是几个最常用的logger配置方法:
  • Logger.setLevel() 指定一个logger将处理的日志级别
  • Logger.addHandler()和Logger.removeHandler() 从logger对象中添加和删除handler
  • Logger.addFilter()和Logger.removeFilter() 从logger对象中添加和删除filter对象
当logger被配置后,下面的方法将创建日志信息:
  • Logger.debug()、Logger.info()、Logger.warning()、Logger.error()和Logger.critical()
  • Logger.exception() 创建一个类似Logger.error()的日志信息,不同点是Logger.exception()会输出堆栈信息
  • Logger.log()
getLogger()返回一个指向logger实例的引用(如果提供名字的话就返回特定名字,没有的话为root)。
Handlers
Handler对象可靠的分发正确的日志给handler所指定的目的地。Logger对象可以使用addHandler()方法添加0个或多个handler给自己,比如一个使用场景是,应用想发送所有的日志给一个日志文件,error或更高级别的日志发送到标准输出,critical日志以邮件发送。这种场景需要三个handler,分别发送日志到指定地方。
  • setLevel() 和logger对象的一样,指定日志的级别,这里为什么会有两个setLevel()方法呢?logger对象设置的日记级别决定哪些级别的日志会传到它的handler(),每个handler设置的日志级别决定哪些级别的日志会被发送到目的地。
  • setFormatter() handler选择一个Formatter对象去使用。
  • addFilter()和removeFilter()每个handler分别配置和取消配置filter对象。
应用程序不应该直接使用Handler对象的实例,而是Handler作为基类,为子类定义行为一致的接口。
Formatters
Formatter对象配置最终日志的顺序、结构和内容,不像基类logging.Handler,应用程序代码可以实例化formatter类,如果你需要特别的行为,你也可以使用formatter的子类。Formatter的构造器有三个可选参数,一个日志格式字符串,一个时间日期格式字符串和一个风格指示器。
logging.Formatter.__init__( fmt=None, datefmt=None, style='%')
如果没有format字符串,默认使用行消息
如果没有时间日志格式字符串,默认使用的格式如下:
%Y-%m-%d %H:%M:%S
style有三种:%,'{'或‘$',如果没有指定,默认是%
如果style是%,消息格式字符串时使用%(<dictionary key>)s 去替换;
如果style是'{ ',消息字符串的格式被假定和str.format()一致(使用关键字参数)
如果style是’$',消息字符串的格式符合string.Template.substiute()定义的

配置Logging
程序配置logging有以下三种方式:
1. 使用上面介绍的配置方法创建loggers,handlers和formatters
2. 创建一个日志配置文件然后使用fileConfig()去读取。
3. 创建一个字典配置信息然后使用dictConfig()去解析。
import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
输出:
$ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message

一些有用的Handler

除了基类Handler之外,下面是一些很有用的子类:
1. StreamHandler--实例发送消息到流(file-like对象)
2. FileHandler--实例发送消息到磁盘文件
3. BaseRotatingHandler--绕接日志文件的基类,不能被直接实例化,使用RotatingFileHandler或TimeRotatingFileHandler
4. RotatingFileHandler--发送消息到磁盘文件并支持日志文件大小达到规定大小时绕接。
5. TimeRotatingFileHandler--发送消息到磁盘文件,并支持在确定的时间点时绕接文件。
6. SocketHandler--发送消息给TCP/IP sockets,自3.4起支持Unix的域名sockets。
7. DatagramHandler--发送消息给UDP sockets,自3.4起支持Unix的域名sockets
8. SMTPHandler--以邮件方式发送消息
9. SysLogHandler--发送消息给Unix的守护进程,有可能是远端机器
10. NTEventLogHandler--发送消息给NT/2000/XP的event log
11. MemoryHandler--发送消息到内存缓存区,当指定的条件达到时将被清除。
12. HTTPHandler--使用GET或POST方法发送消息到HTTP服务器
13. WatchedFileHandler--观察正在使用的日志文件,当文件改变时,就关闭然后重新打开,只支持linux系统
14. QueueHandler--发送消息给一个队列,例如queue或multiprocessing这些使用queue的模块
15. NullHandler--发生错误日志时不做任何事情
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值