zoukankan      html  css  js  c++  java
  • python日志模块 logging

    模块级函数

    logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
    logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
    logging.basicConfig():用默认Formatter为日志系统建立一个StreamHandler,设置基础配置并加到root logger中

    Logger

    logging.getLogger([name])
    返回一个logger实例,如果没有指定name,返回root logger。
    每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
    LOG=logging.getLogger(”chat.gui”)
    而核心模块可以这样:
    LOG=logging.getLogger(”chat.kernel”)
     
    Logger.setLevel(logging.WARNING):指定最低的日志级别,低于WARNING的级别将被忽略
    Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
    Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
     
     

    Handlers

    handler对象负责发送相关的信息到指定目的地。可以是文件、屏幕、网络、socket等
    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个输出格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
     

    日志打印到屏幕

    import logging
    
    logging.debug('This is debug message')
    logging.info('This is info message')
    logging.warning('This is warning message')
    
     
    
    返回:
    WARNING:root:This is warning message
    打印到屏幕

    默认情况下,logging将日志打印到屏幕,日志级别为WARNING;
    日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。
     

    格式化日志输出

    logging.basicConfig函数各参数:
    filename: 指定日志文件名
    filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
    format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

    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='myapp.log',
                    filemode='w')
        
    logging.debug('This is debug message')
    logging.info('This is info message')
    logging.warning('This is warning message')
    
     
    
    ./myapp.log文件中内容为:
    Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
    Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
    Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message
    修改输出格式

    日志格式变量

     %(levelno)s: 打印日志级别的数值
     %(levelname)s: 打印日志级别名称
     %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
     %(filename)s: 打印当前执行程序名
     %(funcName)s: 打印日志的当前函数
     %(lineno)d: 打印日志的当前行号
     %(asctime)s: 打印日志的时间
     %(thread)d: 打印线程ID
     %(threadName)s: 打印线程名称
     %(process)d: 打印进程ID
     %(message)s: 打印日志信息
    datefmt: 指定时间格式,同time.strftime()
    level: 设置日志级别,默认为logging.WARNING
    stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
    日志格式

    logging方法

    logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件
    logging.FileHandler: 日志输出到文件
    
    日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler
    logging.handlers.BaseRotatingHandler
    logging.handlers.RotatingFileHandler
    logging.handlers.TimedRotatingFileHandler
    
    logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets
    logging.handlers.DatagramHandler:  远程输出日志到UDP sockets
    logging.handlers.SMTPHandler:  远程输出日志到邮件地址
    logging.handlers.SysLogHandler: 日志输出到syslog
    logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志
    logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer
    logging.handlers.HTTPHandler: 通过"GET""POST"远程输出到HTTP服务器
    logging方法
    由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中
     
     

    在程序中定义日志模块

    import logging
    # create logger
    def logger(log_type):
    logger = logging.getLogger(log_type) # 创建Logger对象,类型是'TEST-LOG'
    logger.setLevel(logging.WARNING) # 设置最低的日志级别,此级别覆盖ch and fh的级别
    # 创建输出到控制台处理程序,并设置级别为DEBUG
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG) # 控制输出到屏幕的级别
    # 创建输出到文件的处理程序,并设置级别
    fh = logging.FileHandler("access.log")
    fh.setLevel(logging.WARNING)
    # 创建日志格式
    formatter_Stream = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
    formatter_File = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    # add formatter to ch and fh
    ch.setFormatter(formatter_Stream)
    fh.setFormatter(formatter_File)
    # add ch and fh to logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    return logger
    eee = logger('EEE')
    rrr = logger('RRR')
    rrr.debug('debug message')
    rrr.info('info message')
    rrr.warning('warn message')
    eee.error('error message')
    eee.critical('critical message')
    代码
     
    屏幕显示内容
    RRR - DEBUG - debug message
    RRR - INFO - info message
    RRR - WARNING - warn message
    EEE - ERROR - error message
    EEE - CRITICAL - critical message
    屏幕显示内容
     
     
    文件中内容
    2017-02-21 21:35:05,700 - RRR - WARNING - warn message
    2017-02-21 21:35:05,700 - EEE - ERROR - error message
    2017-02-21 21:35:05,700 - EEE - CRITICAL - critical message
    文件中内容
     
     

    过滤器

    • 调用logging.getLogger()时参数的格式类似于“A.B.C”。采取这样的格式就是为了配置过滤器。添加过滤器后日志会经过过滤器处理后才输出
    • 过滤器"AAA.BBB"只让名字以"AAA.BBB"开头的logger输出信息
    • 可以添加多个过滤器,只要有一个过滤器拒绝,日志就不会输出
    import logging
    def logger(log_type):
    logger = logging.getLogger(log_type) # 创建Logger对象,类型是'TEST-LOG'
    logger.setLevel(logging.DEBUG) # 此级别覆盖ch and fh的级别
    # 创建输出到控制台处理程序,并设置级别为DEBUG
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG) # 控制输出到屏幕的级别
     
    # 设置过滤器
    filter = logging.Filter('AAA.BBB.CCC')
    ch.addFilter(filter)
    formatter_Stream = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter_Stream)
    logger.addHandler(ch) # ch加入logger
    return logger
    eee = logger('AAA.BBB.CCC')
    rrr = logger('AAA.BBB.DDD')
    rrr.error('debug message')
    rrr.error('info message')
    eee.error('critical message')
    eee.error('critical message')
    代码
     
     

    切割日志

    按大小切割
    import logging
    from logging import handlers
    # create logger
    def logger(log_type):
    logger = logging.getLogger(log_type)
    logger.setLevel(logging.DEBUG)
    fh = logging.FileHandler("access.log")
    fh.setLevel(logging.WARNING)
    # 最多备份5个日志文件,每个日志文件最大10M
    fh = handlers.RotatingFileHandler(filename='access.log', maxBytes=10*1024*1024,backupCount=5)
    formatter_File = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter_File)
    logger.addHandler(fh)
    return logger
    rrr = logger('AAA.BBB.DDD')
    rrr.error('debug message')
    rrr.error('info message')
    代码
    maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
    backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
     
     
    按时间切割
    import logging
    from logging import handlers
    # create logger
    def logger(log_type):
    logger = logging.getLogger(log_type)
    logger.setLevel(logging.DEBUG)
    fh = logging.FileHandler("access.log")
    fh.setLevel(logging.WARNING)
    # 按时间切割日志文件
    fh = handlers.TimedRotatingFileHandler(filename='access.log', when='s', interval=10 )
    formatter_File = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter_File)
    logger.addHandler(fh)
    return logger
    rrr = logger('AAA.BBB.DDD')
    rrr.error('debug message')
    rrr.error('info message')
    rrr.error('warn message')
    代码
    interval:时间间隔
    when: 时间单位 S 秒 M 分 H 小时 D 天 W 每星期(interval==0时代表星期一) midnight 每天凌晨
     
     

    关于root logger以及logger的父子关系


    前面多次提到root logger, 实际上logger实例之间还有父子关系, root logger就是处于最顶层的logger, 它是所有logger的祖先。如下图:root logger是默认的logger如果不创建logger实例, 直接调用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()这些函数,那么使用的logger就是 root logger, 它可以自动创建,也是单实例的。

    如何得到root logger通过logging.getLogger()或者logging.getLogger("")得到root logger实例。
    默认的levelroot logger默认的level是logging.WARNING
    如何表示父子关系logger的name的命名方式可以表示logger之间的父子关系. 比如:parent_logger = logging.getLogger('foo')child_logger = logging.getLogger('foo.bar')
    什么是effective levellogger有一个概念,叫effective level。 如果一个logger没有显示地设置level,那么它就用父亲的level。如果父亲也没有显示地设置level, 就用父亲的父亲的level,以此推....最后到达root logger,一定设置过level。默认为logging.WARNINGchild loggers得到消息后,既把消息分发给它的handler处理,也会传递给所有祖先logger处理
     
    本文参考地址:http://kenby.iteye.com/blog/1162698
     
     
  • 相关阅读:
    IDEA常用快捷指令整理
    Python dict 字典
    内联函数
    【MFC】编辑框 CEdit Ctrl控件自动换行设置
    mysql 多sql文件恢复方案
    Linux: 用64位的系统,能编译32位的程序吗?
    C++ 遍历数组
    工业现场传感器传感器为什么采用电流形式输出?
    【转】电磁阀、电磁铁的工作原理说明
    PCB板强弱电隔离距离不够导致损坏和问题检查记录
  • 原文地址:https://www.cnblogs.com/hanqian/p/6426942.html
Copyright © 2011-2022 走看看