Python中logging模块

1、日志级别


日志级别


数值


Critical


50


Error


40


Warning


30


Info


20


Debug


10


Notset


0

日志级别指的是产生日志的事件的严重程度。

设置一个级别后,严重程度第一设置值得日志消息将被忽略。

Debug(),info(),warning(),error(),critical()方法;

2、格式字符串


属性


格式


描述


日志消息内容


%(message)s


The logged message,computed as msg %args,当调用 formatter.format()时候会被调用


Asctime


%(asctime)s


创建logrecord的可读时间,默认情况下,格式为2003-07-08 00:00:00,000(逗号后面的数字是毫秒部分的时间)


函数名


%(funcname)s


日志调用所在的函数名


日志级别名称


%(levelname)s


消息的级别名称‘debug,info,warning,error,critical’


日志级别数值


%(levelno)s


消息的级别数字,debug,info,warning,error,critical


行号


%(lineno)s


日志调用所在的源码行号


模块


%(module)s


模块(费了那么的名字部分)


进程ID


%(process)s


进程ID


线程ID


%(thread)d


线程ID


进程名


%(processname)s


进程名


线程名


%(threadname)s


线程名称

funName、threadName、processName都是小驼峰。

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT)

logging.info(‘{}‘.format(20))  #info不显示
logging.warning(‘{}‘.format(20)) #默认级别的

2018-06-13 11:01:56,992         Thread info:420 MainThread 20

上栗info不显示的原因是因为logging.basicConfig(format=FORMAT)  后面的默认值level的值是logging.WARNING 低于此级别的不进行显示处理。

改造以后

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT,level=logging.DEBUG)

logging.info(‘1{}‘.format(0))  #info不显示
logging.warning(‘2{}‘.format(0)) #默认级别的
logging.debug(‘3{}‘.format(0))
logging.error(‘4{}‘.format(0))
logging.critical(‘5{}‘.format(0))

2018-06-13 11:39:28,053         Thread info:6212 MainThread 10

2018-06-13 11:39:28,053         Thread info:6212 MainThread 20

2018-06-13 11:39:28,053         Thread info:6212 MainThread 30

2018-06-13 11:39:28,053         Thread info:6212 MainThread 40

2018-06-13 11:39:28,053         Thread info:6212 MainThread 50

格式化字符串是需要定义的。Schools自定义的。打印输出的时候利用extra显示定义的新定义的消息等。

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s %(school)s‘
logging.basicConfig(format=FORMAT,level=logging.INFO)

d = {‘school‘:‘baidu.com‘}
logging.info(‘i am %s %s‘,20,‘years old.‘,extra = d)
logging.warning(‘i am %s %s‘,20,‘years old.‘,extra = d)

2018-06-13 14:57:40,631         Thread info:8908 MainThread i am 20 years old. baidu.com

2018-06-13 14:57:40,631         Thread info:8908 MainThread i am 20 years old. baidu.com

3、修改日期格式

import logging

logging.basicConfig(format=‘%(asctime)s %(message)s‘,datefmt=‘%Y/%m/%d %I:%M:%S‘)
logging.warning(‘this event was logged‘)

2018/06/13 03:04:38 this event was logged

可以自己定义时间的格式,利用datefmt=新的时间格式即可以。

4、输出到文件

import logging
logging.basicConfig(format=‘%(asctime)s %(message)s‘,filename=‘test1.log‘)
for _ in range(5):
    logging.warning(‘this is event logged‘)

还可以输出日志到文件,只是需要filename指定文件存放地址

5、Logger类:

Loggin模块加载的时候,会创建一个root logger,跟logger对象的默认级别是WARNING,调用logging.basicConfig来调整级别,就是对这个跟logger的级别进行修改。

1)构造

Logging.getlogger([name=None])

使用工厂方法返回一个logger实例。

指定name,返回一个名称为name的logger的实例,如果再次使用相同的名字,就是实例化一个对象,未指定none,返回根logger实例。

2)层次结构

Logger是层次结构的,使用.点号分割,如a,a.b或者a.b.c.d,a是a.d的父parent,a.b是a的子child,对于foo来说,名字为foo.bar/foo.bar.bar/foo.bam都是foo的后代。

import logging

root = logging.getLogger()
print(root.name,type(root),root.parent,id(root))

logger = logging.getLogger(__name__)
print(logger.name,type(logger),id(logger.parent),id(logger))

loggerchild = logging.getLogger(__name__+‘.child‘)
print(loggerchild.name,type(loggerchild),id(loggerchild.parent),id(loggerchild))

root <class ‘logging.RootLogger‘> None 283120699768

__main__ <class ‘logging.Logger‘> 283120699768 283118806968

