精华内容
参与话题
问答
  • Python中的logging模块就这么用

    万次阅读 多人点赞 2014-09-05 14:38:37
    logfile = 'log.txt' ...logger = logging.getLogger() hdlr = logging.FileHandler(logfile) formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') hdlr.setFormatter(formatter)

    1、日志级别

    日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL。

    DEBUG:详细的信息,通常只出现在诊断问题上
    INFO:确认一切按预期运行
    WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
    ERROR:更严重的问题,软件没能执行一些功能
    CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行

    这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在WARNING或之上时才被跟踪。


    2、日志输出

    有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件。


    2.1、将日志输出到控制台

    比如,编写一个叫做log.py的文件,如下:

    # coding=utf-8
    __author__ = 'liu.chunming'
    import logging
    
    logging.basicConfig(level=logging.WARNING,
                        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
    # use logging
    logging.info('this is a loggging info message')
    logging.debug('this is a loggging debug message')
    logging.warning('this is loggging a warning message')
    logging.error('this is an loggging error message')
    logging.critical('this is a loggging critical message')
    执行上面的代码将在Console中输出下面信息:

    C:\Python27\python.exe C:/Users/liu.chunming/PycharmProjects/Myproject/log.py
    2015-05-21 17:25:22,572 - log.py[line:10] - WARNING: this is loggging a warning message
    2015-05-21 17:25:22,572 - log.py[line:11] - ERROR: this is an loggging error message
    2015-05-21 17:25:22,572 - log.py[line:12] - CRITICAL: this is a loggging critical message

    【解析】

    通过logging.basicConfig函数对日志的输出格式及方式做相关配置,上面代码设置日志的输出等级是WARNING级别,意思是WARNING级别以上的日志才会输出。另外还制定了日志输出的格式。


    2.2、将日志输出到文件

    我们还可以将日志输出到文件,只需要在logging.basicConfig函数中设置好输出文件的文件名和写文件的模式。

    # coding=utf-8
    __author__ = 'liu.chunming'
    import logging
    
    logging.basicConfig(level=logging.WARNING,
                        filename='./log/log.txt',
                        filemode='w',
                        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
    # use logging
    logging.info('this is a loggging info message')
    logging.debug('this is a loggging debug message')
    logging.warning('this is loggging a warning message')
    logging.error('this is an loggging error message')
    logging.critical('this is a loggging critical message')
    运行之后,打开该文件./log/log.txt,效果如下:

    2015-05-21 17:30:20,282 - log.py[line:12] - WARNING: this is loggging a warning message
    2015-05-21 17:30:20,282 - log.py[line:13] - ERROR: this is an loggging error message
    2015-05-21 17:30:20,282 - log.py[line:14] - CRITICAL: this is a loggging critical message


    2.3、既要把日志输出到控制台, 还要写入日志文件

    这就需要一个叫作Logger 的对象来帮忙,下面将对他进行详细介绍,现在这里先学习怎么实现把日志既要输出到控制台又要输出到文件的功能。

    # coding=utf-8
    __author__ = 'liu.chunming'
    import logging
    
    # 第一步,创建一个logger
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)    # Log等级总开关
    
    # 第二步,创建一个handler,用于写入日志文件
    logfile = './log/logger.txt'
    fh = logging.FileHandler(logfile, mode='w')
    fh.setLevel(logging.DEBUG)   # 输出到file的log等级的开关
    
    # 第三步,再创建一个handler,用于输出到控制台
    ch = logging.StreamHandler()
    ch.setLevel(logging.WARNING)   # 输出到console的log等级的开关
    
    # 第四步,定义handler的输出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    
    # 第五步,将logger添加到handler里面
    logger.addHandler(fh)
    logger.addHandler(ch)
    
    # 日志
    logger.debug('this is a logger debug message')
    logger.info('this is a logger info message')
    logger.warning('this is a logger warning message')
    logger.error('this is a logger error message')
    logger.critical('this is a logger critical message')
    
    执行这段代码之后,在console中,可以看到:

    C:\Python27\python.exe C:/Users/liu.chunming/PycharmProjects/Myproject/log.py
    2015-05-21 17:47:50,292 - log.py[line:30] - WARNING: this is a logger warning message
    2015-05-21 17:47:50,292 - log.py[line:31] - ERROR: this is a logger error message
    2015-05-21 17:47:50,293 - log.py[line:32] - CRITICAL: this is a logger critical message
    在logger.txt中,可以看到:

    2015-05-21 17:47:50,292 - log.py[line:29] - INFO: this is a logger info message
    2015-05-21 17:47:50,292 - log.py[line:30] - WARNING: this is a logger warning message
    2015-05-21 17:47:50,292 - log.py[line:31] - ERROR: this is a logger error message
    2015-05-21 17:47:50,293 - log.py[line:32] - CRITICAL: this is a logger critical message

    
    

    【解析】

    可以发现,实现这个功能一共分5步:

    第一步,创建一个logger;第二步,创建一个handler,用于写入日志文件;第三步,再创建一个handler,用于输出到控制台;第四步,定义handler的输出格式;第五步,将logger添加到handler里面。这段代码里面提到了好多概念,包括:Logger,Handler,Formatter。后面讲对这些概念进行讲解。

    3、多个模块中日志输出顺序

    通常我们的工作中会有多个模块都需要输出日志。那么,具有调用关系的模块之间,它门的日志输出顺序是怎么样的?我们来演示下:假设有两个文件,分别是util.py:
    # util.py
    __author__ = 'liu.chunming'
    import logging
    
    def fun():
        logging.info('this is a log in util module')
    和main.py
    # main.py
    # coding=utf-8
    __author__ = 'liu.chunming'
    import logging
    import util
    
    logging.basicConfig(level=logging.INFO,
                        filename='./log/log.txt',
                        filemode='w',
                        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
    def main():
        logging.info('main module start')
        util.fun()
        logging.info('main module stop')
    
    if __name__ == '__main__':
        main()
    运行后打开log.txt,结果如下:
    2015-05-21 18:10:34,684 - main.py[line:11] - INFO: main module start
    2015-05-21 18:10:34,684 - util.py[line:5] - INFO: this is a log in util module
    2015-05-21 18:10:34,684 - main.py[line:13] - INFO: main module stop
    【解析】
    可以看出,日志的输出顺序就是模块的执行顺序。

    4、日志格式说明

    logging.basicConfig函数中,可以指定日志的输出格式format,这个参数可以输出很多有用的信息,如上例所示:

    %(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: 打印日志信息

    我在工作中给的常用格式在前面已经看到了。就是:

    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'

    这个格式可以输出日志的打印时间,是哪个模块输出的,输出的日志级别是什么,以及输入的日志内容。

    5、高级进阶

    接下来学习一些日志组件以及一些高级部分。日志组件包括:loggers、handlers,filters,formatters.

    Logger 对象扮演了三重角色.首先,它暴露给应用几个方法以便应用可以在运行时写log.其次,Logger对象按照log信息的严重程度或者根据filter对 象来决定如何处理log信息(默认的过滤功能).最后,logger还负责把log信息传送给相关的loghandlers.

    Handler对象负责分配合适的log信息(基于log信息的严重 程度)到handler指定的目的地.Logger对象可以用addHandler()方法添加零个或多个handler对象到它自身.一个常见的场景 是,一个应用可能希望把所有的log信息都发送到一个log文件中去,所有的error级别以上的log信息都发送到stdout,所有critical 的log信息通过email发送.这个场景里要求三个不同handler处理,每个handler负责把特定的log信息发送到特定的地方.

    filter:细致化,选择哪些日志输出

    format:设置显示格式

    1、logging.basicConfig([**kwargs]):

    Does basic configuration for the logging system by creating a StreamHandler with a defaultFormatter and adding it to the root logger. The functionsdebug(),info(),warning(),error() andcritical() will callbasicConfig() automatically if no handlers are defined for the root logger.

    This function does nothing if the root logger already has handlers configured for it.

    为日志模块配置基本信息。kwargs 支持如下几个关键字参数:
    filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
    filemode
    :日志文件的打开模式。 默认值为'a',表示日志消息以追加的形式添加到日志文件中。如果设为'w', 那么每次程序启动的时候都会创建一个新的日志文件;
    format :设置日志输出格式;
    datefmt :定义日期格式;
    level :设置日志的级别.对低于该级别的日志消息将被忽略;
    stream :设置特定的流用于初始化StreamHandler;

    演示如下:

    复制代码
    import logging
    import os
    FILE=os.getcwd()
    
    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 = os.path.join(FILE,'log.txt'),
                        filemode='w')
    logging.info('msg')
    logging.debug('msg2')
    复制代码

    2、logging.getLogger([name])

    创建Logger对象。日志记录的工作主要由Logger对象来完成。在调用getLogger时要提供Logger的名称(注:多次使用相同名称 来调用getLogger,返回的是同一个对象的引用。),Logger实例之间有层次关系,这些关系通过Logger名称来体现,如:

    p = logging.getLogger("root")

    c1 = logging.getLogger("root.c1")

    c2 = logging.getLogger("root.c2")

    例子中,p是父logger, c1,c2分别是p的子logger。c1, c2将继承p的设置。如果省略了name参数, getLogger将返回日志对象层次关系中的根Logger。

    复制代码
    import logging
    '''命名'''
    log2=logging.getLogger('BeginMan')  #生成一个日志对象
    print log2  #<logging.Logger object at 0x00000000026D1710>
    
    '''无名'''
    log3 = logging.getLogger()
    print log3  #<logging.RootLogger object at 0x0000000002721630> 如果没有指定name,则返回RootLogger
    
    '''最好的方式'''
    log = logging.getLogger(__name__)#__name__ is the module’s name in the Python package namespace.
    print log   #<logging.Logger object at 0x0000000001CD5518>  Logger对象
    print __name__  #__main__
    复制代码

    三、Logger对象

    通过logging.getLogger(nam)来获取Logger对象,

    Class logging.Logger

    有如下属性和方法:

    1、Logger.propagate

    print log.propagate         #1

    具体参考:http://docs.python.org/2.7/library/logging.html

    2、Logger.setLevel(lvl)

    设置日志的级别。对于低于该级别的日志消息将被忽略.

    复制代码
    import logging
    import os
    logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG)
    log = logging.getLogger('root.set')   #Logger对象
    print log.propagate         #1
    log.setLevel(logging.WARN)  #日志记录级别为WARNNING  
    log.info('msg')             #不会被记录
    log.debug('msg')            #不会被记录
    log.warning('msg')
    log.error('msg')
    复制代码

    3、Logger.debug(msg [ ,*args [, **kwargs]])

    记录DEBUG级别的日志信息。参数msg是信息的格式,args与kwargs分别是格式参数。

    复制代码
    import logging
    logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
    log = logging.getLogger('root')
    log.debug('%s, %s, %s', *('error', 'debug', 'info'))
    log.debug('%(module)s, %(info)s', {'module': 'log', 'info': 'error'})
    复制代码

    4、同上

    Logger.info(msg[ , *args[ , **kwargs] ] )

    Logger.warnning(msg[ , *args[ , **kwargs] ] )

    Logger.error(msg[ , *args[ , **kwargs] ] )

    Logger.critical(msg[ , *args[ , **kwargs] ] )

    5、Logger.log(lvl, msg[ , *args[ , **kwargs]] )

    记录日志,参数lvl用户设置日志信息的级别。参数msg, *args, **kwargs的含义与Logger.debug一样。

    log.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error
    log.log(logging.ERROR,'再来一遍:%s,%s',*('log日志','error'))  #ERROR,再来一遍:log日志,error

    6、Logger.exception(msg[, *args])

    以ERROR级别记录日志消息,异常跟踪信息将被自动添加到日志消息里。Logger.exception通过用在异常处理块中,如:

    复制代码
    import logging
    import os
    logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG)
    log = logging.getLogger('root')   #Logger对象
    try:
        raise Exception,u'错误异常'
    except:
        log.exception('exception')  #异常信息被自动添加到日志消息中  
    打开文件,显示如下:
    
    '''ERROR,exception
    Traceback (most recent call last):
      File "E:\project\py\src\log3.py", line 12, in <module>
        raise Exception,u'错误异常'
    Exception: 错误异常
    '''
    复制代码

    7、Logger.addFilter(filt)

    指定过滤器

    8、Logger.removeFilter(filt)

    移除指定的过滤器

    9、Logger.filter(record)

    ....其他的后面介绍

    四、 Handler对象、Formatter对象、Filter对象、Filter对象

    这里简要介绍

    复制代码
    #coding=utf8
    '''
    Created on 2013年9月23日
    Function : Handler对象、Formatter对象、Filter对象、Filter对象
    @author : BeginMan
    '''
    import logging
    import os
    '''Logger'''
    l = logging.Logger('root')          #创建Logger对象
    log = logging.getLogger('root')     #通过logging.getLogger创建Logger对象
    print l                             #<logging.Logger object at 0x0000000001DF5B70>
    print log                           #<logging.Logger object at 0x00000000022A16D8>
    
    '''Handler'''
    handler = logging.Handler()         #创建Handler对象
    handler.__init__(logging.DEBUG)     #通过设置level来初始化Handler实例
    handler.createLock()                #初始化一个线程锁可以用来序列化访问底层I / O功能,这可能不是线程安全的。
    handler.acquire()                   #获取线程锁通过handler.createLock()
    handler.release()                   #释放线程锁通过获取handler.acquire()
    handler.setLevel(logging.DEBUG)     #设置临界值,如果Logging信息级别小于它则被忽视,当一个handler对象被创建,级别没有被设置,导致所有的信息会被处理。
    handler.setFormatter("%(levelname)s,%(message)s")              #设置格式
    # handler.addFilter(filter)         #添加指定的过滤器
    # handler.removeFilter(filter)      #移除指定的过滤器
    # handler.filter(record)            #通过设置过滤器适用于记录并返回真值如果要处理的记录
    handler.flush()                     #确保所有的日志输出已经被刷新
    handler.close()                     #收拾任何所使用资源处理程序,
    # handler.handle(record)            #有条件地发出指定的日志记录,这取决于过滤器可能被添加到处理程序。
    # handler.handlerError(record)      #处理错误
    # handler.format(record)            #格式输出
    # handler.emit(record)
    
    #Formatter:http://docs.python.org/2.7/library/logging.html#logging.Formatter
    
    '''Formatter:
    the base Formatter allows a formatter string to be specified,is none ,used default value '%(message)s'
    class logging.Formatter(fmt=None,datefmt=None)
    If no fmt is specified, '%(message)s' is used. If no datefmt is specified, the ISO8601 date format is used.
    '''
    fm = logging.Formatter('%(levelname)s:%(message)s','%m/%d/%Y %I:%M:%S %p')
    print fm        #<logging.Formatter object at 0x0000000002311828>
    #有如下方法:format()、formatTime()、formatException()
    
    #http://docs.python.org/2.7/library/logging.html#formatter-objects
    
    '''Filter'''
    '''
    class logging.Filter(name=''):
        返回Filter实例,If name is specified, it names a logger which, together with its children, 
      will have its events allowed through the filter. If name is the empty string, allows every event.
    用于Loggers、Handlers等过滤的设置
    如果一个过滤器初始化为'A.B',则允许'A.B/A.B.C/A.B.C.D/A.B.D'等,但不允许'A.BB/B.A'等通过
    如果初始化为空字符串,则没有过滤。
    它有filter()方法
    '''
    
    '''LogRecord '''
    '''class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None)
    LogRecord 实例可以被Logger自动创建.也可以通过makeLogRecord()来创建'''
    #http://docs.python.org/2.7/library/logging.html#logrecord-objects

     

    展开全文
  • Python logging模块详解

    万次阅读 多人点赞 2014-05-06 16:11:07
    import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')输出: WARNI
    简单将日志打印到屏幕:
    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

    可见,默认情况下python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默认的日志格式为日志级别: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='/tmp/test.log',
                        filemode='w')
    
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    查看输出:
    cat /tmp/test.log 
    Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
    Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message

    可见在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参数会被忽略。

    format参数中可能用到的格式化串:
    %(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用户输出的消息


    若要对logging进行更多灵活的控制有必要了解一下Logger,Handler,Formatter,Filter的概念
    上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)

    先看一个具体的例子
    #coding:utf-8
    import logging
    
    # 创建一个logger  
    logger = logging.getLogger()
    
    logger1 = logging.getLogger('mylogger')
    logger1.setLevel(logging.DEBUG)
    
    logger2 = logging.getLogger('mylogger')
    logger2.setLevel(logging.INFO)
    
    logger3 = logging.getLogger('mylogger.child1')
    logger3.setLevel(logging.WARNING)
    
    logger4 = logging.getLogger('mylogger.child1.child2')
    logger4.setLevel(logging.DEBUG)
    
    logger5 = logging.getLogger('mylogger.child1.child2.child3')
    logger5.setLevel(logging.DEBUG)
    
    # 创建一个handler,用于写入日志文件  
    fh = logging.FileHandler('/tmp/test.log')
    
    # 再创建一个handler,用于输出到控制台  
    ch = logging.StreamHandler()
    
    # 定义handler的输出格式formatter  
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    
    #定义一个filter
    #filter = logging.Filter('mylogger.child1.child2')
    #fh.addFilter(filter)  
    
    # 给logger添加handler  
    #logger.addFilter(filter)
    logger.addHandler(fh)
    logger.addHandler(ch)
    
    #logger1.addFilter(filter)
    logger1.addHandler(fh)
    logger1.addHandler(ch)
    
    logger2.addHandler(fh)
    logger2.addHandler(ch)
    
    #logger3.addFilter(filter)
    logger3.addHandler(fh)
    logger3.addHandler(ch)
    
    #logger4.addFilter(filter)
    logger4.addHandler(fh)
    logger4.addHandler(ch)
    
    logger5.addHandler(fh)
    logger5.addHandler(ch)
    
    # 记录一条日志  
    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')
    
    logger3.debug('logger3 debug message')
    logger3.info('logger3 info message')
    logger3.warning('logger3 warning message')
    logger3.error('logger3 error message')
    logger3.critical('logger3 critical message')
    
    logger4.debug('logger4 debug message')
    logger4.info('logger4 info message')
    logger4.warning('logger4 warning message')
    logger4.error('logger4 error message')
    logger4.critical('logger4 critical message')
    
    logger5.debug('logger5 debug message')
    logger5.info('logger5 info message')
    logger5.warning('logger5 warning message')
    logger5.error('logger5 error message')
    logger5.critical('logger5 critical message')
    输出:
    2014-05-06 12:54:43,222 - root - WARNING - logger warning message
    2014-05-06 12:54:43,223 - root - ERROR - logger error message
    2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
    2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
    2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
    2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
    2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
    2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
    2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
    2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
    2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
    2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
    2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
    2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
    2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
    2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
    2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
    2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
    2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
    2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
    2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
    2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
    2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
    2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
    2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
    2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
    2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
    2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
    2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

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

    Logger
    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()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。

    我们看到程序中
    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')
    只输出了
    2014-05-06 12:54:43,222 - root - WARNING - logger warning message
    2014-05-06 12:54:43,223 - root - ERROR - logger error message
    2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
    从这个输出可以看出logger = logging.getLogger()返回的Logger名为root。这里没有用logger.setLevel()显示的为logger设置日志级别,所以使用默认的日志级别WARNIING,故结果只输出了大于等于WARNIING级别的信息。

    另外,我们明明通过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的输出遵从了后来设置的日志级别。
    logger1 = logging.getLogger('mylogger')
    logger1.setLevel(logging.DEBUG)
    logger2 = logging.getLogger('mylogger')
    logger2.setLevel(logging.INFO)
    为什么logger1、logger2对应的每个输出分别显示两次,logger3对应的输出显示3次,logger4对应的输出显示4次......呢?
    这是因为我们通过logger = logging.getLogger()显示的创建了root Logger,而logger1 = logging.getLogger('mylogger')创建了root Logger的孩子(root.)mylogger,logger2同样。
    logger3 = logging.getLogger('mylogger.child1')创建了(root.)mylogger.child1
    logger4 = logging.getLogger('mylogger.child1.child2')创建了(root.)mylogger.child1.child2
    logger5 = logging.getLogger('mylogger.child1.child2.child3')创建了(root.)mylogger.child1.child2.child3
    而孩子,孙子,重孙……既会将消息分发给他的handler进行处理也会传递给所有的祖先Logger处理。

    试着注释掉如下一行程序,观察程序输出
    #logger.addHandler(fh)  
    发现标准输出中每条记录对应两行(因为root Logger默认使用StreamHandler)
    2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
    2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
    2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
    2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
    2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
    2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
    2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
    2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
    ……
    而在文件输出中每条记录对应一行(因为我们注释掉了logger.addHandler(fh),没有对root Logger启用FileHandler)
    2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
    2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
    2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
    2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message

    孩子,孙子,重孙……可逐层继承来自祖先的日志级别、Handler、Filter设置,也可以通过Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。设置自己特别的日志级别、Handler、Filter。若不设置则使用继承来的值。

    Handler
    上述例子的输出在标准输出和指定的日志文件中均可以看到,这是因为我们定义并使用了两种Handler。
    fh = logging.FileHandler('/tmp/test.log') 
    ch = logging.StreamHandler()
    Handler对象负责发送相关的信息到指定目的地,有几个常用的Handler方法:
    Handler.setLevel(lel):指定日志级别,低于lel级别的日志将被忽略
    Handler.setFormatter():给这个handler选择一个Formatter
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    可以通过addHandler()方法为Logger添加多个Handler:
    logger.addHandler(fh)
    logger.addHandler(ch)


    有多中可用的Handler:

    logging.StreamHandler 可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息
    logging.FileHandler 用于向一个文件输出日志信息
    logging.handlers.RotatingFileHandler 类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出
    logging.handlers.TimedRotatingFileHandler 和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件
    logging.handlers.SocketHandler 使用TCP协议,将日志信息发送到网络。
    logging.handlers.DatagramHandler 使用UDP协议,将日志信息发送到网络。
    logging.handlers.SysLogHandler 日志输出到syslog
    logging.handlers.NTEventLogHandler 远程输出日志到Windows NT/2000/XP的事件日志 
    logging.handlers.SMTPHandler 远程输出日志到邮件地址
    logging.handlers.MemoryHandler 日志输出到内存中的制定buffer
    logging.handlers.HTTPHandler 通过"GET"或"POST"远程输出到HTTP服务器
    各个Handler的具体用法可查看参考书册:
    https://docs.python.org/2/library/logging.handlers.html#module-logging.handlers


    Formatter
    Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。
    #定义Formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    #为Handler添加Formatter
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    Formatter参数中可能用到的格式化串参见上文(logging.basicConfig()函数format参数中可能用到的格式化串:)

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

    取消下列两行程序的注释
    #filter = logging.Filter('mylogger.child1.child2')
    #fh.addFilter(filter)  
    标准输出中输出结果并没有发生变化,但日志文件输出中只显示了如下内容:
    2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

    当然也可以直接给Logger加Filter。若为Handler加Filter则所有使用了该Handler的Logger都会受到影响。而为Logger添加Filter只会影响到自身。
    注释掉
    #fh.addFilter(filter) 
    并取消如下几行的注释
    #logger.addFilter(filter)
    #logger1.addFilter(filter)
    #logger3.addFilter(filter)
    #logger4.addFilter(filter)
    
    输出结果
    2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message
    2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message
    2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message
    2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message
    2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message
    2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
    2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message
    2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
    2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message
    2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
    2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message

    发现root、mylogger、mylogger.child1的输出全部被过滤掉了。

    除了直接在程序中设置Logger,Handler,Filter,Formatter外还可以将这些信息写进配置文件中。

    例如典型的logging.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=
    

    程序可以这么写
    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")

    多模块使用logging
    logging模块保证在同一个python解释器内,多次调用logging.getLogger('log_name')都会返回同一个logger实例,即使是在多个模块的情况下。所以典型的多模块场景下使用logging的方式是在main模块中配置logging,这个配置会作用于多个的子模块,然后在其他模块中直接通过getLogger获取Logger对象即可。

    main.py:
    import logging  
    import logging.config  
      
    logging.config.fileConfig('logging.conf')  
    root_logger = logging.getLogger('root')  
    root_logger.debug('test root logger...')  
      
    logger = logging.getLogger('main')  
    logger.info('test main logger')  
    logger.info('start import module \'mod\'...')  
    import mod  
      
    logger.debug('let\'s test mod.testLogger()')  
    mod.testLogger()  
      
    root_logger.info('finish test...') 

    子模块mod.py:

    import logging  
    import submod  
      
    logger = logging.getLogger('main.mod')  
    logger.info('logger of mod say something...')  
      
    def testLogger():  
        logger.debug('this is mod.testLogger...')  
        submod.tst() 
    
    子子模块submod.py:
    import logging  
      
    logger = logging.getLogger('main.mod.submod')  
    logger.info('logger of submod say something...')  
      
    def tst():  
        logger.info('this is submod.tst()...')  


    
    
    展开全文
  • 全面介绍logging模块功能,让你轻松驾驭 1、模块级函数 logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger logging.debug()、logging.info()、logging.warning()、...

    全面介绍logging模块功能,让你轻松驾驭

    1、模块级函数


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

    2、Logger

    每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
    LOG=logging.getLogger(”chat.gui”)
    而核心模块可以这样:
    LOG=logging.getLogger(”chat.kernel”)

    Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
    Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
    Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
    Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
    设置logger的level, level有以下几个级别:

    NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
    如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出

    3、Handlers


    handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    4、Formatters

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

    %(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

    用户输出的消息


    5、设置过滤器
    细心的朋友一定会发现前文调用logging.getLogger()时参数的格式类似于“A.B.C”。采取这样的格式其实就是为了可以配置过滤器。看一下这段代码:
    LOG=logging.getLogger(”chat.gui.statistic”)
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter(’%(asctime)s %(levelname)s %(message)s’)
    console.setFormatter(formatter)
    filter=logging.Filter(”chat.gui”)
    console.addFilter(filter)
    LOG.addHandler(console)
    和前面不同的是我们在Handler上添加了一个过滤器。现在我们输出日志信息的时候就会经过过滤器的处理。名为“A.B”的过滤器只让名字带有 “A.B”前缀的Logger输出信息。可以添加多个过滤器,只要有一个过滤器拒绝,日志信息就不会被输出。另外,在Logger中也可以添加过滤器。

    每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
    1)    logging.StreamHandler
    使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
    StreamHandler([strm])
    其中strm参数是一个文件对象。默认是sys.stderr
    2)   logging.FileHandler
    和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
    FileHandler(filename[,mode])
    filename是文件名,必须指定一个文件名。
    mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。
    3)   logging.handlers.RotatingFileHandler
    这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
    RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
    其中filename和mode两个参数和FileHandler一样。
    maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
    backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
    4)   logging.handlers.TimedRotatingFileHandler
    这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
    TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
    其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
    interval是时间间隔。
    when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
    S 秒
    M 分
    H 小时
    D 天
    W 每星期(interval==0时代表星期一)
    midnight 每天凌晨
    5)   logging.handlers.SocketHandler
    6)   logging.handlers.DatagramHandler
    以上两个Handler类似,都是将日志信息发送到网络。不同的是前者使用TCP协议,后者使用UDP协议。它们的构造函数是:
    Handler(host, port)
    其中host是主机名,port是端口名
    7)  logging.handlers.SysLogHandler
    8)  logging.handlers.NTEventLogHandler
    9)  logging.handlers.SMTPHandler
    10) logging.handlers.MemoryHandler
    11) logging.handlers.HTTPHandler

    最后举个例子吧:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    # encoding:utf-8
    #import logging
     
    #FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
    #logging.basicConfig(format=FORMAT)
    #d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
    #logger = logging.getLogger('tcpserver')
    #logger.warning('Protocol problem: %s', 'connection reset', extra=d)
     
    #FORMAT = '%(asctime)-15s %(message)s'
    #logging.basicConfig(filename = "C:\\Users\\june\\Desktop\\1.txt", level = logging.DEBUG, filemode = "a", format=FORMAT) 
    #logging.debug('this is a message') 
    #logging.debug('test') 
     
    #import logging
    #import datetime
    #
    #curDate = datetime.date.today() - datetime.timedelta(days=0)
    #logName =  'C:\\Users\\june\\Desktop\\error_%s.log' %curDate
    #
    #logging.basicConfig(level=logging.INFO,
    #               format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
    #               #datefmt='%a, %d %b %Y %H:%M:%S',
    #               filename=logName,
    #               filemode='a')
    #
    ##2013-10-21 03:25:51,509 writeLog.py[line:14] INFO This is info message
    ##2013-10-21 03:25:51,510 writeLog.py[line:15] WARNING This is warning message
    #logging.debug('This is debug message')
    #logging.info('This is info message')
    #logging.warning('This is warning message')
     
     <div>
     
     
     </div>
    import logging
    import logging.config
     
    logging.config.fileConfig("logging.conf")
     
    #create logger
    loggerInfo = logging.getLogger("infoLogger")
     
    #"application" code
    loggerInfo.debug("debug message")
    loggerInfo.info("info message")
    loggerInfo.warn("warn message")
    loggerInfo.error("error message")
    loggerInfo.critical("critical message")
     
     
    loggerError = logging.getLogger("errorLogger")
    loggerError.error("Error: Hello world!")


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    # 定义logger模块,root是父类,必需存在的,其它的是自定义。
    # logging.getLogger(NAME)便相当于向logging模块注册了一种日志打印
    # name 中用 . 表示 log 的继承关系
    [loggers]
    keys=root,infoLogger,errorLogger
     
    # 定义handler
    [handlers]
    keys=infoHandler,errorHandler
     
    # 定义格式化输出
    [formatters]
    keys=infoFmt,errorFmt
     
    #--------------------------------------------------
    # 实现上面定义的logger模块,必需是[logger_xxxx]这样的形式
    #--------------------------------------------------
    # [logger_xxxx] logger_模块名称
    # level     级别,级别有DEBUG、INFO、WARNING、ERROR、CRITICAL
    # handlers  处理类,可以有多个,用逗号分开
    # qualname  logger名称,应用程序通过 logging.getLogger获取。对于不能获取的名称,则记录到root模块。
    # propagate 是否继承父类的log信息,0:否 1:是
    [logger_root]
    level=INFO
    handlers=errorHandler
     
    [logger_errorLogger]
    level=ERROR
    handlers=errorHandler
    propagate=0
    qualname=errorLogger
     
    [logger_infoLogger]
    level=INFO
    handlers=infoHandler
    propagate=0
    qualname=infoLogger
     
    #--------------------------------------------------
    # handler
    #--------------------------------------------------
    # [handler_xxxx]
    # class handler类名
    # level 日志级别
    # formatter,上面定义的formatter
    # args handler初始化函数参数
     
    [handler_infoHandler]
    class=StreamHandler
    level=INFO
    formatter=infoFmt
    args=(sys.stdout,)
     
    [handler_errorHandler]
    class=logging.handlers.TimedRotatingFileHandler
    level=ERROR
    formatter=errorFmt
    # When computing the next rollover time for the first time (when the handler is created),
    # the last modification time of an existing log file, or else the current time,
    # is used to compute when the next rotation will occur.
    # 这个功能太鸡肋了,是从handler被创建的时间算起,不能按自然时间 rotation 切分,除非程序一直运行,否则这个功能会有问题
    # 临时解决方案参考下面的链接:Python 多进程日志记录
    # http://blogread.cn/it/article/4175?f=wb2
    args=('C:\\Users\\june\\Desktop\\error.log', 'M', 1, 5)
     
    #--------------------------------------------------
    # 日志格式
    #--------------------------------------------------
    # %(asctime)s       年-月-日 时-分-秒,毫秒 2013-04-26 20:10:43,745
    # %(filename)s      文件名,不含目录
    # %(pathname)s      目录名,完整路径
    # %(funcName)s      函数名
    # %(levelname)s     级别名
    # %(lineno)d        行号
    # %(module)s        模块名
    # %(message)s       消息体
    # %(name)s          日志模块名
    # %(process)d       进程id
    # %(processName)s   进程名
    # %(thread)d        线程id
    # %(threadName)s    线程名
     
    [formatter_infoFmt]
    format=%(asctime)s %(levelname)s %(message)s
    datefmt=
    class=logging.Formatter
     
    [formatter_errorFmt]
    format=%(asctime)s %(levelname)s %(message)s
    datefmt=
    class=logging.Formatter


    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #coding=utf-8
    import logging
    import datetime
     
    format='%(asctime)s - %(filename)s - [line:%(lineno)d] - %(levelname)s - %(message)s'
    curDate = datetime.date.today() - datetime.timedelta(days=0)
    infoLogName =  r'C:/Users/june/Desktop/info_%s.log' %curDate
    errorLogName =  r'C:/Users/june/Desktop/error_%s.log' %curDate
     
    formatter = logging.Formatter(format)
     
    infoLogger = logging.getLogger("infoLog")
    errorLogger = logging.getLogger("errorLog")
     
    infoLogger.setLevel(logging.INFO)
    errorLogger.setLevel(logging.ERROR)
     
    infoHandler = logging.FileHandler(infoLogName, 'a')
    infoHandler.setLevel(logging.INFO)
    infoHandler.setFormatter(formatter)
     
    errorHandler = logging.FileHandler(errorLogName, 'a')
    errorHandler.setLevel(logging.ERROR)
    errorHandler.setFormatter(formatter)
     
    testHandler = logging.StreamHandler()
    testHandler.setFormatter(formatter)
    testHandler.setLevel(logging.ERROR)
     
    infoLogger.addHandler(infoHandler)
    infoLogger.addHandler(testHandler)
    errorLogger.addHandler(errorHandler)
     
    #infoLogger.debug("debug message")
    #infoLogger.info("info message")
    #infoLogger.warn("warn message")
    # # 下面这行会同时打印在文件和终端上
    #infoLogger.error("error message")
    #
    #errorLogger.error("error message")
    #errorLogger.critical("critical message")

    展开全文
  • logging模块

    2019-06-11 16:41:11
    日志级别 日志级别Level 数值 CRITICAL 50 ERROR 40 WARNING 30,默认级别 INFO 20 DEBUG 10 NOTSET 0 日志级别指的是产生日志的事件的严重程度 设置一个级别后,严重程度低于设置值的日志......
    日志级别
    日志级别Level 数值
    CRITICAL 50
    ERROR 40
    WARNING 30,默认级别
    INFO 20
    DEBUG 10
    NOTSET 0

    日志级别指的是产生日志的事件的严重程度
    设置一个级别后,严重程度低于设置值的日志消息将被忽略
    debug(),info(),warning(),error()和critical()方法

    格式字符串
    属性名 格式 描述
    日志消息内容 %(message)s The logged message,computed as msg %args.当调用Formatter.format()时设置
    asctime %(asctime)s 创建LogRecord时的可读时间。默认情况下,它的格式为“2003-07-08 16:49:45,896”(逗号后面的数字是毫秒部分的时间)
    函数名 %(funcName)s 日志调用所在的函数名
    日志级别名称 %(levelname)s 消息的级别名称’DEBUG’,‘INFO’,‘WARNING’,‘ERROR’,‘CRITICAL’
    日记级别数值 %(levelno)s 消息的级别数字,对应DEBUG,INFO,WARNING,ERROR,CRITICAL
    行号 %(lineno)d 日志调用所在的源码行号
    模块 %(module)s 模块(filename的名字部分)
    进程ID %(process)d 进程ID
    线程ID %(thread)d 线程ID
    进程名称 %(processName)s 进程名
    线程名称 %(threadName)s 线程名
    logger名称 %(name)s logger名
    默认级别
    #默认为WARRING
    import logging
    FORMAT="%(asctime)s\t Thread info: %(thread)d %(threadName)s %(message)s " \
           "simple level: %(levelno)d %(levelname)s"
    logging.basicConfig(format=FORMAT)
    logging.info(20)
    logging.warning(10)
    

    在这里插入图片描述

    构建消息
    import logging
    FORMAT="%(asctime)s\t Thread info: %(thread)d %(threadName)s %(message)s " \
           "simple level: %(levelno)d %(levelname)s"
    logging.basicConfig(format=FORMAT,level=logging.INFO)
    logging.info(20)
    logging.warning(10)
    
    字符串扩展

    如果需要输出其他内容可以使用extra扩展

    import logging
    FORMAT="%(asctime)s\t Thread info: %(thread)d %(threadName)s %(message)s " \
           "simple level: %(levelno)d %(levelname)s~~~~~~~%(school)s"
    logging.basicConfig(format=FORMAT,level=logging.INFO)
    d={'school':'university'}
    logging.info(20,extra=d)
    logging.warning(10,extra=d)
    

    在这里插入图片描述

    修改日期和输出到文件
    import logging
    logging.basicConfig(format='%(asctime)s %(message)s',datefmt="%Y/%m/%d %H:%M:%S",filename='C:/Users/ASUS/temp/o.txt')
    logging.warning('this')
    logging.warning('is')
    logging.warning('sssssss')
    

     v
    在这里插入图片描述

    Logger类

    在logging模块中,顶层代码中有

    在这里插入图片描述
    logging模块加载的时候,会创建一个全局对象root,它是一个RootLogger实例,即root logger。根Logger对象的默认等级为WARNING。
    RootLogger类继承自Logger类
    类Logger初始化方法签名是(name,level=0)
    类RootLogger初始化方法签名(level),本质上调用的是logger.init(self,“root”,WARNING)
    调用logging,basicConfig来调整级别,就是对这个根Logger的级别进行修改

    构造

    Logger实例的构建,使用Logger类也行,推荐使用getLogger函数

    import logging
    from logging import Manager,Logger
    Logger.manager=Manager(Logger.root)
    def getLogger(name=None):
        if name:
            return Logger.manager.getLogger(name)
        else:
            return root
    

    使用工厂方法返回一个Logger实例
    指定name,返回一个名称为name的Logger实例,如果再次使用相同的名字,返回同一个实例,背后使用一个字典保证同一个名称返回同一个Logger实例
    未指定name,返回根Logger实例。

    import logging
    a=logging.Logger('hello',20)
    b=logging.Logger('hello',30)
    print(a,id(a))
    print(b,id(b))
    
    c=logging.getLogger('hello')
    print(c,id(c))
    d=logging.getLogger('hello')
    print(d,id(d))
    
    层次结构

    Logger是层次结构的,使用.点号分割。

    import logging
    root=logging.root
    print(root,id(root))
    root=logging.getLogger()
    print(root,id(root))
    print(root.name,type(root),root.parent)
    
    parent=logging.getLogger(__name__)
    print(parent.name,type(parent),id(parent.parent),id(parent),parent.parent,parent)
    
    child=logging.getLogger("{}{}".format(__name__,'.child'))
    print(child.name,type(child),id(child.parent),id(child))
    

    在这里插入图片描述

    Level级别设置

    每一个logger实例都有级别设置

    import logging
    FORMAT="%(asctime)s\t Thread info: %(thread)d %(threadName)s %(message)s %(levelname)s"
    logging.basicConfig(format=FORMAT,level=logging.INFO)
    logger=logging.getLogger(__name__)
    print(logger.name,type(logging),logger.level)
    logger.info('1 info')
    print(logger.getEffectiveLevel())
    
    logger.setLevel(28)
    print(logger.getEffectiveLevel(),logger.level,'~~~~~~~~~``')
    # INFO的级别是20,所以不会输出
    logger.info('2 info')
    
    logger.setLevel(42)
    logger.warning('3 warning')
    logger.error('4 error')
    logger.critical('5 critical')
    
    root=logging.getLogger()
    root.info('6 root info')
    

    在这里插入图片描述
    每一个logger实例,都有一个等效的level
    logger对象可以在创建后动态的修改自己的level
    等效level决定这logger实例能输出什么级别信息

    Handler

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

    • 可以单独设置level
    • 可以单独设置格式
    • 可以设置过滤器

    Handler类层次

    • Handler
      • StreamHandler #不指定使用sys.stderr
        • FileHandler #文件
        • _StderrHandler#标准输出
      • NullHandler#什么都不做
        日志输出其实是Handler做的,也就是真正起作用的是Handler
        在logging.basicConfig函数中:
                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加一个输出到文件的FileHandler;如果没有设置文件名,则为根Logger加一个StreamHandler,默认输出到sys.stderr。
    也就是说,根logger一定会至少有一个handler的。

    import logging
    FORMAT='%(asctime)s %(name)s %(message)s'
    logging.basicConfig(format=FORMAT,level=logging.INFO)
    
    logger=logging.getLogger('test')
    print(logger.name,type(logger))
    logger.info('line 1')
    
    handler=logging.FileHandler('C:/Users/ASUS/temp/o.txt','w')
    logger.addHandler(handler)
    logger.info('line 2')
    

    在这里插入图片描述

    日志流

    level继承

    import logging
    logging.basicConfig(format="%(asctime)s %(name)s [%(message)s]")
    
    log1=logging.getLogger('s')
    print(log1.level,log1.getEffectiveLevel())
    log1.info('1 info')
    
    log2=logging.getLogger('s.s1')
    print(log2.level,log2.getEffectiveLevel())
    log2.info('2.info')
    print('~~~~~~~~~~~~')
    
    log1.setLevel(20)
    log1.info('3 info')
    print(log1.level,log1.getEffectiveLevel())
    print(log2.level,log2.getEffectiveLevel())
    log2.info('4.info')
    

    在这里插入图片描述
    logger实例
    如果不设置level,则初始level为0
    如果设置了level,就优先使用自己的level,否则,继承最近的祖先的level。
    信息是否能够从该logger实例上输出,就要看当前的函数的level是否大于等于logger的有效level。

    继承关系及信息传递
    • 每一个Logger实例会有一个level,如果输出等级小于这个level,无法输出

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

    • 消息传递流程

      • 如果消息在某一个logger对象上产生,这个对象就是当前logger,首先消息level要和当前logger的EffectiveLevel比较,如果低于当前logger的EffectiveLevel,则流程结束,否则生成log记录。
      • 日志记录会交给当前logger的所有handler处理,记录还要和每一个handler的级别分别比较,低的不处理,否则按照handler输出日志记录
      • 当前logger的所有handler处理完后,就要看自己的propagate属性,如果是True表示向父logger传递这个日志记录,否则流程到此结束
      • 如果日志记录传递到了父logger,不需要和父logger的level比较,而是直接交给父的所有handler,父logger成为当前logger,直到当前logger的父logger是None退出。
    • logger实例初始的propagate属性为True,即允许向父logger传递消息

    • logging.basicConfig函数
      如果root没有handler,就默认创建一个StreamHandler,如果设置了filename,就创建一个FileHandler。如果设置了format参数,就会用它生成一个Formatter对象,否则会生成缺省Formatter,并把这个formatter加入到刚才创建的handler,然后把这些handler加入到root.handlters列表上,level是设置给root loggre的,如果root.handler列表不为空,logging.basicConfig的调用什么都不做。

    展开全文
  • logging

    2019-07-16 21:58:20
    Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:  logger提供了应用程序可以直接使用的接口;  handler将(logger创建的)日志记录发送到合适的目的输出;  filter提供了细度设备来...
  • logging日志的四个等级和使用

    万次阅读 2019-08-11 16:14:16
    1. logging日志的介绍 在现实生活中,记录日志非常重要,比如:银行转账时会有转账记录;飞机飞行过程中,会有个黑盒子(飞行数据记录器)记录着飞机的飞行过程,那在咱们python程序中想要记录程序在运行时所产生的日...
  • 关于logging的那些坑

    2019-04-01 09:56:00
    python的logging日志记录模块非常强大,使用也很简单,但是特别容易出各种意外状况,打印各种出乎意料的log。最近对logging的一些原理进行了学习,再此做个记录,以备忘。 首先全面的了解一下整体的结构。logging...
  • django日志logging的配置以及处理

    千次阅读 2019-03-24 16:04:20
    一、日志相关概念 日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。一个事件可以用一个可包含可选变量数据的消息来描述。...
  • 修改 logging 时间

    千次阅读 2019-01-06 19:32:22
    在记录一些必要信息时,我通常会使用 logging 模块,在输出信息时同时可以输出时间和日志等级,例如使用 basicConfig 来先设定日志格式: logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', ...
  • logging获取日志

    2019-07-08 12:17:00
    获取日志并保存有两种写法,分别如下 #!/usr/bin/env python ...# @File : logging_test.py ''' logging获取日志 longging模块包括logger,Handler,Filter,Formatter logger:记录器,用于...
  • logging日志

    2019-08-03 19:32:47
    遇到python不懂的问题,可以加Python学习交流qun 688244617一起学习交流,还有零基础入门的学习资料和大量干货哦 1.在settings配置文件中配置以下文件: 定义三种日志输出格式 开始 standard_format = ‘[%(asctime)...
  • logging模块(日志模块)

    千次阅读 2018-10-17 11:31:41
    四、logging模块的Formatter,Handler,Logger,Filter对象 五、Logger与Handler的级别 六、Logger的继承(了解) 七、应用 django的配置 一、日志级别 import logging logging.debug('调试debug') #...
  • python 日志 logging模块(详细解析)

    万次阅读 多人点赞 2019-05-31 09:51:08
    1 基本使用 转自:...配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(...
  • Python日志输出——logging模块

    万次阅读 多人点赞 2012-03-06 00:18:44
    1. logging介绍  Python的logging模块提供了通用的日志系统,可以方便第三方模块或者是应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以...
  • 日志记录模式(LOGGING 、FORCE LOGGING 、NOLOGGING)涉及联机重做日志文件产生的大小,以及数据库的归档模式,数据库的高可用性等相关问题……
  • python logging 日志配置

    万次阅读 2017-04-12 18:44:18
    在一个类下写logging.basicConfig,在此类中调用其他包的方法都会使用该配置,其他类中无需在配置logging.basicConfig。如果不写默等级为WARN 注意,在logging.basicConfig 之前不要有logging.×××,不然配置会...
  • logging 模块的简单使用:

    千次阅读 2018-07-11 20:02:18
    import logging,os FILE = os.getcwd() 设置文件路径,默认是追加到文件中,不过可以设置filemode="w",为重写进去。 logging.basicConfig(filename=os.path.join(FILE,"dosubprocess.log"),file...
  • python Logging日志记录模块详解

    千次阅读 2019-07-14 09:18:04
      logging是Python的一个标准库,其中定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。Python logging 的配置由四个部分组成:Logger、Handlers、Filter、Formatter。本篇博客将依次介绍这四个...
  • Java中给项目程序添加log主要有三种方式,一使用JDK中的java.util.logging包,一种是log4j,一种是commons-logging。其中log4j和commons-logging都是apache软件基金会的开源项目。这三种方式的区别如下: Java.util....
  • commons-logging-1.0.4.jarcommons-logging-1.0.4.jar

    千次下载 热门讨论 2011-04-20 23:20:31
    commons-logging-1.0.4.jar freemarker-2.3.8.jar ognl-2.6.11.jar struts2-core-2.0.11.jar xwork-2.0.4.jar

空空如也

1 2 3 4 5 ... 20
收藏数 389,198
精华内容 155,679
关键字:

logging