日志模块

作者: 慕知 | 来源:发表于2021-08-28 22:05 被阅读0次

    一,日志模块介绍

    1,默认日志级别为30(输出到屏幕)

    import logging
    logging.debug('debug')          #10
    logging.info('info')            #20
    logging.warning('warm')         #30
    logging.error('error')          #40
    logging.critical('critical')    #50
    
    
    
    # WARNING:root:warm
    # ERROR:root:error
    # CRITICAL:root:critical
    
    执行可发现默认的日志级别是warming
    
    
    
    图1

    2, 日志指定输出到文件

    import logging
    
    logging.basicConfig(
    filename='access.log',
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        level=10
    )
    
    
    
    logging.debug('debug')
    logging.info('info')            
    logging.warning('warm')         
    logging.error('error')          
    logging.critical('critical')
    
    
    
    
    执行,在当前文件夹的access.log内容如下,如图1
    2021-08-27 12:55:55 PM - root - DEBUG -日志_logging:  debug
    2021-08-27 12:55:55 PM - root - INFO -日志_logging:  info
    2021-08-27 12:55:55 PM - root - WARNING -日志_logging:  warm
    2021-08-27 12:55:55 PM - root - ERROR -日志_logging:  error
    2021-08-27 12:55:55 PM - root - CRITICAL -日志_logging:  critical
    
    

    二,日志模块的四种角色

    import logging
    
    #1,logger产生日志
    logger1=logging.getLogger('访问日志')
    
    #2,Filter(过滤日志):几乎不用,略
    #3,Handle:接收logger传过来的日志,进行格式化,可以打印到终端也可以打印到文件
    
    sh=logging.StreamHandler()   #打印到终端
    sh1=logging.FileHandler('s1.log',encoding='utf-8')
    sh2=logging.FileHandler('s2.log',encoding='utf-8')
    
    
    
    
    #4,Formatter:日志格式()定义3种不同的日志格式
    formatter=logging.Formatter(
        fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p'
    )
    
    formatter1=logging.Formatter(
        fmt='%(name)s - -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p'
    )
    
    
    formatter2=logging.Formatter(
        fmt='%(asctime)s - %(levelname)s - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p'
    )
    
    
    
    
    #5,为handle绑定日志格式
    sh.setFormatter(formatter)
    sh1.setFormatter(formatter1)
    sh2.setFormatter(formatter2)
    
    
    
    #6,为logger绑定handle
    logger1.addHandler(sh)
    logger1.addHandler(sh1)
    logger1.addHandler(sh2)
    
    
    
    #7,设置日志级别
    logger1.setLevel(0)
    sh.setLevel(20)
    sh1.setLevel(30)
    sh2.setLevel(40)
    
    
    
    #8,测试
    logger1.debug('这是测试debug')
    logger1.info('运行正常~')
    logger1.warning('可能有bug哦')
    logger1.error('出bug了!!!!!')
    logger1.critical('完蛋了!!!!!')
    
    
    
    
    
    
    执行结果:
    终端屏幕上会输出:
    2021-08-28 20:33:57 PM - 访问日志 - WARNING -日志_logging:  可能有bug哦
    2021-08-28 20:33:57 PM - 访问日志 - ERROR -日志_logging:  出bug了!!!!!
    2021-08-28 20:33:57 PM - 访问日志 - CRITICAL -日志_logging:  完蛋了!!!!!
    
    
    
    
    多出个s1文件内容:
    访问日志 - -日志_logging:  可能有bug哦
    访问日志 - -日志_logging:  出bug了!!!!!
    
    
    
    
    多出个s2文件内容:
    2021-08-28 20:33:57 PM - ERROR - 出bug了!!!!!
    2021-08-28 20:33:57 PM - CRITICAL - 完蛋了!!!!!
    
    
    
    
    
    注意⚠️
    
    logger1.setLevel(0)
    sh.setLevel(20)
    sh1.setLevel(30)
    sh2.setLevel(40)
    
    第7步的日志级别中,logger1的日志级别必须比sh,sh1,sh2小,
    如果logger1级别为30,要设置sh的级别为10,是输出不了10级别(debug)和20级别(info)的日志的
    
    
    
    
    总结:
    1,输出日志logger需要绑定handle绑定终端输出,或者是文件输出(一个输出日志可以绑定给多个handle处理成多个文件)
    
    2,每个handle需要一个日志格式,即handle要绑定formatter(不同的handle可以绑定不同的formatter)
    
    3,formatter需要单独设置
    
    4,日志级别需要设置
    
    

    三,日志配置

    """
    logging配置
    """
    
    import os
    import logging.config
    
    # 定义三种日志输出格式 开始
    
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                      '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    
    
    
    
    # 定义日志输出格式 结束
    
    logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
    
    logfile_name = 'all2.log'  # log文件名
    
    # 如果不存在定义的日志目录就创建一个
    if not os.path.isdir(logfile_dir):
        os.mkdir(logfile_dir)
    
    # log文件的全路径
    logfile_path = os.path.join(logfile_dir, logfile_name)
    
    
    
    
    # log配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {                 #standard名字可以随便起,已在上方定义
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            #打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': logfile_path,  # 日志文件
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
        },
    }
    
    
    def load_my_logging_cfg():
        logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
        logger = logging.getLogger(__name__)  # 生成一个log实例
        logger.info('It works!')  # 记录该文件的运行状态
    
    if __name__ == '__main__':
        load_my_logging_cfg()
    
    
    
    
    

    四,日志应用(升级ATM)

    start.py

    import os,sys
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    
    from core import src
    if __name__ == '__main__':
        src.run()
    
    

    setting.py

    import os
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # 以上路径为/Users/shiheng/PycharmProjects/py-study/ATM
    
    LOG_PATH=os.path.join(BASE_DIR,'log','access.log')
    DB_PATH=os.path.join(BASE_DIR,'db','user')
    
    
    
    """
    logging配置
    """
    
    import os
    import logging.config
    
    # 定义三种日志输出格式 开始
    
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                      '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    
    
    
    
    # log配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {                 #standard名字可以随便起,已在上方定义
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            #打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': LOG_PATH,  # 日志文件
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': False,  # 向上(更高level的logger)传递,如果是true,会打印多个父级日志
            },
        },
    }
    
    

    src.py

    from lib import common
    def shop():
        print('购物。。。')
    
    def check_balance():
        print('查看余额。。。')
    
    def transfer_accounts():
        print('转账。。。')
        log_msg='转账了一个亿'
        logger=common.logger_handle('转账')
        logger.debug(log_msg)
    
    
    
    def  run():
        msg='''
        1 购物
        2 查看余额
        3 转账
        '''
    
        while True:
            print(msg)
            choice=input('>>:').strip()
            if not choice:continue
            if choice == '1':
                shop()
            elif choice == '2':
                check_balance()
            elif choice == '3':
                transfer_accounts()
    
    

    common.py

    from conf import settings
    import logging.config
    
    
    def logger_handle(log_name):
        logging.config.dictConfig(settings.LOGGING_DIC)  # 导入上面定义的logging配置
        logger = logging.getLogger(log_name)  # 生成一个log实例
        return logger
    
    

    accesss.log

    [2021-08-28 21:38:40,574][MainThread:4298358080][task_id:转账][src.py:12][DEBUG][转账了一个亿]
    
    
    
    

    执行start.py

    /usr/local/bin/python3 /Users/sg/PycharmProjects/py-study/ATM/bin/start.py
    
        1 购物
        2 查看余额
        3 转账
        
    >>:3
    转账。。。
    
        1 购物
        2 查看余额
        3 转账
        
    >>:[DEBUG][2021-08-28 21:38:54,837][src.py:12]转账了一个亿
    
    
    
    # 屏幕上会出现日志
    # access.log也会有相同的日志

    相关文章

      网友评论

        本文标题:日志模块

        本文链接:https://www.haomeiwen.com/subject/sudmiltx.html