微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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‘,

            ‘filename‘: RUNTIME_HOME + ‘/var/log/root.log‘,

            ‘mode‘: ‘a‘,

            ‘level‘: ‘INFO‘,

        ‘extapi‘: {

            ‘class‘: ‘logging.handlers.WatchedFileHandler‘,

            ‘filename‘: RUNTIME_HOME + ‘/var/log/ext_api.log‘,

            ‘level‘: ‘DEBUG‘,

        ‘api‘: {

            ‘class‘: ‘logging.handlers.WatchedFileHandler‘,

            ‘filename‘: RUNTIME_HOME + ‘/var/log/api.log‘,

    ‘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,**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,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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