python之logging模块学习

一般在python中查看一些变量信息和程序运行情况都采用print函数打印到控制台,然而python的logging模块功能强大。从今天起学习一下logging,告别傻瓜式输出吧~

1.初识logging

1.1简单日志打印

导入格式:

import logging

logging提供了一组便利的函数,用来做简单的日志。它们分别是 debug()、 info()、 warning()、 error() 和 critical()。
日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET)。
logging输出到控制台的默认等级是WARNING,因此我们可以看到只有warning以上的等级才会被输出。

logging.debug('this is debug,打印调试信息,级别最低')
logging.info('this is info,打印正常操作信息')
logging.warning('this is warning,打印警告信息')
logging.error('this is error!打印错误信息')
logging.critical('this critical!打印致命错误信息,级别最高')
WARNING:root:this is warning,打印警告信息
ERROR:root:this is error!打印错误信息
CRITICAL:root:this critical!打印致命错误信息,级别最高

1.2日志级别配置

如果我们想把debug和info也打印出来,使用 basicConfig 对日志打印级别进行配置:

logging.basicConfig(level=logging.DEBUG)

这样debug及其以上级别的信息都会被打印出来,我们可以根据自己的需求来设置日志打印级别。

DEBUG:root:this is debug,打印调试信息,级别最低
INFO:root:this is info,打印正常操作信息
WARNING:root:this is warning,打印警告信息
ERROR:root:this is error!打印错误信息
CRITICAL:root:this critical!打印致命错误信息,级别最高

1.3配置日志格式及日志文件输出位置

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

参数名含义
filename创建FiledHandler,这样日志会被存储在指定的文件中。
filemode文件打开方式,指定filename时使用该参数,w为写模式,a为追加模式
format指定handler使用的日志显示格式
datefmt指定日期时间格式
level设置rootlogger日志级别
stream用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中常用的格式化串:

格式串含义
%(name)sLogger的名字
%(levelno)s打印日志级别的数值
%(pathname)s打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s打印当前执行程序名
%(funcName)s打印日志的当前函数
%(lineno)d打印日志的当前行号
%(asctime)s打印日志的时间
%(thread)d打印线程ID
%(threadName)s打印线程名称
%(process)d打印进程ID
%(message)s打印日志信息

我们把指定格式的日志输出到文件:

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                    filename='test.log',
                    filemode='w')

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

test.log文件内容如下:
在这里插入图片描述

2.logging模块化设计

logging 库采取了模块化的设计,提供了许多组件:记录器、处理器、过滤器和格式化器

模块作用
Logger暴露了应用程序代码能直接使用的接口
Handler将(记录器产生的)日志记录发送至合适的目的地
Filter提供了更好的粒度控制,它可以决定输出哪些日志记录
Formatter指明了最终输出中日志记录的布局

2.1 Logger

Logger 对象要做三件事情。

  • 首先,向应用代码暴露了许多方法,这样应用可以在运行时记录消息
  • 其次,记录器对象通过严重程度(默认的过滤设施)或者过滤器对象来决定哪些日志消息需要记录下来。
  • 第三,记录器对象将相关的日志消息传递给所有感兴趣的日志处理器。

常用的记录器对象的方法分为两类:配置和发送消息
常用的配置方法如下:

方法作用
Logger.setLevel()指定logger将会处理的最低的安全等级日志信息
Logger.addHandler()和Logger.removeHandler()从记录器对象中添加和删除处理程序对象
Logger.addFilter()和Logger.removeFilter()从记录器对象添加和删除过滤器对象

2.2 Handler

处理程序对象负责将适当的日志消息(基于日志消息的严重性)分派到处理程序的指定目标。
常用的有4种:

1) logging.StreamHandler -> 控制台输出

2) logging.FileHandler -> 文件输出
3) logging.handlers.RotatingFileHandler -> 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件

这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2…最后重新创建 chat.log,继续输出日志信息。

它的构造函数为:

RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
参数含义
filename文件名
mode写入模式
maxBytes最大文件大小 ,maxBytes=0则日志文件可以无限大
backupCount指定保留的备份文件的个数

4) logging.handlers.TimedRotatingFileHandler -> 按照时间自动分割日志文件
间隔一定时间就 自动创建新的日志文件。重命名的过程RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。

它的构造函数是:

TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])

其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。
它有以下取值:

  • S 秒
  • M 分
  • H 小时
  • D 天
  • W 每星期(interval==0时代表星期一)
  • midnight 每天凌晨

下面看一个示例:
需求:
输出log到控制台以及将日志写入log文件。
保存2种类型的log, all.log 保存debug, info, warning, critical 信息, error.log则只保存error信息,同时按照时间自动分割日志文件。

代码如下:

import logging
from logging import handlers

class Logger(object):
    #日志级别关系映射
    level_relations = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARNING,
        'error':logging.ERROR,
        'critical': logging.CRITICAL
    }

    def __init__(self,filename,level='info',when='S',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s:%(message)s'):
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt)                  #设置日志格式
        self.logger.setLevel(self.level_relations.get(level))#设置日志级别
        sh = logging.StreamHandler()                         #设置向屏幕输出
        sh.setFormatter(format_str)                          #设置屏幕上显示的格式
        # 往文件里写入#指定间隔时间自动生成文件的处理器
        th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')
        th.setFormatter(format_str)
        self.logger.addHandler(sh)
        self.logger.addHandler(th)

if __name__ == '__main__':
    log = Logger('all.log',level='debug')
    log.logger.debug('debug')
    log.logger.info('info')
    log.logger.warning('警告')
    log.logger.error('报错')
    log.logger.critical('严重')
    Logger('error.log',level='error').logger.error('error')

控制台输出为:
在这里插入图片描述
when=‘S’,生成的文件如下:
在这里插入图片描述
参考博客:
https://www.cnblogs.com/nancyzhu/p/8551506.html
https://blog.csdn.net/Runner1st/article/details/96481954

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值