记录

参见 日志页面 了解可用功能的详细信息。

在代码中使用日志语句

基本日志记录

以下代码将从 ROS 2 节点输出日志信息,该节点位于 DEBUG 严重性:

// printf 风格
RCLCPP_DEBUG(网站->;get_logger(), "我的日志信息 %d";, 4);

// C++ 流风格
rclcpp_debug_stream(网站->;get_logger(), "我的日志信息"; <<; 4);

请注意,这两种情况下都不添加尾部换行符,因为日志基础设施会自动添加尾部换行符。

仅首次登录

以下代码将从 ROS 2 节点输出日志信息,该节点位于 信息 严重性,但仅限于第一次撞击:

// printf 风格
rclcpp_info_once(网站->;get_logger(), "我的日志信息 %d";, 4);

// C++ 流风格
rclcpp_info_stream_once(网站->;get_logger(), "我的日志信息"; <<; 4);

除第一次外的所有记录

以下代码将从 ROS 2 节点输出日志信息,该节点位于 警告 严重性,但不是第一次被击中:

// printf 风格
rclcpp_warn_skipfirst(网站->;get_logger(), "我的日志信息 %d";, 4);

// C++ 流风格
rclcpp_warn_stream_skipfirst(网站->;get_logger(), "我的日志信息"; <<; 4);

记录受阻

以下代码将从 ROS 2 节点输出日志信息,该节点位于 错误 严重程度,但每秒不得超过一次。

指定报文之间毫秒间隔的间隔参数应为整数数据类型,以便将其转换为 rcutils_duration_value_t (一个 int64_t):

// printf 风格
rclcpp_error_throttle(网站->;get_logger(), *网站->;获取时钟(), 1000, "我的日志信息 %d";, 4);

// C++ 流风格
rclcpp_error_stream_throttle(网站->;get_logger(), *网站->;获取时钟(), 1000, "我的日志信息"; <<; 4);

// 目前,使用 nanoseconds() 方法来使用现有的 rclcpp::Duration 值,请参见 https://github.com/ros2/rclcpp/issues/1929。
rclcpp_error_stream_throttle(网站->;get_logger(), *网站->;获取时钟(), msg_interval.纳秒()/1000000, "我的日志信息"; <<; 4);

除第一次外,其他所有记录都被节流

以下代码将从 ROS 2 节点输出日志信息,该节点位于 DEBUG 严重性,每秒不超过一次,跳过第一次撞击:

// printf 风格
rclcpp_debug_skipfirst_throttle(网站->;get_logger(), *网站->;获取时钟(), 1000, "我的日志信息 %d";, 4);

rclcpp_debug_skipfirst_throttle(网站->;get_logger(), *网站->;获取时钟(), 1000, "我的日志信息"; <<; 4);

记录演示

在此 演示可显示不同类型的日志调用,并可在本地和外部配置不同日志记录器的严重程度。

开始演示:

玫瑰2 运行 日志演示 日志_演示_主

随着时间的推移,您将看到各种不同属性的日志调用输出。开始时,您只能看到严重性为 信息 及以上 (警告, 错误, 致命).请注意,第一条信息只会被记录一次,尽管每次迭代都会到达该行,因为这是用于该信息的日志调用的属性。

日志目录配置

日志记录目录可通过两个环境变量进行配置: ROS_LOG_DIRROS_HOME.逻辑如下

  • 使用 $ROS_LOG_DIR 如果 ROS_LOG_DIR 已设置且不为空。

  • 否则,请使用 $ROS_HOME/log使用 ~/.ros 对于 ROS_HOME 如果未设置或为空。

例如,要将日志记录目录设置为 ~/my_logs:

出口 ROS_LOG_DIR=~/my_logs ros2 运行 日志演示 日志_演示_主

然后,您可以在 ~/my_logs/.

或者,您也可以设置 ROS_HOME 而日志记录目录将相对于该目录 ($ROS_HOME/log). ROS_HOME 的目的是供任何需要基本目录的文件使用。请注意 ROS_LOG_DIR 必须为未设置或空。例如 ROS_HOME 设为 ~/my_ros_home:

