Python logging模块

1.日志级别

为了实现在不同的环境记录不同详细程度的日志,这就需要用到日志等级了。

2.输出到控制台

logging模块是Python的一个标准库模块,logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。

(1)在error_test1.py中写入代码

import logging  
logging.debug('this is a debug message')  
logging.info('this is a info message')  
logging.warning('this is a warning message')  
logging.error('this is a error message')  
logging.critical('this is a critical message') 

(2)控制台输出

可以看到,在默认情况下python的logging模块会将日志打印在控制台,且只显示大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING。

3.使用logging.basicConfig配置日志

logging.basicConfig()用于为logging日志系统做一些基本配置。

格式:logging.basicConfig(配置参数)

(1)常用参数

参数

名称

描述

level

指定日志级别。

format

指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。

datefmt

指定日期、时间格式,默认:datefmt="%Y-%m-%d %H:%M:%S"。

filename

指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了。

filemode

指定日志文件打开模式,默认为'a'。该选项在filename指定时才有效。

stream

指定日志输出目标stream,如sys.stdout、sys.stderr。需要注意stream和filename不能同时出现,否则会引发ValueError异常。

style

指定format格式字符串的风格,可取值为'%'、'{'和'$',默认为'%'

(2)format格式化字符串的字段

字段名称

使用格式

描述

asctime

%(asctime)s

日志事件发生的时间,默认如:2018-05-04 21:48:05,956。

created

%(created)f

日志事件发生的时间--时间戳,就是当时调用time.time()函数返回的值。

msecs

%(msecs)d

日志事件发生事件的毫秒部分

levelname

%(levelname)s

该日志记录的文字形式的日志级('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')。

levelno

%(levelno)s

该日志记录的数字形式的日志级别。

name

%(name)s

所使用的日志器名称,默认是'root',因为默认使用的是rootLogger。

message

%(message)s

日志记录的文本内容。

pathname

%(pathname)s

调用日志记录函数的源码文件的全路径。

filename

%(filename)s

pathname的文件名部分,包含文件后缀。

module

%(module)s

filename的名称部分,不包含后缀。

lineno

%(lineno)d

调用日志记录函数的源代码所在的行号。

funcName

%(funcName)s

调用日志记录函数的函数名。

process

%(process)d

进程ID。

processName

%(processName)s

进程名称。

thread

%(thread)d

线程ID。

threadName

%(thread)s

线程名称。

4.输出到文件

(1)在error_test1.py中写入代码

import logging  
logging.basicConfig(level=logging.DEBUG,  
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s:%(message)s',  
                    filename='D:/st07/error/tmp/test.log',  
                    filemode='w')  
#日志
logging.debug('this is a debug message')  
logging.info('this is a info message')  
logging.warning('this is a warning message')  
logging.error('this is a error message')  
logging.critical('this is a critical message')  
#测试代码
try:
    print("start")
    n=int(input("Please enter a number:"))
    share=12/n
    print('每一个股东的分红是:{}亿元。'.format(share))
except ValueError as e:
    logging.error(e)
except ZeroDivisionError as e:
    logging.error(e)
finally:
    print("end")

(2)控制台输出

(3)查看test.log日志文件

2018-05-04 22:34:02,591 -error_test1.py[line:7] - DEBUG:this is a debugmessage

2018-05-04 22:34:02,591 -error_test1.py[line:8] - INFO:this is a infomessage

2018-05-04 22:34:02,591 -error_test1.py[line:9] - WARNING:this is awarning message

2018-05-04 22:34:02,591 -error_test1.py[line:10] - ERROR:this is a errormessage

2018-05-04 22:34:02,591 -error_test1.py[line:11] - CRITICAL:this is a critical message

2018-05-04 22:34:06,850 -error_test1.py[line:19] - ERROR:invalid literalfor int() with base 10: '3.5'

5.logging输出日志到控制台和文件

(1)在把DEBUG等级日志输出到文件的同时,在控制台只输出ERROR等级日志

