诚意
诚意如你,当一诚的态度对待

导航

 

 logging日志模块

一:日志级别

只有大于等于当前日志等级的操作才会被记录。

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

 

如何查找级别:

 

 

 

 

二:默认级别为warning,默认打印到终端

案例:

import logging

logging.basicConfig(filename='xxx.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S ',
                    level=10)

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

 

结果:

 

把level=10删掉:

 

 

 

 

三:为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

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

filename用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。

filemode文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。

format指定handler使用的日志显示格式。

datefmt指定日期时间格式。

level设置rootlogger(后边会讲解具体概念)的日志级别

stream用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略

 

 

#格式

%(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:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

 

%(thread)d:线程ID。可能没有

 

%(threadName)s:线程名。可能没有

 

%(process)d:进程ID。可能没有

 

%(message)s:用户输出的消息
View Code 

 

 

四:logging模块的FormatterHandlerLoggerFilter对象

 

logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。

 

基本用法:

 

import logging

import sys

 

# 获取logger实例,如果参数为空则返回root logger

logger = logging.getLogger("AppName")

 

# 指定logger输出格式

formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')

 

# 文件日志

file_handler = logging.FileHandler("test.log")

file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式

 

# 控制台日志

console_handler = logging.StreamHandler(sys.stdout)

console_handler.formatter = formatter  # 也可以直接给formatter赋值

 

# 为logger添加的日志处理器

logger.addHandler(file_handler)

logger.addHandler(console_handler)

 

# 指定日志的最低输出级别,默认为WARN级别

logger.setLevel(logging.INFO)

 

# 输出不同级别的log

logger.debug('this is debug info')

logger.info('this is information')

logger.warn('this is warning message')

logger.error('this is error message')

logger.fatal('this is fatal message, it is same as logger.critical')

logger.critical('this is critical message')

 

# 2016-10-08 21:59:19,493 INFO    : this is information

# 2016-10-08 21:59:19,493 WARNING : this is warning message

# 2016-10-08 21:59:19,493 ERROR   : this is error message

# 2016-10-08 21:59:19,493 CRITICAL: this is fatal message, it is same as logger.critical

# 2016-10-08 21:59:19,493 CRITICAL: this is critical message

 

# 移除一些日志处理器

logger.removeHandler(file_handler)
View Code 

 

 

 

#logger:产生日志的对象

 

#Filter:过滤日志的对象

 

#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端

 

#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

 

 

 1 import logging
 2 
 3  
 4 
 5 #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
 6 
 7 logger=logging.getLogger(__file__)
 8 
 9  
10 
11 #2、Filter对象:不常用,略
12 
13  
14 
15 #3、Handler对象:接收logger传来的日志,然后控制输出
16 
17 h1=logging.FileHandler('t1.log') #打印到文件
18 
19 h2=logging.FileHandler('t2.log') #打印到文件
20 
21 h3=logging.StreamHandler() #打印到终端
22 
23  
24 
25 #4、Formatter对象:日志格式
26 
27 formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
28 
29                     datefmt='%Y-%m-%d %H:%M:%S %p',)
30 
31  
32 
33 formmater2=logging.Formatter('%(asctime)s :  %(message)s',
34 
35                     datefmt='%Y-%m-%d %H:%M:%S %p',)
36 
37  
38 
39 formmater3=logging.Formatter('%(name)s %(message)s',)
40 
41  
42 
43  
44 
45 #5、为Handler对象绑定格式
46 
47 h1.setFormatter(formmater1)
48 
49 h2.setFormatter(formmater2)
50 
51 h3.setFormatter(formmater3)
52 
53  
54 
55 #6、将Handler添加给logger并设置日志级别
56 
57 logger.addHandler(h1)
58 
59 logger.addHandler(h2)
60 
61 logger.addHandler(h3)
62 
63 logger.setLevel(10)
64 
65  
66 
67 #7、测试
68 
69 logger.debug('debug')
70 
71 logger.info('info')
72 
73 logger.warning('warning')
74 
75 logger.error('error')
76 
77 logger.critical('critical')
View Code 

 

五:应用案例:

def func():
    try:
        a =a +1
    except Exception as e:
        print(e)  #local variable 'a' referenced before assignment  注意e是对象,打印对象之所以能打印出字符串是因为执行__str__
        logging.error(str(e))

func()

 

结果:

 

 

缺点:这样的日志信息我们无法具体获得报错信息。

六:应用案例升级

import logging
import traceback

logging.basicConfig(filename='xxx.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S ',
                    )

def func():
    try:
        a =a +1
    except Exception as e:    #e是对象,我们通常利用e获得封装的数据
        #获取当前错误的堆栈信息
        msg = traceback.format_exc()
        logging.error(msg)

func()

 七:坑

 

 

 1 import logging
 2 
 3  
 4 
 5 logging.basicConfig(filename='x1.log',
 6                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
 7                     datefmt='%Y-%m-%d %H:%M:%S ',
 8                     level=10
 9                     )
10 logging.basicConfig(filename='x2.log',
11                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
12                     datefmt='%Y-%m-%d %H:%M:%S ',
13                     level=10
14                     )
15 
16 logging.debug('debug')
17 logging.debug('debug')
View Code

 

这种情况,我们希望两个文件都写或者分别记录到不同日志里。但我们可以看结果。

x2.log这个文件没有形成,都放在x1.log文件里了。

 

 

造成这种情况的原因:

logging.basicConfig会在内存中配置,但是如果在来logging.basicConfig会查看内存,有的话就不做了。这样只能第一次生效。归根结底造成这种问题是日志中使用了重复的handler那么非要写到两个日志文件里怎么办呢?就形成不同的handler对象就可以,如下:

 

 1 import logging
 2 
 3 
 4 # 创建一个操作日志的对象logger(依赖FileHandler)
 5 file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
 6 file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))
 7 
 8 logger1 = logging.Logger('s1', level=logging.ERROR)
 9 logger1.addHandler(file_handler)
10 
11 
12 logger1.error('123123123')
13 
14 
15 # 在创建一个操作日志的对象logger(依赖FileHandler)
16 file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
17 file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))
18 
19 logger2 = logging.Logger('s2', level=logging.ERROR)
20 logger2.addHandler(file_handler2)
21 
22 logger2.error('666')
View Code

 

posted on 2018-08-31 23:17  诚意  阅读(529)  评论(0)    收藏  举报