出口 ROS_HOME=~/my_ros_home ros2 运行 日志演示 日志_演示_主

然后,您可以在 ~/my_ros_home/log/.

记录仪级别配置:编程

重复 10 次后,记录仪的级别将设置为 DEBUG会导致记录更多信息。

其中一些调试信息会导致额外的函数/表达式被评估,而这些函数/表达式之前会被跳过,因为 DEBUG 日志调用未启用。请参见 源代码 有关所用调用的进一步解释,请参阅演示中的 rclcpp 日志文档,了解所支持的日志调用的完整列表。

记录仪级别配置:外部

ROS 2 节点有可用的服务,可在运行时从外部配置日志记录级别。这些服务默认为禁用。下面的代码展示了如何在创建节点时启用日志记录器服务。

// 创建一个启用了日志服务的节点
汽车 网站 = 标准::共享<;rclcpp::节点>;("NodeWithLoggerService";, rclcpp::节点选项().启用日志服务())

如果按上述配置运行其中一个节点,运行时会发现有两个服务 玫瑰2 服务 清单:

$ 玫瑰2 服务 列表 .../NodeWithLoggerService/get_logger_levels /NodeWithLoggerService/set_logger_levels ...
  • get_logger_levels

    使用此服务可获取指定记录仪名称的记录仪级别。

    运行 玫瑰2 服务 致电 以获取 NodeWithLoggerServicercl.

    $ 玫瑰2 服务 致电 /NodeWithLoggerService/get_logger_levels rcl_interfaces/srv/GetLoggerLevels '{names:["NodeWithLoggerService", "rcl"]}';
    
    请求人: 制造 要求: rcl_interfaces.srv.GetLoggerLevels_Request(姓名=['NodeWithLoggerService';, 'rcl';])
    
    response: rcl_interfaces.srv.GetLoggerLevels_Response(两级=[rcl_interfaces.msg.LoggerLevel(名字='NodeWithLoggerService';, 夷为平地=0), rcl_interfaces.msg.LoggerLevel(名字='rcl';, 夷为平地=0)])
    
  • 设置记录仪级别

    使用此服务可为指定的记录仪名称设置记录仪级别。

    运行 玫瑰2 服务 致电 的记录仪级别。 NodeWithLoggerServicercl.

    $ 玫瑰2 服务 致电 /NodeWithLoggerService/set_logger_levels rcl_interfaces/srv/SetLoggerLevels '{levels:[{name:"NodeWithLoggerService", level:20}, {name:"rcl", level:10}]}';
    
    请求人: 制造 要求: rcl_interfaces.srv.SetLoggerLevels_Request(两级=[rcl_interfaces.msg.LoggerLevel(名字='NodeWithLoggerService';, 夷为平地=20), rcl_interfaces.msg.LoggerLevel(名字='rcl';, 夷为平地=10)])
    
    响应:rcl_interfaces.srv.SetLoggerLevels_Response(成果=[rcl_interfaces.msg.SetLoggerLevelsResult(成功的=没错、 理由=''), rcl_interfaces.msg.SetLoggerLevelsResult(成功的=没错、 理由='')])
    

此外,还有演示代码展示如何通过记录仪服务设置或获取记录仪级别。

  • rclcpp: 演示代码

    $ 玫瑰2 运行 演示节点 使用记录仪服务
    
  • rclpy: 演示代码

    $ 玫瑰2 运行 演示节点 使用记录仪服务
    

警告

目前,存在以下限制 get_logger_levels设置记录仪级别 服务不是线程安全的。这意味着需要确保每次只有一个线程调用服务。请参阅 https://github.com/ros2/rcutils/issues/397

使用记录仪配置组件

响应记录仪配置请求的服务器是作为一个组件开发的,因此可以添加到现有的基于组合的系统中。例如,如果您正在使用 运行节点的容器要配置记录仪,您只需请求它额外加载 logging_demo::LoggerConfig 组件放入容器中。

