• python_logging模块


             软件开发中通过日志记录程序的运行情况是一个开发的好习惯,对于错误排查和系统运维都有很大帮助。
    Python标准库自带日志模块,程序的日志功能直接调用标准库的日志模块即可通过日志,开发者可以清楚地了解发生了哪些事件,包括出现了哪些错误。
     

    logging.level(message)     --->>    创建一条level级别的日志

    logging.basicConfig()        -->>     对logger进行配置

    先写个小例子:

    import logging
    
    ### Formatter格式
    #   %(asctime)s        日志事件发生的时间
    #   %(levelname)s      该日志记录的日志级别
    #   %(message)s        日志记录的文本内容
    LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"  # 设置输出的格式
    logging.basicConfig(level=logging.WARNING, format=LOG_FORMAT)  # 记录显示哪个等级以上的日志
    
    
    logging.debug('This is a debug log')
    logging.info('This is a info log')
    logging.warning('This is a warning log')
    logging.error('This is a error log')
    logging.critical('This is a critical log')

    运行结果

     到这里, 大家就有个简单的认识了。现在只是输出在控制台,后面我们还需要用Formatter格式输入log到文本。

    日志等级

     Logging 中几种级别:DEBUG < INFO < WARNING < ERROR < CRITICAL

    日志等级(level

    描述

    DEBUG

    调试信息,通常在诊断问题的时候用得着

    INFO

    普通信息,确认程序按照预期运行

    WARNING

    警告信息,表示发生意想不到的事情,或者指示接下来可能会出现一些问题,但是程序还是继续运行   

    ERROR

    错误信息,程序运行中出现了一些问题,程序某些功能不能执行

    CRITICAL

    危险信息,一个严重的错误,导致程序无法继续运行

    Formatter格式

    %(asctime)s

    日志事件发生的时间

    %(levelname)s

    该日志记录的日志级别

    %(message)s

    日志记录的文本内容

    %(name)s

    所使用的日志器名称,默认是'root'

    %(pathname)s

    调用日志记录函数的文件的全路径

    %(filename)s

    调用日志记录函数的文件

    %(funcName)s

    调用日志记录函数的函数名

    %(lineno)d

    调用日志记录函数的代码所在的行号

        如果只是简单地使用logging,那么使用上面介绍的方法就可以了,如果要深度定制logging,那么久需要对它有更深入的了解

        logging模块还提供了模块化组建的方法,来灵活配置日志器

    组件

    说明

    Loggers(日志记录器)

    提供程序直接使用的接口

    Handlers(日志处理器)

    将记录的日志发送到指定的位置

    Filters(日志过滤器)

    用于过滤特定的日志记录

    Formatters(日志格式器)

    用于控制日志信息的输出格式

    说了这么多,模块组件是怎么使用的呢?

    模块化组件的使用

    1.创建一个logger(日志处理器)对象

    2.定义handler(日志处理器),决定把日志发到哪里          

    常用的是

    StreamHandler     ->  输出到控制台

    FileHandler           ->  输出到文件

    3.设置日志级别(level)和输出格式Formatters(日志格式器
    4.把handler添加到对应的logger中去
     
     
    到这里,直接写个小案例:
    import logging
    
    # 第一步, 创建一个logger
    logger = logging.getLogger("%s_log" % __name__)
    logger.setLevel(logging.INFO)  # 设置日志等级
    
    # 第二步,创建一个handler, 用于写入日志文件
    # logging.StreamHandler()    # 输出在控制台
    fh = logging.FileHandler('test.log')  # 输出到文件 
    
    # 第三步,定义handler的输出格式           Formatte 用于控制日志信息的输出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s [line:%(lineno)d]- %(levelname)s : %(message)s")
    fh.setFormatter(formatter)   # 把格式器应用到handler中去
    
    # 第四步,将对应的hangler添加在logger对象中
    logger.addHandler(fh)

    这里还不能直接运行,我们还需要应用一下:

    try:
        1/0
    except ZeroDivisionError as c:
        logger.warning('This is a warning log')

    到这里,就算结束啦,运行看下结果:

    xshell 进入 test.log 所在文件夹,vim test.log 进入文件

     到这里,还不算结束, 哈哈!!!

    还可以封装logging, 当当!

    # __author__ = " Caric Lee "
    import logging, time, os
    # 这个是日志保存本地的路径
    log_path = "D:/log"
    
    class Log:
        def __init__(self):
            # 文件的命名
            self.logname = os.path.join(log_path, '%s.log'%time.strftime('%Y_%m_%d'))
            self.logger = logging.getLogger()
            self.logger.setLevel(logging.DEBUG)
            # 日志输出格式
            self.formatter = logging.Formatter('[%(asctime)s] -  %(filename)s[line:%(lineno)d] - fuc:%(funcName)s- %(levelname)s:  %(message)s')
        def __console(self, level, message):
            # 创建一个FileHandler,用于写到本地
            fh = logging.FileHandler(self.logname, 'a', encoding='utf-8')  # 追加模式   # 第一次执行log执行编码问题,在定义Filehandler时指定encoding
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(self.formatter)
            self.logger.addHandler(fh)
    
            # 创建一个StreamHandler,用于输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)
            ch.setFormatter(self.formatter)
            self.logger.addHandler(ch)
    
            if level == 'info':
                self.logger.info(message)
            elif level == 'debug':
                self.logger.debug(message)
            elif level == 'warning':
                self.logger.warning(message)
            elif level == 'error':
                self.logger.error(message)
            # 这两行代码是为了避免日志输出重复问题
            self.logger.removeHandler(ch)
            self.logger.removeHandler(fh)
            # 关闭打开的文件
            fh.close()
    
        def debug(self, message):
            self.__console('debug', message)
    
        def info(self, message):
            self.__console('info', message)
    
        def warning(self, message):
            self.__console('warning', message)
    
        def error(self, message):
            self.__console('error', message)
    
    if __name__ == "__main__":
       log = Log()
       log.info("---测试开始----")
       log.info("输入密码")
       log.warning("----测试结束----")

     到这真的结束了。

     
     

    作者:含笑半步颠√

    博客链接:https://www.cnblogs.com/lixy-88428977

    声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,欢迎转载。转载与引用请注明作者及出处。

  • 相关阅读:
    makefile中的wildcard和patsubst
    makefile中=,:=,?=,+=区别
    hash函数查找和ASL计算
    ubuntu apt-get提示no dependencys怎么办
    增广贤文是不多的古典珍宝之一
    如何打印查看c++stack<..>中的内容(不使用pop,top)
    c/c++标准IO重定向
    c/c++使用#define,#ifdef,#endif将debug代码分离
    未完待续
    c++重载覆盖重定义多态其他别名区别
  • 原文地址:https://www.cnblogs.com/lixy-88428977/p/9595361.html
Copyright © 2020-2023  润新知