重定向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. 永久解决Sublime包管理package control 打开install package报错 There are no packages available for installation

    很多用户在使用sumblime安装插件的时候,打开package control的install package会出现报错:There are no packages available for in ...

  2. 分布式全文搜索引擎(ElasticSearch)

    1. ElasticSearch介绍(简称ES) ES即为了解决原生Lucene使用的不足,优化Lucene的调用方式,并实现了高可用的分布式集群的搜索方案. 首先,ES的索引库管理支持依然是基于Ap ...

  3. docker(三):服务services

    docker中services位于container上面,services可以控制image的运行方式,包括image运行时所需资源的大小 创建yml文件 yml文件定义了容器运行时的行为.我们先创建 ...

  4. vue 仿写微信公众号自定义菜单

    先看效果图 代码参考 <template> <div> <!-- 公众号设置 --> <el-col :span="24" style=& ...

  5. 判断密码是否可见/判断登录的状态/判断在form表单中 定义rules规则验证(iview)

    一: 判断密码是否可见判断:type="visiblePassword ? 'text' : 'password'" 是否为false 或者 true 密码为输入框或者文本框点击眼 ...

  6. caurina缓动类

    一.简单的缓动 一个实例名为box的正方体,开始alpha为0.5,在两秒内移动到x:300 y:100的位置,alpha变为1.import caurina.transitions.Tweener; ...

  7. uni-app项目导入第三方组件库muse-ui

    你说uni-app是什么 我说,uni-app是一套基于vue.js开发跨平台应用的前端框架,可编译多个平台,比如:Android.IOS.H5.微信小程序.支付宝小程序.头条小程序.百度小程序 懂行 ...

  8. [jsp学习笔记] jsp过滤器

  9. Logback+ELK+SpringMVC搭建日志收集服务器

    (转) 1.ELK是什么? ELK是由Elasticsearch.Logstash.Kibana这3个软件的缩写. Elasticsearch是一个分布式搜索分析引擎,稳定.可水平扩展.易于管理是它的 ...

  10. text-overflow 全兼容

    text-overflow 全兼容 text-overflow 这个CSS属性用于设置或检索是否使用一个省略标记(...)标示对象内文本的溢出.比起在后台用程序截断文本再附上省略标记的做法,用CSS来 ...