我遇到了某种循环问题,试图使用自定义处理程序在我的项目中实现日志记录,因此我正在寻求帮助。我确实有一定的编程经验,但是我对python还是很陌生,所以也许我完全错了。
如下所示,我收到一个“ RecursionError”。我还在这篇文章的结尾处附加了错误的截断副本以及代码。
提前谢谢!
Error:
Traceback (most recent call last):
File "app.py", line 18, in <module>
logger.debug('debug message!')
File "/usr/lib/python3.8/logging/__init__.py", line 1422, in debug
self._log(DEBUG, msg, args, **kwargs)
File "/usr/lib/python3.8/logging/__init__.py", line 1577, in _log
self.handle(record)
File "/usr/lib/python3.8/logging/__init__.py", line 1587, in handle
self.callHandlers(record)
File "/usr/lib/python3.8/logging/__init__.py", line 1649, in callHandlers
hdlr.handle(record)
File "/usr/lib/python3.8/logging/__init__.py", line 950, in handle
self.emit(record)
File "/app/python/logger_handlers.py", line 27, in emit
requests.post(self.url, headers = header, data = json.dumps(payload))
[...truncated...]
RecursionError: maximum recursion depth exceeded in comparison
# app.py
import logging
import my_module
from logger_handlers import CustomHandler
logging.getLogger("requests").disabled = True
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# Custom handler
custom_handler = CustomHandler(url = 'http://some_url.com/api/1/log')
custom_handler.setLevel(logging.DEBUG)
custom_handler.setFormatter(formatter)
logger.addHandler(custom_handler)
# Log to root handler
logger.debug('debug message!')
# Run a function in a different module that also has a logger defined
my_module.run()
# my_module.py
import logging
log = logging.getLogger(__name__)
log.addHandler(logging.NullHandler())
def run():
log.debug('A message from A Module')
# logger_handlers.py
import logging
import requests
import json
from socket import gethostname, gethostbyname
class CustomHandler(logging.Handler):
def __init__(self, *args, **kwargs):
super().__init__()
self.url = kwargs['url']
def emit(self, record):
message = self.format(record)
header = {"content-type": "application/json"}
payload = {
"token":None,
"client_version":"",
"parameters": {
"source": "Host: {} ({}), Module: {}, {}".format(gethostname(), gethostbyname(gethostname()), record.filename, record.funcName),
"severity": record.levelname,
"message": message
}
}
requests.post(self.url, headers = header, data = json.dumps(payload))
更新(2020-04-03):
通过使用此代码段,我能够识别出为避免循环而必须禁用的所有记录器:
for key in logging.Logger.manager.loggerDict:
print(key)
然后我用它来禁用它们:
logging.getLogger("urllib3.util.retry").disabled = True
logging.getLogger("urllib3.util").disabled = True
logging.getLogger("urllib3").disabled = True
logging.getLogger("urllib3.connection").disabled = True
logging.getLogger("urllib3.response").disabled = True
logging.getLogger("urllib3.connectionpool").disabled = True
logging.getLogger("urllib3.poolmanager").disabled = True
logging.getLogger("requests").disabled = True
不是很漂亮,但是可以。如果您认为此方法存在主要缺点,请随时发表评论。
答案 0 :(得分:0)
在您的app.py脚本中,只需将 name 作为name参数传递给getLogger()。所以,
logger = logging.getLogger(__name__)
答案 1 :(得分:0)
使用请求模块执行请求时,将创建日志。有些来自requests
记录器,也有些来自其他使用的库。例如,urllib
模块还具有一个创建日志的记录器。这些日志在日志层次结构中传播并最终到达根记录器。根记录器也有您的处理程序,因此将再次执行q请求,从而创建更多日志,并最终存储在根记录器中。
仅将处理程序添加到请求日志不传播到的记录器中。