ROS logger与Python logger冲突求助:如何独立使用Python logger
我完全懂你碰到的这个糟心问题——rospy初始化节点前Python日志完全没动静,只有节点启动后才正常输出,这确实是rospy在背后修改了Python标准logging系统的配置导致的。下面给你拆解原因和可行的解决方案:
问题根源
rospy在执行rospy.init_node()时,会初始化ROS专属的日志系统,其中关键操作是替换Python根logger的Handler,还可能调整根logger的日志级别。如果你的自定义logger没有做隔离设置,就会被rospy的配置覆盖,导致节点初始化前的日志无法输出,而节点启动后才会继承rospy修改后的配置。
解决方案:彻底隔离自定义Python Logger
要让你的Python logger完全独立于rospy工作,只需要做两个关键修改:
1. 禁用自定义logger的日志传播
设置logger.propagate = False,这样你的日志就不会传递到根logger,彻底避开rospy对根logger的修改干扰。
2. 明确设置自定义logger的最低日志级别
默认情况下,Python logger的级别是NOTSET,会自动继承根logger的级别(默认是WARNING)。哪怕你给Handler设置了更低的级别,只要logger本身的级别不够,日志还是会被过滤掉。所以要手动给logger设置最低级别(比如DEBUG),确保所有符合Handler级别的日志都能输出。
修改后的Logger初始化代码
import logging path = "/some_directory/" formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger('logger_name') # 关键修改1:禁用日志传播,切断与根logger的关联 logger.propagate = False # 关键修改2:明确设置logger的最低级别,确保日志能被正常处理 logger.setLevel(logging.DEBUG) # 基础日志文件Handler file_handler_info = logging.FileHandler('{}log.log'.format(path)) file_handler_info.setFormatter(formatter) file_handler_info.setLevel(logging.INFO) logger.addHandler(file_handler_info) # 警告日志文件Handler file_handler_critical = logging.FileHandler('{}critical.log'.format(path)) file_handler_critical.setFormatter(formatter) file_handler_critical.setLevel(logging.WARNING) logger.addHandler(file_handler_critical) # 控制台输出Handler stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) stream_handler.setLevel(logging.DEBUG) logger.addHandler(stream_handler)
修改后的ROS节点启动代码
现在不管rospy有没有初始化,你的logger都能正常输出了:
logger.info("This message WILL be displayed now!") rospy.init_node('node_name', anonymous=True) logger.info("This message will also be displayed")
额外说明
如果你之后需要同时使用rospy的日志(比如rospy.loginfo()),也不会和自定义logger冲突——两者已经完全隔离,rospy的日志会走ROS自身的rosout系统,而你的自定义日志会严格按照你配置的Handler输出。
内容的提问来源于stack exchange,提问作者Sharky Bamboozle