__main__.child <class ‘logging.Logger‘> 283118806968 283118808872

3)level级别设置

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT,level=logging.DEBUG)

logger = logging.getLogger(__name__)
print(logger.name,type(logger))
print(logger.getEffectiveLevel())

logger.info(‘hello‘)
logger.setLevel(28)

print(logger.getEffectiveLevel())
logger.info(‘hello2‘)
logger.warning(‘hello3 warning‘)

root = logging.getLogger()
root.info(‘hello4 info root‘)

2018-06-13 15:49:51,076         Thread info:8952 MainThread hello

__main__ <class ‘logging.Logger‘>

2018-06-13 15:49:51,076         Thread info:8952 MainThread hello3 warning

10

2018-06-13 15:49:51,076         Thread info:8952 MainThread hello4 info root

28

每一个logger创建后,都有一个等效的level。

Logger对象可以在创建后动态的修改自己的level。

不指定的话就是标准错误输出。

6、handler

Handler:主要工作的。

Handler控制日志信息的输出的目的地,可以是控制台、文件。

可以单独设置level   Handler都有独立的level。

可以单独设置格式

可以设置过滤器

Handler类继承。

Handler

Streamhandler不指定使用sys.stderr

filehandler文件

_stderrhandler 标准输出

Nullhandler 什么都不做

输出打印全部靠的是handler,真正干活的也是handler。

if handlers is None:
    filename = kwargs.pop("filename", None)
    mode = kwargs.pop("filemode", ‘a‘)
    if filename:
        h = FileHandler(filename, mode)
    else:
        stream = kwargs.pop("stream", None)
        h = StreamHandler(stream)
    handlers = [h]

如果设置文件名,则根logger加一个输出到文件handler;如果没有设置文件名,则为根logger加一个streamhandler,默认输出到sys.stderr

也就是说,根logger一定会至少有一个handler。

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT,level=logging.DEBUG)

logger = logging.getLogger(‘test‘)
print(logger.name,type(logger))
logging.info(‘line 1‘)

handler = logging.FileHandler(‘ll.log‘,‘w‘)
logger.addHandler(handler)

logger.info(‘line 2‘)

文件内的内容为line 2  控制台打印输出的内容为line1和line2,原因是因为设置的等级问题,没指定在控制台输出是因为继承的root的类,输出在控制台中。

7、日志流

Level的继承

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT,level=logging.INFO)
root = logging.getLogger()

log1 = logging.getLogger(‘s‘)
log1.setLevel(logging.INFO)

log2 = logging.getLogger(‘s.s1‘)
log2.warning(‘log2 warning‘)

2018-06-13 16:37:50,650         Thread info:8464 MainThread log2 warning

logger实例,如果设置了level,就用它和信息的级别比较,否则,继承最近的祖先的level。

继承关系及信息传递:

每一个logger实例的level如同入口。让水流进来,如果门槛太高,信息就无法进入,例如log3.warning(‘log3’),如果log3定义的级别高,就不会有信息通过log3

如果level没有设置,就用父logger的,如果父logger的level没有设置,继续找父的父,最终找到root上面,如果设置了就用他的,如果root没有设置,root的默认值是WARNING,

消息传递流程:

1)、如果消息在某个logger对象上产生,这个logger就是当前的logger,首先消息level要和当前的logger的effective比较,如果第一当前的logger的effectivelevel,则流程结束。

2)、日志记录会交给当前logger的所有handler处理,记录还要和每一个handler的级别分别比较,低的不处理,否则按照handler输出日志记录。

3)、当前logger的所有handler处理完后,就要看自己的propagate属性,如果是True表示向父logger传达这个日志,否则到此结束流程。

4)、如果日志记录仪传递到了父logger,不需要和logger的level比较,而是直接交给父的所有handler,父logger成为当前的logger,重复2,3步骤,直到当前的父logger是None退出,也就是说当前logger最后一般是root logger(是否能到root logger更看中间的logger是否允许propagate)。

Logger实话初始化的propagate属性为True,即允许向父logger传递消息。

Logger.basicConfig

如果root没有handler,就默认创建一个streamhandler,如果设置了filename,就创建一个filehandler,如果设置了format参数,就会用它生成一个formatter对象,并把这个formatter加入到刚刚创建的handler上,然后把这些handler加入到root.handlers列表上,level是设置给root.logger的

如果root.handlers 列表不能为空,loggingbasicConfig的调用什么都不做。

import logging

logging.basicConfig(format=‘%(name)s %(asctime)s %(message)s ‘,level=logging.INFO)

root = logging.getLogger()
root.setLevel(logging.ERROR)
print(‘root‘,root.handlers)
h0 = logging.StreamHandler()
h0.setLevel(logging.WARNING)
root.addHandler(h0)
print(‘root‘,root.handlers)
for h in root.handlers:
    print(‘root handler = {},formatter={}‘.format(h,h.formatter))

