Python日志 logging模块用法

logging模块

日志级别

logging中的日志级别是通过数值比较来进行的,可以是非下列表中的数值,但不推荐。

Levelvalue
CRITICAL50
ERROR40
WARNING30,default
INFO20
DEBUG10
NOTSET0

设置通知level后,低于该级别的日志信息都会被忽略。

使用log时需要传入上述级别参数

也可以直接使用下列方法

critical() error() waring() info() debug()

格式化字符串

属性名格式描述
asctime%(asctime)s当前时间
message%(message)s输出时追加的内容
filename%(filename)s文件名
funcName%(funcName)s函数名
levelname%(levelname)s级别名
levelno%(levelno)s级别数值
module%(module)s模块名
name%(name)s调用者名称
process%(process)d进程id
thread%(thread)d线程id
processName%(processName)s进程名
threadName%(threadName)s线程名

logging.basicConfig()

参数用法
level设置等级,默认WARNING
format使用上面的格式化字符串来设置,会添加到输出的字符串前
datefmt对asctime单独格式化
filename传入一个文件名,将输出写入文件
filemode打开模式,默认使用a模式
import logging

fmt = '%(asctime)s %(levelname)s %(message)s'

logging.basicConfig(level=logging.INFO, 
                    format=fmt, 
                    datefmt='%Y-%m-%d %H:%M:%S')


logging.warning('hello logging')

#>>>2020-07-30 16:43:01 WARNING hello logging

输出时是支持C风格格式化字符串的

logging.warning('%d %s', 123, 'string')

#>>>2020-07-30 16:45:59 WARNING 123 string
extra

除了模块自带的格式化属性外,也可以自己定义并使用extra参数传入

import logging

fmt = '%(asctime)s %(levelname)s %(message)s %(descrip)s' #descrip属性是自定义的

logging.basicConfig(level=logging.INFO, format=fmt, datefmt='%Y-%m-%d %H:%M:%S')


logging.warning('hello logging', extra={'descrip':'这里需要一个字典'})

#>>>2020-07-30 16:50:07 WARNING hello logging 这里需要一个字典

进阶用法

在上面的使用中,调用的都是logging模块中的函数,其实在函数的调用过程中已经创建了实例。使用logging.getLogger(name)方法来获取实例。如果传入的name为空字符串或者传参时会返回root实例。

继承

  • 这里的继承有别于面向对象的继承

  • 获取到的实例存在继承关系,默认继承于root实例。如果name字符串中存在.的话,例如s.s1,如果此时s存在,s1的父就为s。并且在创建时父就存在的话,就会从父继承到level属性。

logging.getLogger(name)

利用该实例直接来调用critical(),error(),waring(),info() ,debug()等就能应用个性的level了

方法用法
setLevel重新设置级别
getEffectiveLevel返回有效级别
parent返回父对象
addHandler添加一个Handler

Handler

使用getLogger获取到的实例无法直接来设置format和datefmt,这时需要handler来进行设置

logging模块中提供了以下几个Handler

  • Handler

    • FileHandler
  • StreamHandler

    • NullHandler

参数or用法
FileHandlerfilename:文件名 mode:打开模式 encoding:文本编码
StreamHandler可以传入一个输出流,默认是sys.stderr标准错误输出
NullHandler什么也不干

主要方法

方法用法
setLevel设置级别
setFormat与basicConfig相同的格式字符串
addFilter增加过滤器

通过logging.getLogger(name)返回的实例的addHandler来增加Handler实例

特性

Handler和logging.Logger实例都有各自level,判断的时候如何来判断,继承时又该如何继承

  • 将logging.Logger和Handler单独来看,logging.Logger是log的一个对象,而Handler是具体输出的一个工具。类似于人和打印机之间的关系。
  • 继承时只继承父的level
  • 判断时会判断当前Logger对象的level,如果输出的是有效的level,就会依次判断自身和祖先的Handler,如果大于等于Handler的level就会执行该Handler,不会再判断祖先logger对象的level了。
  • 把logger实例比作一个员工的话。如果要打印的内容符合员工要求的话,员工就开始找打印机,将自己家族(即自己到祖先)的所有符合要求的打印机都拿来打印。
  • 像上面我们直接使用logging的函数来输出,其实隐式地创建了root实例,并可以通过logging.basicConfig()来修改其Handler。(注意:logging.basicConfig()的参数level指的是logger对象的level,而非Handler)

注意:如果logger对象的propagate属性为False,则只会使用自身的Handler,缺省值为True

流程图

addFilter

将指定的过滤器 filter 添加到此处理器。判断顺序和规则与level相同。

Filter类

使用一个logger名来初始化。基本过滤器类只允许低于日志记录器层级结构中低于特定层级的事件。 例如,一个用 ‘A.B’ 初始化的过滤器将允许 ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’ 等日志记录器所记录的事件。 但 ‘A.BB’, ‘B.A.B’ 等则不允许。 如果用空字符串初始化,则所有事件都会被略过。

建议

由于Python模块不会重复加载的特性,当多个模块之间都使用了Logger时,可能会出现字符串重复的情况。建议使用模块名来实例化Logger对象,模块名具有唯一性,而在同一模块中也可以用模块名+函数名的方式。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值