import asyncio
from pathlib import Path
import spdlog as spd
import asyncio
import logging
async def A():
asyncio.create_task(B())
while True:
await asyncio.sleep(1)
async def B():
logger = spd.DailyLogger(name = 'B', filename = 'B.log', hour = 0, minute = 0, async_mode=True)
logger.set_level(spd.LogLevel.INFO)
# logging.basicConfig(level=logging.INFO, filename='B.log', filemode='w')
# logger = logging.getLogger('B')
while True:
logger.info('B')
await asyncio.sleep(1)
if __name__ == "__main__":
asyncio.run(A())
首先,我创建了一个任务
B
inside
A
,每秒打印一行
B
当我使用Python的默认日志记录时,一切正常,但使用C++的spdlog时,无论我启用
async_mode
或不启用,都没有输出。
我尝试禁用
async_mode
,还是一样
你观察到的行为是 Python 的异步特性和 spdlog 库之间交互方式的结果。 尽管 spdlog 提供了
async_mode
选项,但它并不会使日志记录操作本身异步化。 它主要影响 spdlog 内部如何处理日志消息的
队列
。
在你的代码中,问题在于你是在一个无限循环中创建和使用 spdlog 日志器的 (
while True
)。 发生这种情况时,日志器永远不会被垃圾回收,而且更重要的是,它的内部队列也永远不会被刷新到文件中。
要解决此问题,你需要确保在某个时刻刷新日志器或将其关闭。 以下是几种方法:
1. 使用
spdlog.shutdown()
:
这是最直接的方法。 在你的主异步函数退出之前,调用
spdlog.shutdown()
会刷新所有日志器并将消息写入磁盘:
import asyncio
from pathlib import Path
import spdlog as spd
async def A():
asyncio.create_task(B())
while True:
await asyncio.sleep(1)
async def B():
logger = spd.DailyLogger(name='B', filename='B.log', hour=0, minute=0, async_mode=True)
logger.set_level(spd.LogLevel.INFO)
while True:
logger.info('B')
await asyncio.sleep(1)
if __name__ == "__main__":
asyncio.run(A())
spdlog.shutdown() # 在退出前刷新所有日志器
2. 定期刷新日志器:
你可以在循环内部定期手动刷新日志器。 这可以确保消息定期写入文件:
async def B():
logger = spd.DailyLogger(name='B', filename='B.log', hour=0, minute=0, async_mode=True)
logger.set_level(spd.LogLevel.INFO)
while True:
logger.info('B')
logger.flush() # 刷新日志器以写入消息
await asyncio.sleep(1)
3. 使用上下文管理器:
你可以使用
spdlog
的上下文管理器来自动处理刷新。 这可以确保在退出上下文时刷新日志器:
async def B():
with spd.DailyLogger(name='B', filename='B.log', hour=0, minute=0, async_mode=True) as logger:
logger.set_level(spd.LogLevel.INFO)
while True:
logger.info('B')
await asyncio.sleep(1)
请记住,虽然
async_mode=True
可以通过将日志操作卸载到单独的线程来提高性能,但在你的情况下,主要问题是缺少刷新机制。 选择最适合你需求的方法。