例如,如果要调试 构成::谈话者 演示时,您可以像往常一样启动通话器:

外壳 1:

玫瑰2 运行 rclcpp_components 组件容器

外壳 2:

玫瑰2 组成部分 负荷 /ComponentManager 构成 构成::谈话者

然后,当你想启用调试日志时,加载 记录仪配置 组成部分:

外壳 2

玫瑰2 组成部分 负荷 /ComponentManager 日志演示 logging_demo::LoggerConfig

最后,通过寻址空名日志记录器,将所有未设置的日志记录器配置为调试严重性。请注意,已特别配置为使用特定严重性的日志记录器不会受到此调用的影响。

外壳 2:

玫瑰2 服务 致电 /config_logger logging_demo/srv/ConfigLogger "{logger_name: '', level:DEBUG}";

你应该会看到进程中先前未设置的日志记录器开始出现调试输出,包括来自 ROS 2 内核的调试输出。

记录仪级别配置:命令行

从 Bouncy ROS 2 版本开始,可以通过命令行配置未明确设置严重性的日志记录器的严重性级别。使用以下命令行参数重新启动演示程序:

玫瑰2 运行 日志演示 日志_演示_主 --ros-args --日志级 排错

这会将任何未设置日志记录器的默认严重性配置为调试严重性级别。你应该能看到来自演示本身和 ROS 2 内核的日志记录器的调试输出。

可通过命令行配置单个记录仪的严重性级别。使用以下命令行参数重新启动演示程序:

玫瑰2 运行 日志演示 日志_演示_主 --ros-args --日志级 logger_usage_demo:=排错

控制台输出格式

如果您想要更多或更少的冗长格式,可以使用 rcutils_console_output_format 环境变量。例如,要额外获取日志调用的时间戳和位置,可停止演示,然后在设置环境变量后重新启动:

出口 rcutils_console_output_format="[{严重性} {时间}] [{名称}]:{message} ({function_name}() at {file_name}:{line_number})";
玫瑰2 运行 日志演示 日志_演示_主

您会看到以秒为单位的时间戳以及函数名、文件名和行号与每条信息一起打印出来。 时间 "选项仅在 ROS 2 Bouncy 版本中支持。

rcutils_console_output_format 还支持以下转义字符语法。

转义字符语法

代表人物

\a

警报

\b

退格

\n

新线路

\r

回车

\t

横向标签

控制台输出着色

默认情况下,针对终端的输出是彩色的。如果要强制启用或禁用,可以使用 rcutils_colorized_output 环境变量。例如

出口 rcutils_colorized_output=0  # 1 为强迫
玫瑰2 运行 日志演示 日志_演示_主

你会发现调试、警告、错误和致命日志现在都没有着色。

备注

在 Linux 和 MacOS 中,强制着色输出意味着如果将输出重定向到文件,ansi 转义颜色代码就会出现在文件上。在 windows 中,着色方法依赖于控制台 API。如果强制着色,就会收到着色失败的警告。默认行为已检查输出是否为控制台,因此不建议强制着色。

控制台输出的默认数据流

在 Foxy 及其后续版本中,所有调试级别的输出默认都转到 stderr。可以通过设置 rcutils_logging_use_stdout 环境变量为 1.例如

出口 rcutils_logging_use_stdout=1

行缓冲控制台输出

默认情况下,所有日志输出都是非缓冲的。您可以通过设置 rcutils_logging_buffered_stream 环境变量为 1。例如

出口 rcutils_logging_buffered_stream=1

那就跑吧

玫瑰2 运行 日志演示 日志_演示_主

设置日志文件名前缀

默认情况下,日志文件名基于可执行文件名,后跟进程 ID 和文件创建时的系统时间戳。您可以使用 --日志文件名 命令行参数:

玫瑰2 运行 演示节点 话匣子 --ros-args --日志文件名 文件名

这将把日志文件名前缀配置为 文件名而不是可执行文件名(可执行文件名是 话匣子 在这种情况下)。