首页 > 编程语言 > 详细

Python日志处理--【logging】

时间:2019-12-10 15:40:58      阅读:71      评论:0      收藏:0      [点我收藏+]

在程序开发完成之后,我们会把它部署到生产环境中去,这时候代码相当于是在一个黑盒环境下运行的,我们只能看到其运行的效果,是不能直接看到代码运行过程中每一步的状态的。在这个环境下,运行过程中难免会在某个地方出现问题,甚至这个问题可能是我们开发过程中未曾遇到的问题。因此,日志记录非常有必要的,任何一款软件如果没有标准的日志记录,都不能算作一个合格的软件。

 

1、日志级别

首先来了解一下输出日志的等级信息,logging模块共提供了如下等级,每个等级其实都对应了一个数值,列表如下:

等级 数值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTEST 0

我们自定义日志级别时注意不要和默认的日志级别数值相同,logging 执行时输出大于等于设置的日志级别的日志信息,如设置日志级别是 INFO,则 INFO、WARNING、ERROR、CRITICAL 级别的日志都会输出。

2、logging流程

官方的 logging 模块工作流程图如下:

技术分享图片

从上图中我们可以看出看到这几种 Python 类型,LoggerLogRecordFilterHandlerFormatter

类型说明:

Logger:日志,暴露函数给应用程序,基于日志记录器和过滤器级别决定哪些日志有效。

LogRecord :日志记录器,将日志传到相应的处理器处理。

Handler :处理器, 将(日志记录器产生的)日志记录发送至合适的目的地。

Filter :过滤器, 提供了更好的粒度控制,它可以决定输出哪些日志记录。

Formatter:格式化器, 指明了最终输出中日志记录的布局。

大体流程:

  • 判断 Logger 对象对于设置的级别是否可用,如果可用,则往下执行,否则,流程结束。
  • 创建 LogRecord 对象,如果注册到 Logger 对象中的 Filter 对象过滤后返回 False,则不记录日志,流程结束,否则,则向下执行。
  • LogRecord 对象将 Handler 对象传入当前的 Logger 对象,(图中的子流程)如果 Handler 对象的日志级别大于设置的日志级别,再判断注册到 Handler 对象中的 Filter 对象过滤后是否返回 True 而放行输出日志信息,否则不放行,流程结束。
  • 如果传入的 Handler 大于 Logger 中设置的级别,也即 Handler 有效,则往下执行,否则,流程结束。
  • 判断这个 Logger 对象是否还有父 Logger 对象,如果没有(代表当前 Logger 对象是最顶层的 Logger 对象 root Logger),流程结束。否则将 Logger 对象设置为它的父 Logger 对象,重复上面的 3、4 两步,输出父类 Logger 对象中的日志输出,直到是 root Logger 为止。

3、日志输出格式

日志的输出格式可以按需设置,默认格式为下图所示:
技术分享图片

4、基本使用

logging 使用非常简单,使用 basicConfig() 方法就能满足基本的使用需要,如果方法没有传入参数,会根据默认的配置创建Logger 对象,默认的日志级别被设置为 WARNING,默认的日志输出格式如上图,该函数可选的参数如下表所示。

参数名称 参数描述
filename 日志输出到文件的文件名
filemode 文件模式,r[+]、w[+]、a[+]
format 日志输出的格式
datefat   日志附带日期时间的格式 
level 设置日志输出级别
stream 定义输出流,用来初始化 StreamHandler 对象,不能和 filename 参数一起使用,否则会ValueError 异常
style  格式占位符,默认为 "%" 和 “{}”
handles 定义处理器,用来创建 Handler 对象,不能和 filename 、stream 参数一起使用,否则也会抛出 ValueError 异常

示例代码如下:

import logging

logging.basicConfig()
logging.debug(‘This is a debug message‘)
logging.info(‘This is an info message‘)
logging.warning(‘This is a warning message‘)
logging.error(‘This is an error message‘)
logging.critical(‘This is a critical message‘) 

输出结果如下:

WARNING:root:This is a warning message
ERROR:root:This is an error message
CRITICAL:root:This is a critical message


传入常用的参数,示例代码如下(这里日志格式占位符中的变量放到后面介绍):

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
logging.debug(‘This is a debug message‘)
logging.info(‘This is an info message‘)
logging.warning(‘This is a warning message‘)
logging.error(‘This is an error message‘)
logging.critical(‘This is a critical message‘)

生成的日志文件 test.log ,内容如下:

13-10-18 21:10:32 root:DEBUG:This is a debug message
13-10-18 21:10:32 root:INFO:This is an info message
13-10-18 21:10:32 root:WARNING:This is a warning message
13-10-18 21:10:32 root:ERROR:This is an error message
13-10-18 21:10:32 root:CRITICAL:This is a critical message


但是当发生异常时,直接使用无参数的 debug()、info()、warning()、error()、critical() 方法并不能记录异常信息,需要设置 exc_info 参数为 True 才可以,或者使用 exception() 方法,还可以使用 log() 方法,但还要设置日志级别和 exc_info 参数。

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
a = 5
b = 0
try:
    c = a / b
except Exception as e:
    # 下面三种方式三选一,推荐使用第一种
    logging.exception("Exception occurred")
    logging.error("Exception occurred", exc_info=True)
    logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)

 



参考:https://juejin.im/post/5bc2bd3a5188255c94465d31#heading-3 

 

Python日志处理--【logging】

原文:https://www.cnblogs.com/deeo/p/12016288.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!