在error1.py中写入代码:

import logging

logging.basicConfig(level=logging.DEBUG,  
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s:%(message)s',  
                    filename='D:/st07/error/tmp/test.log',  
                    filemode='w')        

#在控制台输出ERROR等级日志,在logging.basicConfig中的参数配置会成为默认配置
#创建一个logger,定义输出到控制台的log等级开关为ERROR  
logger = logging.getLogger()      
con = logging.StreamHandler()
con.setLevel(logging.ERROR)  
#定义handler的输出格式  
format1 = logging.Formatter("%(asctime)s  %(filename)s[line:%(lineno)d]  %(levelname)s: %(message)s")  
con.setFormatter(format1)   
#将logger添加到handler里面  
logger.addHandler(con) 
                                       
#日志              
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')  

#测试代码
try:
    print("start")
    n=int(input("Please enter a number:"))
    share=12/n
    print('每一个股东的分红是:{}亿元。'.format(share))
except ValueError as e:
    logging.error(e)
except ZeroDivisionError as e:
    logging.error(e)
finally:
    print("end")

(2)在控制台输出:

(3)查看test.log日志文件:

2018-05-04 23:05:16,612 -error1.py[line:20] - DEBUG:debug message

2018-05-04 23:05:16,612 -error1.py[line:21] - INFO:info message

2018-05-04 23:05:16,612 -error1.py[line:22] - WARNING:warning message

2018-05-04 23:05:16,612 -error1.py[line:23] - ERROR:error message

2018-05-04 23:05:16,612 -error1.py[line:24] - CRITICAL:critical message

2018-05-04 23:05:46,735 -error1.py[line:33] - ERROR:invalid literal for int() with base 10: '2.5'

6.logging模块组件

(1)logging模块的四大组件

组件名称

对应类名

描述

日志器

Logger

提供了应用程序可一直使用的接口。

处理器

Handler

将logger创建的日志记录发送到合适的目的输出。

过滤器

Filter

提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录。

格式器

Formatter

决定日志记录的最终输出格式。

(2)Logger对象常用方法

方法

描述

Logger.setLevel()

设置日志器将会处理的日志消息的最低严重级别。

Logger.addHandler()

为该logger对象添加handler对象。

Logger.removeHandler()

为该logger对象移除handler对象。

Logger.addFilter()

为该logger对象添加filter对象。

Logger.removeFilter()

为该logger对象移除个filter对象。

怎样得到一个Logger对象呢?

通常用: logger = logging.getLogger()

logging.getLogger()方法有一个可选参数name,该参数表示将要返回的日志器的名称标识,如果不提供该参数,则其值为'root'。

name相同:只要logging.getLogger(name)中name相同,则返回的Logger实例就是同一个,最后logger的输出遵从后来设置的日志级别。

(3)Handler对象常用方法

方法

描述

Handler.setLevel()

设置handler将会处理的日志消息的最低严重级别。

Handler.setFormatter()

为handler设置一个格式器对象。

Handler.addFilter()

为handler添加一个过滤器对象。

Handler.removeFilter()

为handler删除一个过滤器对象。

一些常用的Handler子类

Handler

描述

logging.StreamHandler

将日志消息发送到Stream。

logging.FileHandler

将日志消息发送到磁盘文件,默认情况下文件大小会无限增长。

logging.handlers.RotatingFileHandler

将日志消息发送到磁盘文件,并支持日志文件按大小切割。

logging.hanlders.TimedRotatingFileHandler

将日志消息发送到磁盘文件,并支持日志文件按时间切割。

logging.handlers.HTTPHandler

将日志消息以GET或POST的方式发送给一个HTTP服务器。

logging.handlers.SMTPHandler

将日志消息发送给一个指定的email地址。

例如:

con = logging.StreamHandler()

con.setLevel(logging.ERROR)   

经常需要将日志消息发送到磁盘文件,并支持日志文件按时间切割:logging.hanlders.TimedRotatingFileHandler的构造函数定义如下:
     TimedRotatingFileHandler(filename[,when [,interval [,backupCount]]])
