在aiogram的代码中添加一个asyncio的Event Loop,然后在关键部分使用run_in_executor方法来确保日志记录不会阻塞io运行。
以下是示例代码:
import asyncio
import logging
import subprocess
from aiogram import Bot, Dispatcher, types
# 配置日志
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
async def on_startup(dp):
asyncio.ensure_future(subprocess_logging())
async def subprocess_logging():
# 子进程运行一个脚本并记录输出
proc = await asyncio.create_subprocess_shell(
"python my_script.py", stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
# 日志输出处理程序
async def logger_output(fd, level):
while True:
data = await fd.readline()
if not data:
break
logger.log(level, data.decode())
# 记录标准输出和标准错误
asyncio.ensure_future(logger_output(proc.stdout, logging.INFO))
asyncio.ensure_future(logger_output(proc.stderr, logging.ERROR))
# 等待子进程结束并记录退出码
returncode = await proc.wait()
logger.info(f"子进程已退出, 返回码: {returncode}")
async def start_bot():
bot = Bot(token="BOT_TOKEN_HERE")
dp = Dispatcher(bot=bot)
dp.register_message_handler(echo, content_types=types.ContentType.TEXT)
dp.register_message_handler(photo_handler, content_types=types.ContentType.PHOTO)
dp.register_message_handler(video_handler, content_types=types.ContentType.VIDEO)
# 这里添加一个asyncio的Event Loop
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(on_startup(dp))
await dp.start_polling()
finally:
await bot.session.close()
loop.close()
async def echo(message):
await message.answer(message.text)
async def photo_handler(message):
photo_file_id = message.photo[-1].file_id
await bot.send_photo(chat_id=message.chat.id, file_id=photo_file_id)
async def video_handler(message):
video_file_id = message.video.file_id
await bot.send_video(chat_id=message.chat.id, file_id=video_file_id)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(start_bot())