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
python logging 重定向print(标准输入输出)的更多相关文章
- python logging 替代print 输出内容到控制台和重定向到文件
转自:http://blog.csdn.net/z_johnny/article/details/50740528
- python学习第二天标准输入输出和注释用法
任何编程语言都有输入输出和用打交道,python也不例外,输入input(),输出print() 玖乐网络(http://www.96net.com.cn/)分享自己的心得 1,input()用法实例 ...
- python logging—模块
python logging模块 python logging提供了标准的日志接口,python logging日志分为5个等级: debug(), info(), warning(), error( ...
- 从使用os.system)在python命令(重定向标准输入输出
从使用os.system)在python命令(重定向标准输入输出 python 标准输出stdout stdio os.system通常我可以通过改变sys.stdout的值在python更改标准输出 ...
- Python学习笔记015——文件file的常规操作之三(标准输入输出文件)
1 标准输入输出文件 在Python中,模块sys中含有标准的输入输出文件 sys.stdin 标准输入方法(一般是键盘) sys.stdout 标准输出方法(到显示器的缓冲输出) sys ...
- Python基础笔记系列十一:标准输入输出、文件读写和指针等操作
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 标准输入输出一.输入 在sublime中这个时候需要安装SublimeRE ...
- C/C++ 标准输入输出重定向
转载自:http://www.cnblogs.com/hjslovewcl/archive/2011/01/10/2314356.html 这个对经常在OJ上做题的童鞋们很有用.OJ基本都是用标准输入 ...
- 【转载】标准输入输出重定向(Visual C++)
原文:标准输入输出重定向(Visual C++) 引言 本人偶得在 Visual C++ 中进行输入输出重定向的办法,比通常的做法“freopen”更加的灵活和方便,特在此共享.目前,代码正在不断地摸 ...
- linux标准输入输出与重定向
原文:http://blog.sina.com.cn/s/blog_8333cf8f0100vzzl.html##1 1. 标准输入输出和错误 linux下使用标准输入文件stdin和标准输出文 ...
随机推荐
- 深度解析qml引擎---(1)Qml文件加载
"美的事物是永恒的喜悦" --- 济慈 ...
- PAT(B) 1045 快速排序(C)
题目链接:1045 快速排序 (25 point(s)) 参考博客:1045 快速排序 (25 point(s))繁星蓝雨 题目描述 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一 ...
- HTTPDNS
传统 DNS 缺点 1.域名缓存问题 它可以在本地做一个缓存,也就是说,不是每一个请求,它都会去访问权威 DNS 服务器,而是访问过一次就把结果缓存到自己本地,当其他人来问的时候,直接就返回这 ...
- 测试不得不知的python编程小技能-----升级版基础语法和优秀的编码习惯
编程和学习python,最后快速上手.能写小工具,写自动化用例这类要求对鹅厂的测试人员来说都是一些基础的必备素质,但是一个优秀的测试,也是有着一颗开发完美测试工具的心的.但是罗马不是一天构建成,特别是 ...
- 使用 SetParent 跨进程设置父子窗口时的一些问题(小心卡死)
原文:使用 SetParent 跨进程设置父子窗口时的一些问题(小心卡死) 在微软的官方文档中,说 SetParent 可以在进程内设置,也可以跨进程设置.当使用跨进程设置窗口的父子关系时,你需要注意 ...
- usercript and passwdcript array
usercript and passwdcript array ######################## # nsnet_usercript # xxd -g 4 -c 16 -s +$(( ...
- Vue异步加载高德地图API
项目中用到了高德地图的API以及UI组件库,因为是直接把引入script写在index.html中,项目打包后运行在服务器,用浏览器访问加载第一次时会非常慢,主要原因是加载高德地图相关的js(近一分钟 ...
- title 有背景边框自适应 mobile
固定宽度,固定高度,来写背景的高度.这样就能居中.
- C# 将Excel导出PDF
1.安装所需包,使用nuget安装所需包 1.1.Spire.Xls 1.2.iTextSharp.text.pdf 2.Spire.Xls介绍 将Excel转换为PDF是一个很常用的功能,常见的转换 ...
- 微信小程序自定义toast的实现
今天写微信小程序突然发现一个尴尬的问题,请求报错需要提示,就去小程序API里找,可悲的小程序的toast并不能满足我的需求,原生提供的方法调用如下 wx.showToast({ title: '成功' ...