Python的logging模块!

Python的logging模块!


今天博主跟大家聊一聊如何使用Python的logging模块!不喜勿喷,如有建议欢迎补充、讨论!

关于安装和汉化可以观看博主的这篇文章《下载安装及汉化 》以及Python系列:windows10配置Python3.0开发环境!,安装完毕重启VsCode!以及VSCode配置Python开发环境!


Come on!logging模块简介

logging模块是Python的一个标准库模块,开发过程中,可以通过该模块,灵活的完成日志的记录。

logging模块提供了两种记录日志的方式:

  1. 使用logging提供的模块级别的函数(logging.basicConfig,logging.debug,logging.info…)
  2. 使用logging模块的组件(loggers,handlers,filters,formatters)

logging模块的日志级别

logging模块的日志级别(level)包括:DEBUG,INFO,WARNING,ERROR,CRITICAL

日志级别(level)描述
DEBUG调试级别,一般用于问题的排查,日志的信息最为详细
INFO仅记录普通的信息,日志信息的详细程度仅次于DEBUG
WARNING警告信息,一般这类信息不会影响程序的正常运行
ERROR错误信息, 出现错误信息时,程序一般已不能正常运行
CRITICAL更严重的错误信息,程序不能继续运行

从 DEBUG 到 CRITICAL,日志等级依次提高,即严重性逐步提升,日志的信息量依次减少:

DEBUG < INFO < WARNING < ERROR < CRITICAL

通过logging模块级别的函数记录日志
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   loggingDemo.py
@Time    :   2019/10/21 14:16:02
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib


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     # 默认的日志格式:日志级别 : Logger名称 : 用户输出消息。
# ERROR:root:error message
# CRITICAL:root:critical message

这里仅输出了大于等于WARNING级别的日志,说明 logging模块 默认的日志级别为WARNING,即日志级别大于等于WARNING的才会被输出,且默认情况下,日志会直接打印到标准输出中

通过 logging模块 的basicConfig函数可灵活地配置日志级别,日志格式以及日志的输出位置:(记得创建文件目录用于记录log)

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   loggingDemo.py
@Time    :   2019/10/21 14:16:57
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format=
    '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  # 日志格式
    datefmt='%Y-%m-%d %H:%M:%S',  # 时间格式:2019-10-21 XX:XX:XX
    filename='/tmp/test.log',  # 日志的输出路径
    filemode='a')  # 追加模式

logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

结果如下

2019-10-21 14:18:14 loggingdemo.py[line:25] DEBUG debug message
2019-10-21 14:18:14 loggingdemo.py[line:26] INFO info message
2019-10-21 14:18:14 loggingdemo.py[line:27] WARNING warning message
2019-10-21 14:18:14 loggingdemo.py[line:28] ERROR error message
2019-10-21 14:18:14 loggingdemo.py[line:29] CRITICAL critical message

logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

  • filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
  • filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
  • format:指定handler使用的日志显示格式。
  • datefmt:指定日期时间格式。
  • level:设置rootlogger(后边会讲解具体概念)的日志级别
  • stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中可能用到的格式化串:

  • %(name)s Logger的名字
  • %(levelno)s 数字形式的日志级别
  • %(levelname)s 文本形式的日志级别
  • %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
  • %(filename)s 调用日志输出函数的模块的文件名
  • %(module)s 调用日志输出函数的模块名
  • %(funcName)s 调用日志输出函数的函数名
  • %(lineno)d 调用日志输出函数的语句所在的代码行
  • %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
  • %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
  • %(asctime)s 字符串形式的当前时间。默认格式是 “2018-11-13 00:00:00,896”。逗号后面的是毫秒
  • %(thread)d 线程ID。可能没有
  • %(threadName)s 线程名。可能没有
  • %(process)d 进程ID。可能没有
  • %(message)s用户输出的消息

通过logging模块的组件记录日志

使用logging模块级别的函数记录日志,无法实现将日志输出到多个路径下。这里logging模块提供了4个组件,通过这些组件可实现将日志输出到多个路径下,且每个路径下的日志格式可单独配置

logging模块中用于记录日志的4大组件

组件名称功能描述
Logger日志器,提供了应用程序可一直使用的接口
Handler将 logger 产生的日志发送到指定的路径下(例如可以是终端,也可以是文件)
Filter若有多个 Logger,可根据名称过滤出指定的 Logger 来记录日志
Formatter定义日志格式