filename是输出日志文件名,when是一个字符串:

 “S”:Seconds

“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight

interval是指等待多少个单位when的时间后,Logger会自动重建文件(这个文件的创建取决于filename+suffix,若这个文件跟之前的文件有重名,则会自动覆盖掉以前的文件)。

backupCount是保留日志个数,默认的0不会自动删除日志。若设10,则在文件的创建过程中库会判断是否有超过10个,若超过则会从最先创建的开始删除。

(4)Formater对象

Formater对象用于配置日志信息的最终顺序、结构和内容。

例如:

#定义handler的输出格式

format1 =logging.Formatter("%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s: %(message)s")

con.setFormatter(format1)

(5)Filter对象

Filter可以被Handler和Logger用来做比level更细粒度的、更复杂的过滤功能。

7.实例

(1)需求

(a)要求将所有级别的日志都写入磁盘文件中

(b)all.log文件中记录所有的日志信息

(c)error.log文件中单独记录error及以上级别的日志信息

(d)要求all.log,每秒一个log文件,超过10个log就删除。

代码:

import logging
import logging.handlers
import time
import threading
def log_test():
    #1.创建一个logger,设置Log等级总开关
    logger = logging.getLogger('mylogger')
    logger.setLevel(logging.DEBUG)
    
    #2.设置输出到all.log的参数
    f1 = logging.handlers.TimedRotatingFileHandler('D:/st07/error/tmp1/all.log', when='S', 
    interval=1, backupCount=10)
    format1=logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s:%(message)s')
    f1.setFormatter(format1)
    f1.suffix = "%Y-%m-%d_%H-%M-%S.log" 
    
    #3.设置输出到error.log的等级开关和格式
    f2 = logging.FileHandler('D:/st07/error/tmp1/error.log')
    f2.setLevel(logging.ERROR)
    format2 = logging.Formatter("%(asctime)s  %(filename)s[line:%(lineno)d]  %(levelname)s: %(message)s") 
    f2.setFormatter(format2)
    #4.把logger添加到handler里面 
    logger.addHandler(f1)
    logger.addHandler(f2)
    
    #日志
    logger.debug('logger debug message')  
    logger.info('logger info message')  
    logger.warning('logger warning message')  
    logger.error('logger error message')  
    logger.critical('logger critical message')

    #为了测试,重复构造定时器
    global timer
    timer = threading.Timer(1, log_test)
    timer.start()
        
#测试(用定时器来实现)
timer = threading.Timer(1, log_test)
timer.start()

注意:filehanlder.suffix的格式,如果设定是天应该写成“%Y-%m-%d.log”,写成其他格式会导致不能删除旧文件。

查看生成的log文件个数:

(2)在error_test1.py写代码:

import logging  
  
# 创建logger    
logger = logging.getLogger()  
logger.setLevel(logging.DEBUG) 
 
logger1 = logging.getLogger('mylogger')  
logger1.setLevel(logging.INFO)  

logger2 = logging.getLogger('mylogger.child1')  
logger2.setLevel(logging.WARNING)  
 
f = logging.FileHandler('D:/st07/error/tmp/all.log',mode='w')   
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s:%(message)s')  
f.setFormatter(formatter)  
logger.addHandler(f)

f1 = logging.FileHandler('D:/st07/error/tmp/some.log',mode='w')    
f1.setFormatter(formatter)  
logger1.addHandler(f1)
logger2.addHandler(f1)  
# 日志    
logger.debug('logger debug message')  
logger.info('logger info message')  
logger.warning('logger warning message')  
logger.error('logger error message')  
logger.critical('logger critical message')  
  
logger1.debug('logger1 debug message')  
logger1.info('logger1 info message')  
logger1.warning('logger1 warning message')  
logger1.error('logger1 error message')  
logger1.critical('logger1 critical message') 

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

打开all.log和some.log,可以看到:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

午夜安全

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值