重定向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

python logging 重定向print(标准输入输出)的更多相关文章

  1. python logging 替代print 输出内容到控制台和重定向到文件

    转自:http://blog.csdn.net/z_johnny/article/details/50740528

  2. python学习第二天标准输入输出和注释用法

    任何编程语言都有输入输出和用打交道,python也不例外,输入input(),输出print() 玖乐网络(http://www.96net.com.cn/)分享自己的心得 1,input()用法实例 ...

  3. python logging—模块

    python logging模块 python logging提供了标准的日志接口,python logging日志分为5个等级: debug(), info(), warning(), error( ...

  4. 从使用os.system)在python命令(重定向标准输入输出

    从使用os.system)在python命令(重定向标准输入输出 python 标准输出stdout stdio os.system通常我可以通过改变sys.stdout的值在python更改标准输出 ...

  5. Python学习笔记015——文件file的常规操作之三(标准输入输出文件)

    1 标准输入输出文件 在Python中,模块sys中含有标准的输入输出文件 sys.stdin     标准输入方法(一般是键盘) sys.stdout   标准输出方法(到显示器的缓冲输出) sys ...

  6. Python基础笔记系列十一:标准输入输出、文件读写和指针等操作

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 标准输入输出一.输入 在sublime中这个时候需要安装SublimeRE ...

  7. C/C++ 标准输入输出重定向

    转载自:http://www.cnblogs.com/hjslovewcl/archive/2011/01/10/2314356.html 这个对经常在OJ上做题的童鞋们很有用.OJ基本都是用标准输入 ...

  8. 【转载】标准输入输出重定向(Visual C++)

    原文:标准输入输出重定向(Visual C++) 引言 本人偶得在 Visual C++ 中进行输入输出重定向的办法,比通常的做法“freopen”更加的灵活和方便,特在此共享.目前,代码正在不断地摸 ...

  9. linux标准输入输出与重定向

    原文:http://blog.sina.com.cn/s/blog_8333cf8f0100vzzl.html##1 1. 标准输入输出和错误    linux下使用标准输入文件stdin和标准输出文 ...

随机推荐

  1. GraphQL简介

    原文地址 https://flaviocopes.com/graphql/ 中译文地址 什么是GraphQL GraphQL的原则 GraphQL vs REST Rest是一个概念 单个端点 根据你 ...

  2. [转帖]keepalived工作原理和配置、使用

    keepalived工作原理和配置.使用 https://www.iteye.com/blog/aoyouzi-2288124 keepalived是什么 keepalived是集群管理中保证集群高可 ...

  3. c++基础(五)——关联容器

    1.关联容器 关联容器中的元素时按照关键字来保存和访问的,与之相对的,顺序容器中的元素时按它们在容器中的位置来顺序保存和访问的.两个主要关联容器是 map 和 set.标准库提供了8个关联容器,这8个 ...

  4. listWdiget控件

    2019-07-15 1.常用方法的功能 listWidget = QListWidget() #实例化一个(item base)的列表 listWidget.addItem('dd') #添加一个项 ...

  5. Python-10-迭代器

    一.定义 1. 迭代的概念 迭代器即迭代的工具,那什么是迭代呢?迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不是迭 ...

  6. quartz2.3.0(七)调度器中断任务执行,手动处理任务中断事件

    job任务类 package org.quartz.examples.example7; import java.util.Date; import org.slf4j.Logger; import ...

  7. CF449E Jzzhu and Squares

    题目大意:有一个$n\times m$的方格图,求其中所有的格点正方形完整包含的小方格个数,多组询问.$n,m\leqslant 10^6$ 题解:令$n\leqslant m$.有一个显然的式子:$ ...

  8. 访问Harbor报502 Bad Gateway

    Harbor启动都是多个容器的,首先查看一下是否有相关容器未启动 docker ps | grep harbor cae340214e57 goharbor/nginx-photon:v1.9.3 & ...

  9. GOF 的23种JAVA常用设计模式总结 03 面向对象七大设计原则

    在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据 7 条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 各位代码界的大佬们总结出的七 ...

  10. Nginx的proxy buffer参数总结

    1. proxy_buffering 语法:proxy_buffering on|off 默认值:proxy_buffering on 上下文:http,server,location 作用:该指令开 ...