日志和日志记录器配置
概述
ROS 2 中的日志子系统旨在向各种目标发送日志信息,包括
连接控制台(如果已连接控制台)
记录磁盘上的文件(如果本地存储可用)
致
/rosout
关于 ROS 2 网络的主题
默认情况下,ROS 2 节点的日志信息将发送到控制台(stderr)、磁盘上的日志文件和 /rosout
ROS 2 网络上的主题。所有目标都可以按节点单独启用或禁用。
本文档的其余部分将介绍日志子系统背后的一些想法。
严重程度
日志信息有与之相关的严重性级别: DEBUG
, 信息
, 警告
, 错误
或 致命
按升序排列。
日志记录器只会处理严重性达到或高于为日志记录器选择的指定级别的日志信息。
每个节点都有一个与之关联的日志记录器,该日志记录器会自动包含节点名称和命名空间。如果节点的名称从外部重新映射为与源代码中定义的名称不同的名称,则会反映在日志记录器名称中。还可以创建使用特定名称的非节点记录仪。
记录仪名称代表一种层次结构。如果名为 "abc.def "的日志记录器的级别未设置,它将服从名为 "abc "的父日志记录器的级别;如果该级别也未设置,则将使用默认日志记录器级别。当日志记录器 "abc "的级别发生变化时,其所有后代(如 "abc.def"、"abc.ghi.jkl")的级别都将受到影响,除非它们的级别已明确设置。
应用程序接口
这些是 ROS 2 日志基础架构的最终用户应该使用的 API,按客户端库划分。
rclcpp_{debug,info,warn,error,fatal}
- 每击中此行一次,就输出给定的 printf 样式的信息rclcpp_{debug,info,warn,error,fatal}_once
- 仅在首次击中此行时输出给定的 printf 样式的信息rclcpp_{debug,info,warn,error,fatal}_expression
- 只有当给定表达式为真时,才输出给定的 printf 样式的信息rclcpp_{debug,info,warn,error,fatal}_function
- 只有在给定函数返回 true 时,才输出给定的 printf 样式的信息rclcpp_{debug,info,warn,error,fatal}_skipfirst
- 输出给定的 printf 样式的信息,但第一次点击这一行时除外rclcpp_{debug,info,warn,error,fatal}_throttle
- 以不超过给定速率(整数毫秒)的速度输出给定的打印格式信息rclcpp_{debug,info,warn,error,fatal}_skipfirst_throttle
- 以不超过给定速率(整数毫秒)的速度输出给定的 printf 样式的信息,但跳过第一个rclcpp_{debug,info,warn,error,fatal}_stream
- 每击中此行一次,就输出给定的 C++ 流式信息rclcpp_{debug,info,warn,error,fatal}_stream_once
- 仅在首次碰到此行时输出给定的 C++ 流式信息rclcpp_{debug,info,warn,error,fatal}_stream_expression
- 只有当给定表达式为真时,才输出给定的 C++ 流式信息rclcpp_{debug,info,warn,error,fatal}_stream_function
- 仅在给定函数返回 true 时才输出给定的 C++ 流式信息rclcpp_{debug,info,warn,error,fatal}_stream_skipfirst
- 输出给定的 C++ 流式信息,但该行第一次被击中时除外rclcpp_{debug,info,warn,error,fatal}_stream_throttle
- 以不超过给定速率(整数毫秒)的速度输出给定的 C++ 流式信息rclcpp_{debug,info,warn,error,fatal}_stream_skipfirst_throttle
- 以不超过给定速率(整数毫秒)的速度输出给定的 C++ 流式信息,但跳过第一个
上述每个应用程序接口都需要一个 rclcpp::Logger
对象作为第一个参数。通过调用 node->get_logger()
(建议),或通过构建一个独立的 rclcpp::Logger
反对
rcutils_logging_set_logger_level
- 将特定日志记录器名称的日志记录级别设置为给定的严重性级别rcutils_logging_get_logger_effective_level
- 给定日志记录器名称,返回日志记录器级别(可能未设置)
logger.{debug,info,warning,error,fatal}
- 将给定的 Python 字符串输出到日志基础设施。调用接受以下关键字参数来控制行为:节流阀持续时间
- 如果不是 "无",节流间隔的持续时间,以浮点秒为单位skip_first
- 如果为 True,则输出除首次点击此行之外的所有信息一次
- 如果为 True,则只在第一次点击这一行时输出信息
rclpy.logging.set_logger_level
- 将特定日志记录器名称的日志记录级别设置为给定的严重性级别rclpy.logging.get_logger_effective_level
- 给定日志记录器名称,返回日志记录器级别(可能未设置)
配置
因为 rclcpp
和 rclpy
使用相同的底层日志基础设施,配置选项也相同。
环境变量
以下环境变量可控制 ROS 2 记录仪的某些方面。对于每个环境设置,请注意这是一个进程范围的设置,因此适用于该进程中的所有节点。
ROS_LOG_DIR
- 控制用于将日志信息写入磁盘的日志目录(如果启用)。如果非空,则使用该变量中指定的确切目录。如果为空,则使用ROS_HOME
环境变量来构建一个$ROS_HOME/.log
.在所有情况下~
字符会扩展到用户的 HOME 目录。ROS_HOME
- 控制各种 ROS 文件(包括日志和配置文件)的主目录。在日志记录中,该变量用于构建日志文件目录的路径。如果非空,则使用该变量的内容作为 ROS_HOME 路径。在任何情况下~
字符会扩展到用户的 HOME 目录。rcutils_logging_use_stdout
- 控制信息输出到哪个数据流。如果未设置或为 0,则使用 stderr。如果为 1,则使用 stdout。rcutils_logging_buffered_stream
- 控制日志记录流(在rcutils_logging_use_stdout
)应该是行缓冲还是未缓冲。如果未设置,则使用流的默认值(通常,stdout 为行式缓冲,stderr 为非缓冲)。如果设置为 0,则强制使用非缓冲流。如果为 1,则强制使用行缓冲流。rcutils_colorized_output
- 控制输出信息时是否使用颜色。如果未设置,则根据平台和控制台是否为 TTY 自动确定。如果为 0,则强制禁止使用颜色输出。如果为 1,则强制启用输出时使用颜色。rcutils_console_output_format
- 控制每条日志信息的输出字段。可用字段包括{严重性}
- 严重程度。名称
- 记录仪名称(可为空)。{信息}
- 日志信息(可能为空)。{function_name}
- 调用该函数的函数名(可能为空)。{文件名}
- 调用的文件名(可能为空)。{时间}
- 自纪元开始的时间(以秒为单位)。{时间为纳秒} .
- 自纪元开始的时间(纳秒)。{行号}
- 调用的行号(可能为空)。
如果没有给出格式,则默认为
[{严重性}] [{时间}] [{名}]: {信息}
使用。
节点创建
在初始化 ROS 2 节点时,可以通过节点选项来控制某些方面的行为。由于这些选项是按节点设置的,因此即使节点组成了一个进程,也可以对不同的节点进行不同的设置。
log_levels
- 此节点内组件的日志级别。可通过以下方式设置:玫瑰2 运行 演示节点 话匣子 --ros-args --日志级 通话者:=DEBUG
外部日志配置文件
- 用于配置后端日志记录器的外部文件。如果为空,将使用默认配置。请注意,该文件的格式是后端特定的(目前默认的 spdlog 后端日志记录器尚未实现)。可通过以下方式设置:玫瑰2 运行 演示节点 话匣子 --ros-args --日志配置文件 log-config.txt
log_stdout_disabled
- 是否禁用将日志信息写入控制台。可以通过以下方式实现:玫瑰2 运行 演示节点 话匣子 --ros-args --禁用--输出日志
log_rosout_disabled
- 是否禁用将日志信息写入/rosout
.这可以大大节省网络带宽,但外部观察员将无法监控日志记录。可以采用以下方法:玫瑰2 运行 演示节点 话匣子 --ros-args --禁用--输出日志
log_ext_lib_disabled
- 是否完全禁用外部日志记录器。这在某些情况下可能更快,但意味着日志不会写入磁盘。可以通过以下方式实现:玫瑰2 运行 演示节点 话匣子 --ros-args --禁用外部-lib-日志
日志子系统设计
下图显示了日志子系统的五个主要部分及其交互方式。

