python logging模块使用

学习完本篇,你将会

  • 理解什么是日志
  • 了解Logger各个模块功能
  • 掌握Logger配置文件conf的使用
  • 能独立编写一个自己的Logger日志,负责打印信息,以及收集信息,方便后续查看

log日志学习

  • 什么是日志:为了更方便的定位问题,通过文字或图表的方式给出程序在运行的状态内容,方便后续定位以及系统优化。
    1.Python中用logging模块用户记录日志
    2.C++使用log4cplus
    3.Java中使用log4j

logging简介

  • Logging分为4个模块:loggers,handlers,filters,and formatters.
    1.Loggers:提供应用程序调用的接口
    2.handlers: 把日志发送到指定的位置
    3.filters: 过滤日志信息
    4.formatters: 格式化输出日志
Formatter:
默认形式为: %Y-%m-%d %H:%M:%S. 格式为: %()s
  • Logger:
Logger.setLevel()  设置日志级别
LoaddHand()和removeHandler()增加和删除日志处理器
Logger.addFilter()和Logger.removeFilter增加和删除过滤器
Logger.debug(),Logger.info(),Logger.warning(),Logger.error(),and Logger.critical()创建不同的级别日志
GetLogger()获取日志的根示例
  • Handler:
setLevel()设置日志级别
setFormatter()设置输出格式
addFilter()and removeFilter增加和删除过滤器

Logging模块例子

  • Logger简单的例子:
#coding:utf-8
import logging
logging.debug('debug message') 
logging.info('info message') 
logging.warning('warning message') 
logging.error('error message') 
logging.critical('critical message')
打印输出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

从上输出的可以的出:
1.输出的内容只有warning、error、critical
2.从上知道日志的级别依次为CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET 。只有大于info的级别日志才在输出中显示
3.默认出输出的内容为:”级别:用户输入内容”

自定义配置

  • Logger简单的例子:
import logging
logging.basicConfig(level=logging.DEBUG,
                              format='%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s %(message)s',
                              datefmt='%a, %d %b %Y %H:%M:%S',
                              filename='test.log',
                              filemode='w')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
**打印输出:
Tue, 25 Apr 2021 17:46:33 demo3.py[line:7] DEBUG debug message
Tue, 25 Apr 2021 17:46:33 demo3.py[line:8] INFO info message
Tue, 25 Apr 2021 17:46:33 demo3.py[line:9] WARNING warning message
Tue, 25 Apr 2021 17:46:33 demo3.py[line:10] ERROR error message
Tue, 25 Apr 2021 17:46:33 demo3.py[line:11] CRITICAL critical message

从上图输出的可以的出:
1.可以通过配置basicConfig参数来配置模块输出内容以及各式
2.Leve指输出级别至少是多少的时候才能输出
3.filemode文件打开的方式
4.format 指输出各式,整体格式
5.datefmt 日期输出格式
6.stream指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为
7.sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。(该示例没体现)

自定义配置参数format介绍

  • format配置参数介绍:
    1.%(name)s : Logger的名字
    2.%(levelno)s:数字形式的日志级别
    3.%(levelname)s:文本形式的日志级别
    4.%(pathname)s: 调用日志输出函数的模块的完整路径名,可能没有
    5.%(filename)s :调用日志输出函数的模块的文件名
    6.%(module)s: 调用日志输出函数的模块名
    7.%(funcName)s: 调用日志输出函数的函数名
    8.%(lineno)d :调用日志输出函数的语句所在的代码行
    9.%(created)f :当前时间,用UNIX标准的表示时间的浮 点数表示
    10.%(relativeCreated)d :输出日志信息时的,自Logger创建以 来的毫秒数
    11.%(asctime)s :字符串形式的当前时间。默认格式是 “2021-09-06 16:49:45,896”。逗号后面的是毫秒
    12.%(thread)d :线程ID。可能没有
    13.%(threadName)s :线程名。可能没有
    14.%(process)d :进程ID。可能没有
    15.%(message)s:用户输出的消息

