我正在使用该logging
模块在我的 Python 脚本中向 MS Teams 发送大量消息。不幸的是,这很慢,所以我想向消息添加异步/等待功能。
这是我的记录器模块(有些简化):
from logging import StreamHandler
import pymsteams
class TeamsHandler(StreamHandler):
def __init__(self, channel_url):
StreamHandler.__init__(self)
self.channel_url = channel_url
self.client = pymsteams.connectorcard(self.channel_url)
def emit(self, record):
msg = self.format(record)
self.client.text(msg)
try:
self.client.send()
except:
print(f"{msg} could not be sent to Teams")
然后您将在常规脚本中使用它:
import logging
from TeamsHandler import TeamsHandler #the module above
my_logger = logging.getLogger('TestLogging')
my_logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
my_logger.addHandler(console_handler)
CHANNEL_ID = "https://outlook.office.com/webhook/your-big-number"
teamshandler = TeamsHandler(CHANNEL_ID)
teamshandler.setFormatter(logging.Formatter('%(levelname)s %(message)s'))
teamshandler.setLevel(logging.DEBUG)
my_logger.addHandler(teamshandler)
for i in range(1,100):
my_logger.error(f"this is an error [{i}]")
my_logger.info(f"this is an info [{i}]")
do_something_else()
我怎样才能让它do_something_else
立即(几乎)执行,而不必等待 200 条消息才能进入 Teams?
我尝试添加一些async
和await
在中的关键字TeamsHandler
模块,但不尝试是成功的,所以我没有把他们的问题。如果不是完整的解决方案,很高兴得到一些指导。
理想情况下,随着脚本的进行,消息的顺序应该保持不变。
如果pymsteams
不支持 async/await,那么添加async
到您的函数不会真正帮助您,因为您最终仍会从pymsteams
. 即使它确实支持 async/await,它仍然无法工作,因为您是从 Python 日志记录 API 内部调用它们的,而 Python 日志记录 API 本身不是异步的。async/await 不能神奇地将同步代码转换为 async,程序必须全面使用 async/await。
但是,如果您需要异步执行只是在后台运行某些东西,则可以改用线程。例如,创建一个专门的线程进行日志记录,例如:
class TeamsHandler(StreamHandler):
def __init__(self, channel_url):
super().__init__()
self.channel_url = channel_url
self.client = pymsteams.connectorcard(self.channel_url)
self.queue = queue.Queue()
self.thread = threading.Thread(target=self._worker)
self.thread.start()
# shutdown the worker at process exit
atexit.register(self.queue.put, None)
def _worker(self):
while True:
record = self.queue.get()
if record is None:
break
msg = self.format(record)
self.client.text(msg)
try:
self.client.send()
except:
print(f"{msg} could not be sent to Teams")
def emit(self, record):
# enqueue the record to log and return control to the caller
self.queue.put(record)
当然,这有一个缺点,如果日志后端出现问题,您的程序可能会比您在日志中看到的内容提前——但是当您删除日志记录和执行之间的同步时,情况总是如此。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句