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

    一、logging模块的简介

     logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

    1. 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
    2. print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出

    二、logging模块的机制:

    • logger:提供日志接口,供应用代码使用。logger最长用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
    • handler:将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
    •  filter:提供一种优雅的方式决定一个日志记录是否发送到handler。
    •  formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。

    三、logging模块的使用,分为一下几步:

      1.倒入logging模块

      2.配置logging基本的设置(包括:(1.)log的输出路径  (2.)log的输出格式  (3.)log的输出方式 (4.)log的输出内容)

      3.实例化一个logging对象(如果不实例化,那么默认实例化对象是root)

      4.进行内容的编辑

    具体看2个例子:

    #!/usr/bin/env/python
    # -*-coding:utf-8-*-
    
    import logging
    logging.basicConfig(level
    = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s') #1.实例化logger记录器对象,记录器的名称叫 appname logger = logging.getLogger("appname") logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")

    结果:

    2018-08-01 17:52:19,734 - appname - INFO - Start print log
    2018-08-01 17:52:19,734 - appname - WARNING - Something maybe fail.
    2018-08-01 17:52:19,734 - appname - INFO - Finish

    #!/usr/bin/env/python
    # -*-coding:utf-8-*-
    
    import logging
    
    #2.没有实例化的
    logging.debug('debug message')
    logging.info('info message')
    logging.warn('warn message')
    logging.error('error message')
    logging.critical('critical message')

    结果:

    WARNING:root:warn message
    ERROR:root:error message
    CRITICAL:root:critical message

      可以看出来,没有对logging进行格式化的话,log的格式是以下图片:

       

      格式化logging的格式是:按照定义的log输出格式来的。

      问题来了:为什么第一个例子没有debug的信息,第二个例子没有debug和info的信息?那么我们就要对日志级别进行详细讲解了,看以下的内容。

    四、logging的级别详解 

    日志级别
    级别 何时使用
    DEBUG 详细信息,调试的时候一步一步看结果时会用,一般可以不用
    INFO 证明事情按预期工作,正常运行
    WARNING 表明发生了一些意外,或者不久将来会发生的问题(磁盘满了),但是程序还是在正常工作
    ERROR 由于更严重的问题,软件已不能执行一些功能了
    CRITOCAL 严重错误,表示程序已不能继续运行了

     

      如果不设置log的基本配置,那么默认是从warning开始输出,所以第二个例子是没有info和debug的信息。

      第一个例子,由于设定了log的输出最低级别level=logging.info,所以第一个例子有info但是没有debug的信息。

     五、logging的配置方式

    • 显式创建记录器Logger、处理器Handler和格式化器Formatter,并进行相关设置;
    • 通过简单方式进行配置,使用basicConfig()函数直接进行配置;
    • 通过配置文件进行配置,使用fileConfig()函数读取配置文件;
    • 通过配置字典进行配置,使用dictConfig()函数读取配置信息;
    • 通过网络进行配置,使用listen()函数进行网络配置。

    logging用法解析

    1. 初始化 logger = logging.getLogger("endlesscode"),getLogger()方法后面最好加上所要日志记录的模块名字,后面的日志格式中的%(name)s 对应的是这里的模块名字
    2. 设置级别 logger.setLevel(logging.DEBUG),Logging中有NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL这几种级别,日志会记录设置级别以上的日志
    3. Handler,常用的是StreamHandler和FileHandler,windows下你可以简单理解为一个是console和文件日志,一个打印在CMD窗口上,一个记录在一个文件上
    4. formatter,定义了最终log信息的顺序,结构和内容,我喜欢用这样的格式 '[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S',

    basicConfig关键字参数

    关键字描述
    filename 创建一个FileHandler,使用指定的文件名,而不是使用StreamHandler。
    filemode 如果指明了文件名,指明打开文件的模式(如果没有指明filemode,默认为'a')。
    format handler使用指明的格式化字符串。
    datefmt 使用指明的日期/时间格式。
    level 指明根logger的级别。
    stream 使用指明的流来初始化StreamHandler。该参数与'filename'不兼容,如果两个都有,'stream'被忽略。
                                                                     
    有用的format格式
    格式描述
    %(levelno)s 打印日志级别的数值
    %(levelname)s 打印日志级别名称
    %(pathname)s 打印当前执行程序的路径
    %(filename)s 打印当前执行程序名称
    %(funcName)s 打印日志的当前函数
    %(lineno)d 打印日志的当前行号
    %(name)s Logger的名字
    %(module)s 调用日志输出函数的模块名
    %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    %(asctime)s 打印日志的时间,默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    %(thread)d 打印线程id
    %(threadName)s 打印线程名称
    %(process)d 打印进程ID
    %(message)s 打印日志信息




     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    看一段代码:
    #!/usr/bin/env/python
    # -*-coding:utf-8-*-
    
    import logging
    
    #实例化logging对象,实例化的名称叫 appname
    logger = logging.getLogger("appname")
    
    #建立一个filehandler来把日志以只读的形式记录在文件appLog.md中,级别为debug以上
    fh = logging.FileHandler("appLog.md",'w')
    fh.setLevel(logging.DEBUG)
    
    #建立一个streamhandler来把日志打在cmd窗口上,级别为error以上
    sh = logging.StreamHandler()
    sh.setLevel(logging.ERROR)
    
    #设置日志的格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    sh.setFormatter(formatter)
    
    #将相应的handler添加在logger对象中
    logger.addHandler(fh)
    logger.addHandler(sh)
    
    #开始打印信息
    logger.info("Start print log")
    logger.debug("Do something")
    logger.warning("Something maybe fail.")
    logger.info("Finish")
    logger.error("error")
    logger.critical("critical")

    结果:
    cmd

    appLog.md

    
    

     当一个项目比较大的时候,不同的文件都要用到log,可以烤考虑将其封装为一个类来使用。

    #!/usr/bin/env/python
    # -*-coding:utf-8-*-
    
    import logging
    
    class LogTest(object):
    
        def __init__(self,path,s_level=logging.DEBUG, f_level=logging.DEBUG):
            self.logger = logging.getLogger(path)
            self.logger.setLevel(logging.DEBUG)
    
            #定义日志格式
            fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
            # 设置写入CMD日志
            sh = logging.StreamHandler()
            sh.setFormatter(fmt)
            sh.setLevel(s_level)
            # 设置写入文件日志
            fh = logging.FileHandler(path)
            fh.setFormatter(fmt)
            fh.setLevel(f_level)
            #将handle加入logger对象中
            self.logger.addHandler(sh)
            self.logger.addHandler(fh)
    
        def debug(self, message):
            self.logger.debug(message)
    
        def info(self, message):
            self.logger.info(message)
    
        def war(self, message):
            self.logger.warn(message)
    
        def error(self, message):
            self.logger.error(message)
    
        def cri(self, message):
            self.logger.critical(message)
    
    if __name__ == '__main__':
        logyyx = LogTest('yyx.log', logging.ERROR, logging.DEBUG)
        logyyx.debug('一个debug信息')
        logyyx.info('一个info信息')
        logyyx.war('一个warning信息')
        logyyx.error('一个error信息')
        logyyx.cri('一个致命critical信息')

    如果想在CMD窗口中对于error的日志标红,warning的日志标黄,那么可以使用ctypes模块

    #!/usr/bin/env/python
    # -*-coding:utf-8-*-
    
    import logging
    import ctypes
    
    FOREGROUND_WHITE = 0x0007
    FOREGROUND_BLUE = 0x01  # text color contains blue.
    FOREGROUND_GREEN = 0x02  # text color contains green.
    FOREGROUND_RED = 0x04  # text color contains red.
    FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN
    
    STD_OUTPUT_HANDLE = -11
    std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
    
    
    def set_color(color, handle=std_out_handle):
        bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
        return bool
    
    
    class Logger:
        
        def __init__(self, path, clevel=logging.DEBUG, Flevel=logging.DEBUG):
            self.logger = logging.getLogger(path)
            self.logger.setLevel(logging.DEBUG)
            fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
            # 设置CMD日志
            sh = logging.StreamHandler()
            sh.setFormatter(fmt)
            sh.setLevel(clevel)
            # 设置文件日志
            fh = logging.FileHandler(path)
            fh.setFormatter(fmt)
            fh.setLevel(Flevel)
            self.logger.addHandler(sh)
            self.logger.addHandler(fh)
    
        def debug(self, message):
            self.logger.debug(message)
    
        def info(self, message):
            self.logger.info(message)
    
        def war(self, message, color=FOREGROUND_YELLOW):
            set_color(color)
            self.logger.warn(message)
            set_color(FOREGROUND_WHITE)
    
        def error(self, message, color=FOREGROUND_RED):
            set_color(color)
            self.logger.error(message)
            set_color(FOREGROUND_WHITE)
    
        def cri(self, message):
            self.logger.critical(message)
    
    
    if __name__ == '__main__':
        logyyx = Logger('yyx.log', logging.WARNING, logging.DEBUG)
        logyyx.debug('一个debug信息')
        logyyx.info('一个info信息')
        logyyx.war('一个warning信息')
        logyyx.error('一个error信息')
        logyyx.cri('一个致命critical信息')
  • 相关阅读:
    JS获取元素的子元素
    js iframe
    获取窗口句柄
    python 从PDF中提取附件
    xlwings 使用方法
    基于KNN的发票识别
    爬取漫画网站并进行图片拼接
    用python实现对元素的长截图
    Head First C 第三章总结
    Ruby on Rails Tutorial 第八章笔记 基本登陆功能
  • 原文地址:https://www.cnblogs.com/peiminer/p/9403275.html
Copyright © 2011-2022 走看看