自定义配置参数datefmt介绍

  • datefmt配置参数介绍:
    1.%a:星期的英文简写。如 星期三为Web
    2.%A :星期的英文全写。如 星期三为Wednesday
    3.%b :月份的英文简写。如4月份为Apr
    4.%B:月份的英文全写。如4月份为April 
    5.%c:日期时间的字符串表示。(如: 04/07/10 10:43:39)
    6.%d:  日在这个月中的天数(是这个月的第几天)
    7.%f:  微秒(范围[0,999999])
    8.%H:  小时(24小时制,[0, 23])
    9.%I:  小时(12小时制,[0, 11])
    10.%j:  日在年中的天数 [001,366](是当年的第几天)
    11.%m:  月份([01,12])
    12.%M:  分钟([00,59])
    13.%p:  AM或者PM
    14.%S:  秒(范围为[00,61],为什么不是[00, 59],参考python手册_
    15.%U:  周在当年的周数当年的第几周),星期天作为周的第一天
    16.%w:  今天在这周的天数,范围为[0, 6],6表示星期天
    17.%W:  周在当年的周数(是当年的第几周),星期一作为周的第一天
    18.%x:  日期字符串(如:04/07/10)
    19.%X:  时间字符串(如:10:43:39)
    20.%y:  2个数字表示的年份
    21.%Y:  4个数字表示的年份
    22.%z:  与utc时间的间隔 (如果是本地时间,返回空字符串)
    23.%Z:  时区名称(如果是本地时间,返回空字符串)
    24.%%:  %% => %

Logger模块

python logging模块使用_日志输出

  • Logger介绍:
    1.Logger是一个树形结构,输出信息之前都要获得一个logger,如果没有显示的获取则自动创建并使用root logger,如第一个例子所示。 logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。
    当然也可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
    Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。
    2.logger1.setLevel(logging.DEBUG)将logger1的日志级别设置为了DEBUG,为何显示的时候没有显示出DEBUG级别的日志信息,而是从INFO级别的日志开始显示呢?原来logger1和logger2对应的是同一个Logger实例,只要logging.getLogger(name)中名称参数name相同则返回的Logger实例就是同一个,且仅有一个,也即name与Logger实例一一对应。在logger2实例中通过logger2.setLevel(logging.INFO)设置mylogger的日志级别为logging.INFO,所以最后logger1的输出遵从了后来设置的日志级别。
    3.logger1、logger2对应的每个输出分别显示两次,logger3对应的输出显示3次,logger4对应的输出显示4次......通过logger = logging.getLogger()显示的创建了root Logger,而logger1 = logging.getLogger('mylogger')创建了root Logger的孩子(root.)mylogger,logger2同样。

Handler模块

简单例子*

fh = logging.FileHandler('test.log')
ch = logging.StreamHandler()
  • Handler介绍:
1.Handler作用:
Handler对象负责发送相关的信息到指定目的地,有几个常用的Handler方法:           Handler.setLevel(lel):指定日志级别,低于lel级别的日志将被忽略
Handler.setFormatter():给这个handler选择一个Formatter
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

1.通过通过addHandler()方法为Logger添加多个Handler:logger.addHandler(fh);logger.addHandler(ch)
以下是部分Handler简介:
1.logging.StreamHandler 可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息
2.logging.FileHandler 用于向一个文件输出日志信息
3.logging.handlers.RotatingFileHandler 类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出4.logging.handlers.TimedRotatingFileHandler 和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件5.logging.handlers.SocketHandler 使用TCP协议,将日志信息发送到网络。6.logging.handlers.DatagramHandler 使用UDP协议,将日志信息发送到网络。7.logging.handlers.SysLogHandler 日志输出到syslog
8.logging.handlers.NTEventLogHandler 远程输出日志到Windows NT/2000/XP的事件日志 
9.logging.handlers.SMTPHandler 远程输出日志到邮件地址logging.handlers.MemoryHandler 日志输出到内存中的制定buffer
10.logging.handlers.HTTPHandler 通过"GET"或"POST"远程输出到HTTP服务器

Formatter模块

  • Formatter:对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。

Filter模块

  • 限制只有满足过滤规则的日志才会输出。
    比如我们定义了filter = logging.Filter('a.b.c'),并将这个Filter添加到了一个Handler上,则使用该Handler的Logger中只有名字带a.b.c前缀的Logger才能输出其日志。