log1 = logging.getLogger(‘s‘)
log1.setLevel(logging.ERROR)
h1 = logging.FileHandler(‘h1.log‘)
h1.setLevel(logging.WARNING)
log1.addHandler(h1)
print(‘log1‘,log1.handlers)

log2 = logging.getLogger(‘s.s1‘)
log2.setLevel(logging.CRITICAL)
h2 = logging.FileHandler(‘h2.log‘)
h2.setLevel(logging.WARNING)
log2.addHandler(h2)
print(‘log2‘,log2.handlers)

log3 = logging.getLogger(‘s.s1.s2‘)
log3.setLevel(logging.INFO)
print(log3.getEffectiveLevel())
log3.warning(log3)
print(‘log3‘,log3.handlers)

root [<logging.StreamHandler object at 0x00000088203E9748>]

root [<logging.StreamHandler object at 0x00000088203E9748>, <logging.StreamHandler object at 0x00000088203FE5F8>]

root handler = <logging.StreamHandler object at 0x00000088203E9748>,formatter=<logging.Formatter object at 0x00000088203E9780>

root handler = <logging.StreamHandler object at 0x00000088203FE5F8>,formatter=None

log1 [<logging.FileHandler object at 0x0000008820E2DDA0>]

log2 [<logging.FileHandler object at 0x0000008820E2DF28>]

20

log3 []

s.s1.s2 2018-06-13 17:17:43,695 <logging.Logger object at 0x0000008820E2DF60>

<logging.Logger object at 0x0000008820E2DF60>

8、Formatter

Logging的formatter类,允许指定某个格式的字符串,如果提供None,name%(message)s将会作为默认值。

import logging

logging.basicConfig(format=‘%(name)s %(asctime)s %(message)s ‘,level=logging.INFO)

root = logging.getLogger()
root.setLevel(logging.ERROR)
print(‘root‘,root.handlers)
h0 = logging.StreamHandler()
h0.setLevel(logging.WARNING)
root.addHandler(h0)
print(‘root‘,root.handlers)
for h in root.handlers:
    print(‘root handler = {},formatter={}‘.format(h,h.formatter))

log1 = logging.getLogger(‘s‘)
log1.setLevel(logging.ERROR)
h1 = logging.FileHandler(‘h1.log‘)
h1.setLevel(logging.WARNING)
log1.addHandler(h1)
print(‘log1‘,log1.handlers)

log2 = logging.getLogger(‘s.s1‘)
log2.setLevel(logging.CRITICAL)
h2 = logging.FileHandler(‘h2.log‘)
h2.setLevel(logging.WARNING)
log2.addHandler(h2)
print(‘log2‘,log2.handlers)
f2 = logging.Formatter(‘log2 %(name)s %(asctime)s %(message)s‘)
h2.setFormatter(f2)
print(‘log2 formatter‘,h2.formatter)
log2.addHandler(h2)
print(‘log2‘,log2.handlers)

log3 = logging.getLogger(‘s.s1.s2‘)
log3.setLevel(logging.INFO)
print(log3.getEffectiveLevel())
log3.warning(log3)
print(‘log3‘,log3.handlers)

s.s1.s2 2018-06-13 17:24:13,392 <logging.Logger object at 0x00000033721EF208>

root [<logging.StreamHandler object at 0x0000003372019780>]

<logging.Logger object at 0x00000033721EF208>

root [<logging.StreamHandler object at 0x0000003372019780>, <logging.StreamHandler object at 0x0000003372130710>]

root handler = <logging.StreamHandler object at 0x0000003372019780>,formatter=<logging.Formatter object at 0x00000033720197B8>

root handler = <logging.StreamHandler object at 0x0000003372130710>,formatter=None

log1 [<logging.FileHandler object at 0x00000033721DDEB8>]

log2 [<logging.FileHandler object at 0x00000033721EF080>]

log2 formatter <logging.Formatter object at 0x00000033721EF1D0>

log2 [<logging.FileHandler object at 0x00000033721EF080>]

20

log3 []

9、filter是过滤

可以为handler增加过滤器,所哟这种过滤器只是影响某一个handler,不会影响整个处理流程,但是,如果过滤器增加到logger上,就会影响整个流程。

import logging

FORMAT = ‘%(asctime)-15s\tThread info:%(thread)d %(threadName)s %(message)s‘
logging.basicConfig(format=FORMAT,level=logging.DEBUG)

log1 = logging.getLogger(‘s‘)
log1.setLevel(logging.WARNING)