rcutils
rcutils
有一个日志实现,可以按照一定的格式来格式化日志信息(参见 配置
),并将这些日志信息输出到控制台。
rcutils
实现了一个完整的日志记录解决方案,但允许高层组件在依赖注入模型中将自己插入到日志记录基础架构中。当我们讨论 rcl
下面一层。
请注意,这是一个 每进程 因此,在此级别配置的任何内容都将影响整个流程,而不仅仅是单个节点。
rcl_logging_spdlog
rcl_logging_spdlog
实现 rcl_logging_interface
应用程序接口,从而为 rcl
层。特别是 rcl_logging_spdlog
实现获取格式化的日志信息,并使用 spdlog
图书馆,通常在 ~/.ros/log
(但这是可以配置的,参见 配置
同上)。
rcl
中的日志子系统 rcl
用途 rcutils
和 rcl_logging_spdlog
来提供大部分 ROS 2 日志服务。当收到日志信息时 rcl
决定将它们发送到哪里。日志信息主要可以在三个地方发送;单个节点可以启用其中的任意组合:
通过
rcutils
层次通过
rcl_logging_spdlog
层次致
/rosout
通过 RMW 层的 ROS 2 网络上的主题
rclcpp
这是 ROS 2 的主要 C++ 应用程序接口,位于 rcl
应用程序接口。在日志记录方面、 rclcpp
提供了 RCLCPP_
日志宏;见 应用程序接口
上面的完整列表。当其中一个 RCLCPP_
宏运行时,它会根据宏的严重性级别检查节点的当前严重性级别。如果宏的严重性级别大于或等于节点的严重性级别,信息将被格式化并输出到当前配置的所有位置。请注意 rclcpp
对日志调用使用全局互斥,因此同一进程中的所有日志调用最终都是单线程的。
rclpy
这是主要的 ROS 2 Python 应用程序接口,位于 rcl
应用程序接口。在日志记录方面、 rclpy
提供了 logger.debug
-式函数;见 应用程序接口
上面的完整列表。当其中一个 logger.debug
函数运行时,它会对照宏的严重性级别检查节点的当前严重性级别。如果宏的严重性级别大于或等于节点的严重性级别,信息将被格式化并输出到当前配置的所有位置。
记录使用情况
参见 rclcpp 日志演示 了解一些简单的例子。
参见 记录演示 例如使用