取消下列两行程序的注释

#filter = logging.Filter('mylogger.child1.child2') 
#fh.addFilter(filter)

Logging文件配置信息

  • Logger除了在程序中配置外,还可以通过logger.conf文件方式配置设置 Logger,Handler,Filter,Formatter等信息写入到配置文件,通过加载配置文件实,配置文件具体的实现方式如下:
    logger.conf配置文件
[loggers] 		
keys=root,simpleExample 

[handlers] 
keys=consoleHandler 

[formatters] 
keys=simpleFormatter
 
[logger_root]
 level=DEBUG 
handlers=consoleHandler 

[logger_simpleExample]
 level=DEBUG 
handlers=consoleHandler 
qualname=simpleExample 
propagate=0 

[handler_consoleHandler] 
class=StreamHandler
 level=DEBUG 
formatter=simpleFormatter
 args=(sys.stdout,) 

[formatter_simpleFormatter] 
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

py文件

import logging 				
import logging.config

 logging.config.fileConfig("logging.conf") # 采用配置文件
 
# create logger 
logger = logging.getLogger("simpleExample") 

# "application" code 
logger.debug("debug message") 
logger.info("info message") 
logger.warn("warn message") 
logger.error("error message") 
logger.critical("critical message")

总结

通过本篇,了解了log日志的格式,python如何读取log日志,同时通过不同的方式读取日志

脚本参考

#coding:utf-8
import logging

class loger(object):
    logger = ''
    def __init__(self,
                 user='root',
                 filename='',
                 fileLevel = logging.DEBUG,
                 fileformatter = '%(asctime)s - %(name)s - %(levelname)s:%(message)s',
                 timeformatter='%Y-%m-%d %H:%M:%S'
                 ):
        # 输出文件句柄
        fh = ''
        #输出窗口句柄
        ch = ''
        #设置文件的格式
        formatter = logging.Formatter(fileformatter)
        formatter.datefmt = timeformatter
        # 配置用户
        if user=='root':
            self.logger= logging.getLogger()
        else:
            self.logger = logging.getLogger(user)

        #设置文件输出级别
        self.logger.setLevel(fileLevel) #可以控制控制台以及文件日志日志的级别,

        #配置输出窗口
        ch = logging.StreamHandler()
        ch.setFormatter(formatter)
        #配置控制台输出日志的级别,方便实时观看
        ch.setLevel(logging.INFO)
        self.logger.addHandler(ch)

        #配置输出
        if filename is not '':
            fh=logging.FileHandler(filename)
            fh.setFormatter(formatter)
            self.logger.addHandler(fh)
        self.logger.warning('=========================================')

    def printf_log(self,msg,level='DEBUG',*args,**kwargs):
        print msg
        if level == 'CRITICAL':
            self.logger.critical(msg=msg,*args,**kwargs)
        elif level == 'ERROR':
            self.logger.error(msg=msg,*args,**kwargs)
        elif level == 'WARNING':
            self.logger.warning(msg=msg,*args,**kwargs)
        elif level == 'INFO':
            self.logger.info(msg=msg,*args,**kwargs)
        elif level == 'DEBUG':
            self.logger.debug(msg=msg,*args,**kwargs)
        else:
            self.logger.error(u'请出入正确的级别')

if __name__ == "__main__":
    # loger1 = loger(filename='tttt.log',user='user1')
    # loger1.printf_log('test', level='WARNING')
    loger2=loger(filename='test.log',fileLevel=logging.DEBUG)
    loger2.printf_log(level='ERROR',msg=u'打印%d%s' %(1,'text'))
    loger2.printf_log(level='ERROR', msg=u'打印')
    loger2.printf_log(level='DEBUG', msg=u'打印')
    loger2.printf_log(level='INFO', msg=u'test')
    loger2.printf_log(level='INFO', msg=u'test')
2021-09-10 18:13:21,490 - root - WARNING - logger warning message
2021-09-10 18:13:21,490 - root - ERROR - logger error message
2021-09-10 18:13:21,490 - root - CRITICAL - logger critical message

测试