zoukankan      html  css  js  c++  java
  • python—模块-logging

    logging—记录运行的日志,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别,专业的软件都会有日志级别

    看一下这几个日志级别分别代表什么意思

    LevelWhen it’s used
    DEBUG 调试,平常的日志不会很详细,调成debug会很详细
    INFO 普通的记录
    WARNING 没有错误,担忧潜在的错误
    ERROR 出错误了
    CRITICAL 更高一级的错误

    最简单用法

    import logging
    
    logging.warning("user [alex] attempted wrong password more than 3 times")
    logging.critical("server is down")
    

    输出

    WARNING:root:user [alex] attempted wrong password more than 3 times
    CRITICAL:root:server is down



    其中root是默认以root用户运行程序。

    如果想把日志写到文件里,也很简单

    import logging
    
    logging.basicConfig(filename='log_text.log',level=logging.INFO)
    logging.debug('This message should go to the log file')
    logging.info('So should this')
    logging.warning('And this, too')

    其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。

    #打开log_text.log文件
    INFO:root:So should this
    WARNING:root:And this, too

    可以看到只输出了两条错误,但是输入了三条错误,所以就是说inf及以后的级别的日志才会被记录。

    如果再写一个,会追加,而不是覆盖

    import logging
    
    logging.basicConfig(filename='log_text.log',level=logging.DEBUG)
    logging.debug('This message should go to the log file')
    logging.info('So should this')
    logging.warning('And this, too')

    打开文件夹,会看到如下:

    INFO:root:So should this
    WARNING:root:And this, too
    DEBUG:root:This message should go to the log file
    INFO:root:So should this
    WARNING:root:And this, too

    那么有什么作用呢,如果有用户攻击你的电脑,假设你知道对方的IP地址,你再加上时间,就变成了有用的信息,也就是自定义日志格式。import data  或 import time

    自定义日志格式

    import logging
    logging.basicConfig(filename='log_text.log',

    level=logging.DEBUG,

    format='%(asctime)s %(message)s',

    datefmt='%m/%d/%Y %I:%M:%S %p')

    logging.warning(
    'is when this event was logged.')

    打开文件

    INFO:root:So should this
    WARNING:root:And this, too
    DEBUG:root:This message should go to the log file
    INFO:root:So should this
    WARNING:root:And this, too
    05/22/2018 08:27:52 PM This message should go to the log file
    05/22/2018 08:27:52 PM So should this
    05/22/2018 08:27:52 PM And this, too

    除了加时间,还可以自定义一大堆格式,下表就是所有支持的格式

    %(name)sLogger的名字
    %(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

    用户输出的消息

    举例:
    import logging
    
    logging.basicConfig(filename='log_text.log',
                        level=logging.DEBUG,
                        format='%(asctime)s:%(levelname)s:%(filename)s:%(funcName)s: %(message)s',
                        datefmt='%m/%d/%Y %I:%M:%S %p')
    def sayhi():
        logging.error('from sayhi...')
    sayhi()
    logging.debug('This message should go to the log file')
    logging.info('So should this')
    logging.warning('And this, too')
     
    05/22/2018 08:50:16 PM:ERROR:oneday.py:sayhi: from sayhi...
    05/22/2018 08:50:16 PM:DEBUG:oneday.py:<module>: This message should go to the log file
    05/22/2018 08:50:16 PM:INFO:oneday.py:<module>: So should this
    05/22/2018 08:50:16 PM:WARNING:oneday.py:<module>: And this, too

    上面是直接打在了屏幕上或者文件里,下面既可以搭载屏幕上,又会打在文件里(也就是通过两个方向输入信息):

    日志同时输出到屏幕和文件

    如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了

    Python 使用logging模块记录日志涉及四个主要类(组件),使用官方文档中的概括最为合适:

    • logger提供了应用程序可以直接使用的接口;
    • handler将(logger创建的)日志记录发送到合适的目的输出;
    • filter提供了细度设备来决定输出哪条日志记录;
    • formatter决定日志记录的最终输出格式。

    他们之间的关系是这样的

    每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:

    1. logging.StreamHandler 使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。
    2. logging.FileHandler 和StreamHandler 类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件
    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 每天凌晨

    formatter 组件

    日志的formatter是个独立的组件,可以跟handler组合

    fh = logging.FileHandler("access.log")
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    fh.setFormatter(formatter) #把formmater绑定到fh上
    

     

    import logging
    #1. 生成logger对象
    logger = logging.getLogger('web')
    logger.setLevel(logging.INFO)#设置访问级别
    #2. 生成handle对象
    ch = logging.StreamHandler()
    fh = logging.FileHandler('web.log')
    #2.1 把handle对象绑到logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    #3. 生成formatter 对象
    #3.1 把formatter对象帮绑到handle对象
    file_matter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    
    ch.setFormatter(console_formatter)
    fh.setFormatter(file_matter)
    
    
    logger.debug('text.log')

    文件和屏幕会有显示:
    但如果像下面这样
    import logging
    #1. 生成logger对象
    logger = logging.getLogger('web')
    logger.setLevel(logging.INFO)#设置访问级别
    #2. 生成handle对象
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)# 对屏幕设置日志级别
    
    fh = logging.FileHandler('web.log')
    fh .setLevel(logging.WARNING) # 对文件设置级别
    #2.1 把handle对象绑到logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    #3. 生成formatter 对象
    #3.1 把formatter对象帮绑到handle对象
    file_matter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
    
    ch.setFormatter(console_formatter)
    fh.setFormatter(file_matter)
    
    
    logger.info('text.log')
    logger.debug('text log2')
    
    #console : DEBUG
    #global : INFO
    #file : Warning
    我们发现只有info会再屏幕和文件显示

    日志过滤和日志文件自动截取

    filter 组件

    如果你想对日志内容进行过滤,就可自定义一个filter

    class IgnoreBackupLogFilter(logging.Filter):
        """忽略带db backup 的日志"""
        def filter(self, record): #固定写法
            return   "db backup" not in record.getMessage()

    注意filter函数会返加True or False,logger根据此值决定是否输出此日志

    然后把这个filter添加到logger中

    logger.addFilter(IgnoreBackupLogFilter())

    下面的日志就会把符合filter条件的过滤掉

    logger.debug("test ....")
    logger.info("test info ....")
    logger.warning("start to run db backup job ....")
    logger.error("test error ....")

    一个同时输出到屏幕、文件、带filter的完成例子





















  • 相关阅读:
    Visual Studio 2005 ReportViewer 自适应报表大小显示
    【Vegas原创】SharePoint 503 Service Unavailable Error解决方法
    【Vegas改编】用C#实现浏览文件夹功能
    【Vegas2010】最后的g.cn
    【Vegas原创】SQL Server游标的经典使用
    命名规范(变量、控件)
    【Vegas原创】outlook发送时,报550 5.7.1 client does not have permissions to send as this sender解决方法
    【Vegas原创】Winform中使用MaskedTextBox制作IP地址输入框
    【Vegas原创】Apache2.2 + PHP5.3.2 + Oracle 10g配置
    IT职涯路
  • 原文地址:https://www.cnblogs.com/xiaobai-yemao/p/9072699.html
Copyright © 2011-2022 走看看