• python logging 重定向print(标准输入输出)


    重定向print输出到Mongo

    celery 本身用到logging.info 会输出
    是celery的问题,还是logging初始化的时候就会有输出?
    好像是celery 配合logging的问题
    
    不同位置不同地方的```logging.getLogger(logname)```,只要logname相同,就会获取到同一个日志logging。它们设置的handler是同享的。
    可以理解为,logging名相同则注册在内存里,每次getLogger时,内存里有就指向它,没有就新建一个。
    也就是说,第一个logging.getLogger("MyLogging")设置了handler后,第二处调用logging.getLogger("MyLogging")时拿到的logging已经有handler了。如果每次初始化logging都加句柄,就会导致该句柄重复添加,重复输出。
    可以通过查看该logging的handler的方式,判断还加不加。没有就加,有就算了。
    class Logger(object):
        def __init__(self, logname="ScanDeault"):
            self.logger = logging.getLogger(logname)
            self.logger.setLevel(logging.DEBUG)
    
        def getScanLogger(self):
            if self.logger.handlers:
                return self.logger
            mon = MongoHandler(url=MONGO_SCAN_URL, database_name=MONGO_SCAN_DATABASE)
            mon.setLevel(logging.WARN)
            # ch = logging.StreamHandler()
            # fmt = logging.Formatter('[%(asctime)s][%(levelname)-5s] %(funcName)s(%(lineno)d) : %(message)s',
            #                         "%Y-%m-%d %H:%M:%S")
            # ch.setFormatter(fmt)
            # ch.setLevel(logging.INFO)
            self.logger.addHandler(mon)
            # self.logger.addHandler(ch)
            return self.logger
    
    这里注意,如果在其他地方把这个logname添加了个ERROR的handler,会导致这里的handler加不上了,handler失效
    
    class MongoHandler(logging.Handler):
        def __init__(self, level=logging.NOTSET, url=None, host='localhost', port=27017,
                     database_name='logs', collection='t_logs',
                     username=None, password=None, authentication_db='admin',
                     fail_silently=False, formatter=None, capped=False,
                     capped_max=1000, capped_size=1000000, reuse=True, **kwargs):
            """
            Setting up mongo handler, initializing mongo database connection via
            pymongo.
    
            If reuse is set to false every handler will have it's own MongoClient.
            This could hammer down your MongoDB instance, but you can still use
            this option.
    
            The default is True. As such a program with multiple handlers
            that log to mongodb will have those handlers share a single connection
            to MongoDB.
            """
            logging.Handler.__init__(self, level)
            self.url = url  # changed, 新增MongoDB连接方式
            self.host = host
            self.port = port
            self.database_name = database_name
            self.collection_name = collection
            self.username = username
            self.password = password
            self.authentication_database_name = authentication_db
            self.fail_silently = fail_silently
            self.connection = None
            self.db = None
            self.collection = None
            self.authenticated = False
            self.formatter = formatter or MongoFormatter()
            self.capped = capped
            self.capped_max = capped_max
            self.capped_size = capped_size
            self.reuse = reuse
            self._connect(**kwargs)
    
        def _connect(self, **kwargs):
            """Connecting to mongo database."""
            global _connection
            if self.reuse and _connection:
                self.connection = _connection
            else:
                if pymongo.version_tuple[0] < 3:
                    try:
                        if self.url:
                            self.connection = Connection(self.url)
                        else:
                            self.connection = Connection(host=self.host,
                                                         port=self.port, **kwargs)
                    # pymongo >= 3.0 does not raise this error
                    except PyMongoError:
                        if self.fail_silently:
                            return
                        else:
                            raise
                else:
                    if self.url:
                        self.connection = Connection(self.url)
                    else:
                        self.connection = Connection(host=self.host, port=self.port, **kwargs)
                    try:
                        self.connection.is_primary
                    except ServerSelectionTimeoutError:
                        if self.fail_silently:
                            return
                        else:
                            raise
                _connection = self.connection
    
            self.db = self.connection[self.database_name]
            if self.username is not None and self.password is not None:
                auth_db = self.connection[self.authentication_database_name]
                self.authenticated = auth_db.authenticate(self.username,
                                                          self.password)
    
            if self.capped:
                #
                # We don't want to override the capped collection
                # (and it throws an error anyway)
                try:
                    self.collection = Collection(self.db, self.collection_name,
                                                 capped=True, max=self.capped_max,
                                                 size=self.capped_size)
                except OperationFailure:
                    # Capped collection exists, so get it.
                    self.collection = self.db[self.collection_name]
            else:
                self.collection = self.db[self.collection_name]
    
        def close(self):
            """
            If authenticated, logging out and closing mongo database connection.
            """
            if self.authenticated:
                self.db.logout()
            if self.connection is not None:
                self.connection.close()
    
        def emit(self, record):
            """Inserting new logging record to mongo database."""
            if self.collection is not None:
                try:
                    if os.path.basename(__file__) not in record.pathname:
                        getattr(self.collection, write_method)(self.format(record))
                except Exception:
                    if not self.fail_silently:
                        self.handleError(record)
    
    class MyLogger(object):
        def __init__(self, logname="MyRePrint"):
            self.logger = logging.getLogger(logname)
            self.logger.setLevel(logging.DEBUG)
            if not self.logger.handlers:
                mon = MongoHandler(url=MONGO_SCAN_URL, database_name=MONGO_SCAN_DATABASE)
                mon.setLevel(logging.INFO)   # print为INFO级别
                ch = logging.StreamHandler()
                ch.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)-5s] %(funcName)s(%(lineno)d) : %(message)s',
                                                  "%Y-%m-%d %H:%M:%S"))
                ch.setLevel(logging.INFO)
                self.logger.addHandler(ch)
                self.logger.addHandler(mon)
    
        def write(self, message):
            if message.strip():
                self.logger.info(message)
    
    if __name__ == '__main__':
        original_stdout = sys.stdout
        sys.stdout = PluginLogger(logname="MyRePrint")
        print 1
        sys.stdout = original_stdout
    
    
  • 相关阅读:
    spring异常
    springboot+mybatis
    mybatis初识
    模板引擎Dot
    mysql数据库操作
    1. 安装Oracle,配置环境 2. 实现查询From子句 3. 实现查询where子句 4. 实现查询order by子句
    (1)Set集合 (2)Map集合 (3)异常机制
    (1)网络编程的常识 (2)基于tcp协议的编程模型 (3)tcp协议和udp协议的比较 (4)基于udp协议的编程模型
    (1)线程的常用方法 (2)线程的同步机制 (3)网络编程的常识
    (1)I/O流 (2)线程
  • 原文地址:https://www.cnblogs.com/huim/p/11856173.html
Copyright © 2020-2023  润新知