Python logging模块的使用技巧


日志的级别:

  • DEBUG
  • INFO
  • WARNNING
  • ERROR
  • CRITICAL

几个重要的概念

  1. Logger:记录器,是应用程序直接使用的借口
  2. Handler处理器,将(记录器)产生的日志记录发送往合适的借口
  3. Filter:过滤器,提供更好的输出控制,可以决定输出哪些日志记录
Logger

 Logger是一个树级的结构,使用debug,info等前一定要创建Logger实例,即创建一个记录器。如果没有显式的创建,默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即讲日志信息打印输出在标准的输出上),和格式化器(默认的格式是第一个简单使用程序中输出的样式)。

#创建方法:
logger = logging.getLogger(logger_name)

 创建Logger实例后,可以使用如下的方法设置日志级别,增加处理器Handler。

  • logger.setLevel(logging.DEBUG)
  • logger.addHadnler(handler_name)
  • logger.removeHandler(handler_name)
Handler处理器

 Handler的处理器类型有很多种,常见有三个,Streamhandler,FileHandler,NullHandler
 创建StreamHandler后可以使用如下的方法设置日志级别(level),格式化器(Formatter),过滤器(Filter):

  • ch.setLevel(logging.WARN)
  • ch.setFormatter(formatter_name)
  • ch.addFilter(filter_name)
  • ch.removeFilter(filter_name)
#StreamHandler的创建方法:
sh = logging.StreamHandler(stream=None)
#FileHandler创建方法
fh = logging.FileHandler(filename,mode='a',encoding=None,delay=False)
#NullHandler创建方法
这玩意没什么用,由库开发者使用
Formatter格式化器

 使用Formatter对象设置日志信息的最后贵的,结构和内容,默认的时间格式位__%Y-%m-%d%H:%M:%S__

#创建方法:
formatter = logging.Formatter(fmt=None,datafmt=None)
其中fmt是消息的格式化串,datafmt是日志字符串,如果不指定fmt将会使用%(message)s' 如果不指明datefmt将使ISO8601的日期格式。
Filter过滤器

 Handler和Logger都可以使用Filter完成比级别完成更复杂的过滤,Filter基类仅允许指定Logger层次一下的事件,例如使用’A.B’初始化的Filter允许Logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’等记录的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。 如果用空字符串来初始化,所有的事件都接受。

filter = logger.Filter(name=' ')
Logger Handler Filte Formatter几种关系,该关系可以使用如下图进行描述:

几种实例之间的关系
由上图可以知,Logger是一个树形的结构,Logger可以包括多个Handler和Filter,一个Handler可以有多个Formatter和Filter,并且日志级别将会继承。

Logging的工作流程

Logging的工作流程

    1. 由上图可以知道,如果使用者的代码中产生了日志提交,首先进行判断登记等级是否大于Logger实例的等价,如果小于,会抛弃这个日志,否则进入下一步.
    1. 创建日志,使用注册到Logger中的Filter进行过滤,轮流进行过滤,如果有一个把他过滤掉了,终止。否则等所有的过滤完成后进入下一步。
    1. 日子继续往下流
    • 日志流向所有注册在Logger中的Handlers,首先判断等级够不够,接着判断有没有过滤器,都不能拒绝日志的话,将会格式化输出(会产生额外的信息,比如在哪个文件那一行等)。
    1. 判断日志能够进行传播,如果可以并且有父类Logger,那么将会送入父类进行处理。

几种配置方式

#下面是一些模块级别的函数:
getLogger返回指定name的日志记录器,name=None时候返回层级结构总为根级别的记录器,如果指定了name,name一般是用a. a.b a.b.c.d,这些名称自定义
logging.getLogger(name=None)

logging.GetLoggerClass() 返回标准的Logger类
常见的logging.debug('')都是在根记录器中产生消息

logging.disable(level=logging.CRITICAL),以为重载的形式会作用在所有的Logger,一般用来限制全局
logging.addLevelName(level,levelName) 自己定义一个等级对应的名字,如30对应一个MyDebug
logging.basicConfig(**   kwags) 使用磨人的Formatte创建一个StreamHandler并加入根日志记录起,如果没有为跟记录器定已处理程序,那么debug()等会自动调用basicConfig。如果根日志记录器配置了处理程序,不执行任何操作。
#logging.shutdown

 上述提到的支持一下参数:

名字功能
filename指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了
filemode指定日志文件的打开模式,默认为’a’。需要注意的是,该选项要在filename指定时才有效
format指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。
datafmt指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
level指定日志器的日志级别
stream可以指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常
handlers该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。
encoding
errors

一个例子

# -*- encoding:utf-8 -*-
import logging

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)

# create file handler
log_path = "./log.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARN)

# create formatter
fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)

# add handler and formatter to logger
fh.setFormatter(formatter)
logger.addHandler(fh)

# print log info
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')```

##### 文件配置
配置文件logging.conf如下:
```[loggers]
keys=root,example01

[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[handlers]
keys=hand01,hand02

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('log.log', 'a')

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s```

使用程序logger.py如下:
```#!/usr/bin/python
# -*- encoding:utf-8 -*-
import logging
import logging.config

logging.config.fileConfig("./logging.conf")

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')```

##### 字典配置
有兴趣的童靴可以使用```logging.config.dictConfig(config)```编写一个示例程序发给我,以提供给我进行完善本文。

#### 监听配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值