使用 Python、ROS 和 C++ 进行记录
Logging with Python, ROS, and C++
我有一个 Python 的代码库和 C++ 代码,包括大量使用 ROS。记录是在整个 Python 代码中完成的,同时 system logger and rospy logging -- 人为的例子:
import logging
import rospy
logging.basicConfig(level=logging.INFO)
LOG = logging.getLogger(__name__)
def run():
rospy.loginfo("This is a ROS log message")
LOG.info("And now from Python")
if __name__ == '__main__':
runt()
至于 C++ 代码,我们需要添加日志记录,可能使用 glog,但我愿意接受其他选项。
有没有办法将各种记录器集成到一个模块中? 理想情况下,用户可以在幕后做 my_logger = AwesomeLogger(level='info', output='my_logs.txt')
然后 AwesomeLogger
设置 Python 和 C++ 记录器,并将所有日志输出(包括来自 ROS)合并到干净的控制台消息输出文本文件中。
请注意,我们的目标是支持 ubuntu 16.04、ROS-kinetic、C++11、Python 2.7*
*如果解决方案提供了迁移到 Python 3.6 的合理性,您将获得奖励积分!
更新
如果我从 yaml 加载一个 dict 配置(如 this post on logging best practices 中所述,我可以为 ROS 指定处理程序和记录器。但是使用下面的 yaml,我会向控制台收到重复的 rospy 日志消息,一个是标准的 rospy 日志格式,另一个是其他按我指定的格式。为什么?
version: 1
disable_existing_loggers: True
formatters:
my_std:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
datefmt: "%Y/%m/%d %H:%M:%S"
handlers:
console:
class: logging.StreamHandler
formatter: my_std
level: DEBUG
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: my_std
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
rosconsole:
class: rosgraph.roslogging.RosStreamHandler
level: DEBUG
formatter: my_std
colorize: True
loggers:
my_module:
level: INFO
handlers: [console]
propagate: no
rosout:
level: INFO
handlers: [rosconsole]
propagate: yes
qualname: rosout
root:
level: INFO
handlers: [console, info_file_handler, rosconsole]
你可以使用为ROS-Python制作的rospy.loginfo()
和为ROS-C++制作的ROS_INFO()
并将它们集成到一个场景中。为此,请执行以下操作:
$ roscd log
你会看到几个.log
个文件,然后使用下面的命令来跟踪它们。
$ tail -f <logfile-name.log>
[更新]
此外,您可以订阅 /rosout
主题或回显此主题 ($ rostopic echo /rosout
)。
Reference.
这个配置 yaml 可以解决问题:
version: 1
disable_existing_loggers: True
formatters:
my_std:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
datefmt: "%Y/%m/%d %H:%M:%S"
handlers:
console:
class: logging.StreamHandler
formatter: my_std
level: DEBUG
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: my_std
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
loggers:
__main__:
level: DEBUG
handlers: [console]
propagate: no
rosout:
level: INFO
propagate: yes
qualname: rosout
root:
level: INFO
handlers: [console, info_file_handler]
并加载它,
import logging
import yaml
if os.path.exists(config_path):
with open(config_path, 'rt') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
在 python 中,我使用标准记录器库并将记录器重新映射到 ROS_LOG。请注意,如果您尝试使用 ros_stream_handler.setFormatter.
,ROS_LOG 将不遵守格式
import logging
from rosgraph.roslogging import RosStreamHandler as RosStreamHandler
ros_stream_handler = RosStreamHandler()
ros_stream_handler.setLevel(logging.DEBUG)
logger.addHandler(ros_stream_handler)
我有一个 Python 的代码库和 C++ 代码,包括大量使用 ROS。记录是在整个 Python 代码中完成的,同时 system logger and rospy logging -- 人为的例子:
import logging
import rospy
logging.basicConfig(level=logging.INFO)
LOG = logging.getLogger(__name__)
def run():
rospy.loginfo("This is a ROS log message")
LOG.info("And now from Python")
if __name__ == '__main__':
runt()
至于 C++ 代码,我们需要添加日志记录,可能使用 glog,但我愿意接受其他选项。
有没有办法将各种记录器集成到一个模块中? 理想情况下,用户可以在幕后做 my_logger = AwesomeLogger(level='info', output='my_logs.txt')
然后 AwesomeLogger
设置 Python 和 C++ 记录器,并将所有日志输出(包括来自 ROS)合并到干净的控制台消息输出文本文件中。
请注意,我们的目标是支持 ubuntu 16.04、ROS-kinetic、C++11、Python 2.7*
*如果解决方案提供了迁移到 Python 3.6 的合理性,您将获得奖励积分!
更新 如果我从 yaml 加载一个 dict 配置(如 this post on logging best practices 中所述,我可以为 ROS 指定处理程序和记录器。但是使用下面的 yaml,我会向控制台收到重复的 rospy 日志消息,一个是标准的 rospy 日志格式,另一个是其他按我指定的格式。为什么?
version: 1
disable_existing_loggers: True
formatters:
my_std:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
datefmt: "%Y/%m/%d %H:%M:%S"
handlers:
console:
class: logging.StreamHandler
formatter: my_std
level: DEBUG
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: my_std
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
rosconsole:
class: rosgraph.roslogging.RosStreamHandler
level: DEBUG
formatter: my_std
colorize: True
loggers:
my_module:
level: INFO
handlers: [console]
propagate: no
rosout:
level: INFO
handlers: [rosconsole]
propagate: yes
qualname: rosout
root:
level: INFO
handlers: [console, info_file_handler, rosconsole]
你可以使用为ROS-Python制作的rospy.loginfo()
和为ROS-C++制作的ROS_INFO()
并将它们集成到一个场景中。为此,请执行以下操作:
$ roscd log
你会看到几个.log
个文件,然后使用下面的命令来跟踪它们。
$ tail -f <logfile-name.log>
[更新]
此外,您可以订阅 /rosout
主题或回显此主题 ($ rostopic echo /rosout
)。
Reference.
这个配置 yaml 可以解决问题:
version: 1
disable_existing_loggers: True
formatters:
my_std:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
datefmt: "%Y/%m/%d %H:%M:%S"
handlers:
console:
class: logging.StreamHandler
formatter: my_std
level: DEBUG
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: my_std
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
loggers:
__main__:
level: DEBUG
handlers: [console]
propagate: no
rosout:
level: INFO
propagate: yes
qualname: rosout
root:
level: INFO
handlers: [console, info_file_handler]
并加载它,
import logging
import yaml
if os.path.exists(config_path):
with open(config_path, 'rt') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
在 python 中,我使用标准记录器库并将记录器重新映射到 ROS_LOG。请注意,如果您尝试使用 ros_stream_handler.setFormatter.
,ROS_LOG 将不遵守格式import logging
from rosgraph.roslogging import RosStreamHandler as RosStreamHandler
ros_stream_handler = RosStreamHandler()
ros_stream_handler.setLevel(logging.DEBUG)
logger.addHandler(ros_stream_handler)