logging模块组件的使用,使用组件记录日志的大致步骤如下:

  1. logging.getLogger() 获取 logger对象
  2. 创建一个或多个 handler,用于指定日志信息的输出流向
  3. 创建一个或多个 formatter,指定日志的格式,并分别将 formatter 绑定到 上
  4. 将 handler 绑定到 logger对象 上
  5. logger.setLevel(logging.DEBUG) 设置日志级别
  6. 最后便可使用 logger对象 记录日志~
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   loggingDemo2.py
@Time    :   2019/10/21 14:23:58
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib

import logging

# 获取 logger对象
logger = logging.getLogger()

# 创建一个 handler,用于写入日志文件
fh = logging.FileHandler('/tmp/test.log')

# 再创建一个 handler,用于输出到控制台
ch = logging.StreamHandler()

# 创建一个 formatter,两个 handler 使用相同的日志格式
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 绑定 formatter 到 handler 上
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# 绑定 handler 到 logger对象 上
logger.addHandler(fh)  #logger对象可以添加多个fh和ch对象
logger.addHandler(ch)

# 设置日志级别
logger.setLevel(logging.WARNING)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

也可以通过 handler 来设置日志级别,当使用 handler 来设置日志级别时,存在如下两种情况:

  1. 若 handler 设置的日志级别小于等于 logger 的日志级别时,则以logger 的日志级别为准;
  2. 若 handler 设置的日志级别大于 logger 的日志级别时,则以handler 的日志级别为准;

就是,两者同时设置日志级别,以日志级别高的为准。由于不设置 logger 的日志级别,其默认日志级别就是 WARNING,所以不存在 handler 单独设置日志级别的情况

来验证一下:

  1. logger 日志级别设置为 DEBUG,logger 不设置(默认为WARNING)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   loggingDebug.py
@Time    :   2019/10/21 14:27:51
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib

import logging

logger = logging.getLogger()
ch = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setLevel(logging.DEBUG)
# logger.setLevel(logging.CRITICAL)

ch.setFormatter(formatter)
logger.addHandler(ch)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

# 输出结果:
# 2019-10-21 14:27:55,938 - root - WARNING - logger warning message
# 2019-10-21 14:27:55,939 - root - ERROR - logger error message
# 2019-10-21 14:27:55,940 - root - CRITICAL - logger critical message
  1. logger 日志级别设置为 CRITICAL,logger 设置为 ERROR
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   loggingCRITICAL.py
@Time    :   2019/10/21 14:28:56
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib

import logging

logger = logging.getLogger()
ch = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setLevel(logging.CRITICAL)
logger.setLevel(logging.ERROR)

ch.setFormatter(formatter)
logger.addHandler(ch)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

# 输出结果:
# 2019-10-21 14:28:44,488 - root - CRITICAL - logger critical message

filter组件 的使用

filter组件用来过滤 logger 对象,一个 filter 可以直接添加到 logger对象上,也可以添加到 handler 对象上。

定义一个filter: filter = logging.Filter(‘a.b’),当把这个 filter 添加到一个 handler 上,那么绑定了该 handler 的 多个 logger对象中,只有名字是 ‘a.b’ 前缀的才能通过该 handler 输出日志

在 handler 上添加 filter:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   haldeFilte.py
@Time    :   2019/10/21 14:31:29
@Author  :   YongJia Chen 
@Version :   1.0
@Contact :   chen867647213@163.com
@License :   (C)Copyright 2018-2019, Liugroup-NLPR-CASIA
@Desc    :   None
'''

# here put the import lib


import logging

logger1 = logging.getLogger('a.b.c')
logger2 = logging.getLogger('a.c')

# 定义一个 filter
filter = logging.Filter(name='a.b')

# 定义一个 handler
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)

# 若两个 logger对象 的日志级别相同,且都是用通过一个 handler,可以在这个 handler 上设置日志级别
ch.setLevel(logging.ERROR)

# 在 handler 上放置过滤器
ch.addFilter(filter)

logger1.addHandler(ch)
logger2.addHandler(ch)
logger1.error('logger1 error message')
logger2.error('logger2 error message')

# 输出结果:
# 2019-10-21 14:31:43,883 - a.b.c - ERROR - logger1 error message

可以看到 logger2 被过滤,只有 logger1 输出日志

快去动手试试吧!


到这里:Python的logging模块!分享完毕了,快去试试吧!


最后

  • 更多参考精彩博文请看这里:陈永佳的博客

  • 喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈永佳

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值