h1 = logging.StreamHandler()
h1.setLevel(logging.INFO)
fmt1 = logging.Formatter(‘log1-h1 %(message)s‘)
h1.setFormatter(fmt1)
log1.addHandler(h1)

log2 = logging.getLogger(‘s.s1‘)
print(log2.getEffectiveLevel())

h2 = logging.StreamHandler()
h2.setLevel(logging.INFO)

fmt2 = logging.Formatter(‘log2-h2 %(message)s‘)
h2.setFormatter(fmt2)

f2 = logging.Filter(‘s‘)
h2.addFilter(f2)

log2.addFilter(h2)

log2.warning(‘log2 waring ‘)

30

log1-h1 log2 waring

2018-06-13 17:36:59,798         Thread info:8360 MainThread log2 waring

消息log2的,他的名字是s.s1,所以过滤器的名字设置为s或者s.s1,消息就可以通过,但是如果使其他的就不能通过,不设置过滤器的名字,所以消息通过。

总结:过滤器的核心就一句,在logging.filter类的filter方法中

Record.namem.find(self.name,0,self.nlen) != 0

本质上是等价于record.name.startswith(filter.name)

原文地址:https://www.cnblogs.com/wangchunli-blogs/p/9949900.html

时间: 2024-10-04 22:01:44

Python中logging模块的相关文章

Python中logging模块的基本用法

在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 怎样进行日志记录相关配置 日志记录使用常见误区 下面我们来梳理一下整个演讲的过程,其实其核心就是介绍了 logging 模块的使用方法和一些配置. 日志记录的重要性 在开发过程中,如果程序运行出现了问题,我们是可以使用我们自己的 Debug 工具来检测到到底是哪一步出现了问题,如果出现了问题的话,

python中logging模块的使用

一.基本用法 只需要基本的配置,就可以使用了. import logging def fun2(): logging.basicConfig(filename="fun2.log",format="%(asctime)s %(message)s",level=logging.DEBUG) logging.debug("this is fun2 log") 二.进行详细配置 首先添加一个fileHandler来配置记录的文件,Formatter来设

python中logging模块的一些简单用法

用Python写代码的时候,在想看的地方写个print xx 就能在控制台上显示打印信息,这样子就能知道它是什么了,但是当我需要看大量的地方或者在一个文件中查看的时候,这时候print就不大方便了,所以Python引入了logging模块来记录我想要的信息.print也可以输入日志,logging相对print来说更好控制输出在哪个地方,怎么输出及控制消息级别来过滤掉那些不需要的信息. 1.日志级别 import logging # 引入logging模块 # 将信息打印到控制台上 loggin

python的logging模块

1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('This is info message') logging.warning('This is warning message') 屏幕上打印: WARNING:root:Thisis warning message 默认情况下,logging将日志打印到屏幕,日志级别为WARNING: 日志级别大小关系为:CRITICAL > ER

python之logging模块的使用

python的logging模块是用来写日志的,是python的标准模块. logging的结构 查看logging的python源码,可知主要有四个类实现功能: Loggers:提供应用程序直接使用的接口,如相关的配置设置: Handlers:将Loggers产生的日志传到指定位置,设置日志保存的位置: Filters:对输出日志进行过滤操作: Formatters:控制日志的输出格式: 日志记录的级别 DEBUG:优先级10,记录调试的详细信息,只在调试时开启: INFO:优先级20,记录普

python中常用模块详解二

log模块的讲解 1 Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适: 2 3 logger提供了应用程序可以直接使用的接口API: 4 handler将(logger创建的)日志记录发送到合适的目的输出: 5 formatter决定日志记录的最终输出格式 6 filter提供了细度设备来决定输出哪条日志记录: 7 8 logger 9 每个程序在输出信息之前都要获得一个Logger.Logger通常对应了程序的模块名, 10 比如聊天工具的图形界面模块

Python基础-----logging模块

#!/usr/bin/env python#-*- coding:utf-8 -*- ########################################################################################################################################################灵活配置日志级别,日志格式,输出位置#####################################

python使用logging模块方法 教程

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息:print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据:logging则可以由开发者决定将信息输出到什么地方,以及怎么输出: logging模块的日志级别 logging模块默认定义了以下几个日志等级,它允许开发人员自定义其他日

Python中标准模块importlib详解

Python中标准模块importlib详解 模块简介 Python提供了importlib包作为标准库的一部分.目的就是提供Python中import语句的实现(以及__import__函数).另外,importlib允许程序员创建他们自定义的对象,可用于引入过程(也称为importer). 什么是imp? 另外有一个叫做imp的模块,它提供给Python import语句机制的接口.这个模块在Python 3.4中被否决,目的就是为了只使用importlib. 这个模块有些复杂,因此我们在这