zoukankan      html  css  js  c++  java
  • python+logging

    日志按照下面四个层次来完成日志的功能

    1  Logger暴露出来给应用使用的接口

    2  Handlers是发送日志记录(由logger创建的)到合适的目的地,包括文件,屏幕,email...

    3  Filters 是提供一个过滤的机制,决定哪些日志可以留下

    4  Formatters是输出日志的格式

    创建格式:

    logger = logging.getLogger('apps') # 创建一个新的apps 的logger
    
    logger.setLevel(logging.DEBUG)  # 因为它是会默认传播到祖先logger
    
    logger.propagate = False  # 默认StreamHandler那里, 也就是不会打印在页面上
    
    apps_handler = logging.FileHandler(filename="apps.log")  # 添加handler, 决定日志落地到哪里,可以多个
    
    apps_formatter=logging.Formatter('%(asctime)s:%(name)s:%(levelname)s:%(message)s'  # 输出日志的格式
    
    apps_handler.setFormatter(apps_formatter)  # 装载上
    
    logger.addHandler(apps_handler)  # 装载实例化logger上
    
    # 日志会打印到apps.log, 并且不会输出到屏幕(如果logger.propagate=True就会)

    继承;

    # 定义一个新的logger
    
    child_logger = logging.getLogger('apps.owan')
    
    # 因为这个child_logger 是apps.owan, 它是继承了apps这个logger
    
    # 这个child_logger.propagate 默认是True
    
    # 所以还是会传到它的祖先logger 也就是apps
    
    child_logger.info('haha')
    
    # 所以这个info 是会传播到apps 所以apps.log会出现这个日志。
    
    # 这里充分说明logger的继承关系

    定义Log两种方法

    第一种:就是实例化logger = logging.logger 然后手动给logger添加addHandler, addFilter, handler.setFormatter 添加格式,这样的形式来获取logger。。。。。

    import logging
    
    # 没有创建logger, 默认是root logger, 直接打印在屏幕
    
    logging.basicConfig(level=logging.DEBUG,format='%(asctime)s:%(name)s:%(levelname)s:%(message)s')                                                                                             
    
    logger = logging.getLogger('apps')
    
    apps_handler = logging.FileHandler(filename="apps.log")
    
    logger.addHandler(apps_handler)
    
    logger.setLevel(logging.DEBUG)
    
    logger.info('shis')

    第二种:就是使用 logging.config.dictConfig 来从配置文件生成logger

    logging.config.dictConfig(log_config.PATTERN)
    
    # 没有定义的logger
    
    tool_logger = logging.getLogger('ToolApi')
    
    # 由于没有定义,会冒泡到root logger
    
    tool_logger.info('----------------')
    
    # 定义过的api logger
    
    api_logger = logging.getLogger('API')
    
    # 定义过了,所以api自己的handler会处理,同时会冒泡到root logger处理
    
    api_logger.error('fuck !')

    配置文件:

    PATTERN = {
    
        'version': 1,
    
        'formatters': {
    
            'normal': {
    
                'format': '%(name)s %(asctime)s %(levelname)s %(message)s',
    
                'datefmt': '%Y-%m-%d %H:%M:%S'
    
            },
    
            'raw': {
    
                'format': '%(message)s',
    
            },
    
        },
    
        'handlers': {
    
            'console': {
    
                'class': 'logging.StreamHandler',
    
                'stream': 'ext://sys.stdout',
    
                'formatter': 'normal',
    
            },
    
            'root': {
    
                'class': 'logging.handlers.WatchedFileHandler',
    
                'formatter': 'normal',
    
                'filename': RUNTIME_HOME + '/var/log/root.log',
    
                'mode': 'a',
    
                'level': 'INFO',
    
            },
    
            'extapi': {
    
                'class': 'logging.handlers.WatchedFileHandler',
    
                'formatter': 'normal',
    
                'filename': RUNTIME_HOME + '/var/log/ext_api.log',
    
                'mode': 'a',
    
                'level': 'DEBUG',
    
            },
    
            'api': {
    
                'class': 'logging.handlers.WatchedFileHandler',
    
                'formatter': 'normal',
    
                'filename': RUNTIME_HOME + '/var/log/api.log',
    
                'mode': 'a',
    
                'level': 'DEBUG',
    
            },
    
        },
    
        'loggers': {
    
            'API': {'level': 'DEBUG',
    
                    'handlers': ['api'],
    
                    },
    
            'EXTAPI': {'level': 'DEBUG',
    
                       'handlers': ['extapi'],
    
                       },
    
            'requests.packages.urllib3.connectionpool': {'level': 'ERROR'},
    
        },
    
        'root': {
    
            'handlers': ['root',],
    
            'level': 'INFO',
    
        }
    
    }

    例子:

    import logging
    
    import os
    
    from douban_scrapy import settings
    
    from logging.handlers import RotatingFileHandler
    
    from logging import StreamHandler
    
     
    
    # 直接继承logging.Logger 那么就是说这个类就是一个Logger, 有了Logger所有方法
    
    # 只是在类里面添加一些内部方法,让logger 封装addhandler, setformatter等方法
    
    class LogHandler(logging.Logger):
    
        # 单例模式
    
        _instance = None
    
        def __new__(cls, *args, **kwargs):
    
            if not cls._instance:
    
                # 一开始居然用了 cls()来实例化 导致无限次调用
    
                # cls._instance = cls(*args, **kwargs)
    
                cls._instance = object.__new__(cls, *args, **kwargs)
    
            return cls._instance
    
     
    
        def __init__(self, name, level=logging.DEBUG, to_stream=True, to_file=True):
    
            self.name = name
    
            self.level = level
    
            self.formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
    
            # 错误的, 继承了logger 本身就是logger 不用再self.logger=xxx 这样变成了一个新的变量
    
            #self.logger = logging.Logger(name=name, level=level)
    
            super(LogHandler, self).__init__(name=name, level=level)
    
     
    
            # 写文件
    
            if to_file:
    
                self.__setFileHandler__()
    
     
    
            # 写标准输出
    
            if to_stream:
    
                self.__setSteamHandler__()
    
     
    
        def __setSteamHandler__(self):
    
            stream_handler = StreamHandler()
    
            stream_handler.setFormatter(self.formatter)
    
            self.addHandler(stream_handler)
    
     
    
        def __setFileHandler__(self):
    
            log_path = os.path.join(settings.LOG_DIR, self.name +'.log')
    
            handler = RotatingFileHandler(log_path, maxBytes=1024, backupCount=5)
    
            handler.setFormatter(self.formatter)
    
            self.addHandler(handler)
    
     
     
    
    if __name__ == '__main__':
    
        logger = LogHandler('scrapy')
    
        logger2 = LogHandler('scrapy')
    
        print logger, logger2
    
    logger.info('haha')

    2:-----------------------------------------------------------------------------------------------------------------------2

    import os
    
    import logging
    
    from logging.handlers import TimedRotatingFileHandler
    
     
    
    # 日志级别
    
    CRITICAL = 50
    
    FATAL = CRITICAL
    
    ERROR = 40
    
    WARNING = 30
    
    WARN = WARNING
    
    INFO = 20
    
    DEBUG = 10
    
    NOTSET = 0
    
     
    
    CURRENT_PATH = os.path.dirname(os.path.abspath(__file__))
    
    ROOT_PATH = os.path.join(CURRENT_PATH, os.pardir)
    
    LOG_PATH = os.path.join(ROOT_PATH, 'log')
    
     
    
     
    
    class LogHandler(logging.Logger):
    
        """
    
        LogHandler
    
        """
    
     
    
        def __init__(self, name, level=DEBUG, stream=True, file=True):
    
            self.name = name
    
            self.level = level
    
            logging.Logger.__init__(self, self.name, level=level)
    
            if stream:
    
                self.__setStreamHandler__()
    
            if file:
    
                self.__setFileHandler__()
    
     
    
        def __setFileHandler__(self, level=None):
    
            """
    
            set file handler
    
            :param level:
    
            :return:
    
            """
    
            file_name = os.path.join(LOG_PATH, '{name}.log'.format(name=self.name))
    
            # 设置日志回滚, 保存在log目录, 一天保存一个文件, 保留15天
    
            file_handler = TimedRotatingFileHandler(filename=file_name, when='D', interval=1, backupCount=15)
    
            file_handler.suffix = '%Y%m%d.log'
    
            if not level:
    
                file_handler.setLevel(self.level)
    
            else:
    
                file_handler.setLevel(level)
    
            formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
    
     
    
            file_handler.setFormatter(formatter)
    
            self.file_handler = file_handler
    
            self.addHandler(file_handler)
    
     
    
        def __setStreamHandler__(self, level=None):
    
            """
    
            set stream handler
    
            :param level:
    
            :return:
    
            """
    
            stream_handler = logging.StreamHandler()
    
            formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
    
            stream_handler.setFormatter(formatter)
    
            if not level:
    
                stream_handler.setLevel(self.level)
    
            else:
    
                stream_handler.setLevel(level)
    
            self.addHandler(stream_handler)
    
     
    
        def resetName(self, name):
    
            """
    
            reset name
    
            :param name:
    
            :return:
    
            """
    
            self.name = name
    
            self.removeHandler(self.file_handler)
    
            self.__setFileHandler__()
    
     
    
    if __name__ == '__main__':
    
        log = LogHandler('test')
    
        log.info('this is a test msg')
  • 相关阅读:
    matlab cell
    matlab linux 快捷键设置——有问题还是要解决
    latex 小结
    TOJ 1258 Very Simple Counting
    TOJ 2888 Pearls
    HDU 1248 寒冰王座
    TOJ 3486 Divisibility
    TOJ 3635 过山车
    TOJ 1840 Jack Straws
    HDU 4460 Friend Chains
  • 原文地址:https://www.cnblogs.com/person1-0-1/p/11556731.html
Copyright © 2011-2022 走看看