1. ROS2日志系统概述:日志级别、日志格式、日志存储位置
做自动驾驶系统这些年,我调试过不少奇奇怪怪的问题。说实话,日志系统是我最依赖的工具之一。没有它,很多bug根本无从下手。ROS2的日志系统比ROS1强了不少,今天我们就来好好聊聊。
1.1 日志级别:从DEBUG到FATAL
ROS2定义了5个日志级别。嗯,其实严格来说是6个,但有个特殊的我们后面再说。先看这张图:
每个级别都有明确的用途。我个人习惯这样用:
| 级别 | 含义 | 我常用的场景 |
|---|---|---|
| DEBUG | 调试信息 | 传感器原始数据、中间变量值 |
| INFO | 普通信息 | 节点启动成功、参数加载完成 |
| WARN | 警告 | 传感器数据偶尔丢失、参数超出推荐范围 |
| ERROR | 错误 | CAN总线通信失败、TF树断裂 |
| FATAL | 致命错误 | 内存耗尽、核心算法崩溃 |
💡 小技巧: 调试阶段把日志级别设成DEBUG,上线前改成INFO或WARN。我在项目里吃过亏——DEBUG日志太多,导致系统响应变慢。
1.2 日志格式:一眼看懂关键信息
ROS2的日志格式其实挺讲究的。你看这条日志:
[INFO] [1700000000.123456789] [my_autonomous_car]: Lidar node started successfully.
拆开来看,它包含三个部分:
- 日志级别:用方括号括起来,比如
[INFO] - 时间戳:秒.纳秒 格式,精确到纳秒级别
- 节点名称:告诉你是哪个节点发的
- 消息内容:冒号后面的就是具体信息
你想想看,在自动驾驶系统里,时间精度有多重要?我曾经排查过一个传感器时间不同步的问题,就是靠日志里的纳秒级时间戳找到的。嗯,这个后面会细讲。
🔑 关键点: 日志格式可以通过环境变量自定义。比如
RCUTILS_CONSOLE_OUTPUT_FORMAT 可以调整显示顺序。
1.3 日志存储位置:文件都去哪了?
ROS2的日志默认存在 ~/.ros/log 目录下。但说实话,这个位置在生产环境里不太够用。我一般会改到专门的日志分区。
来看一下典型的日志目录结构:
~/.ros/log/
├── latest -> /home/user/.ros/log/2024-01-15-10-30-00-123456
├── 2024-01-15-10-30-00-123456/
│ ├── node_1.log
│ ├── node_2.log
│ └── ...
└── 2024-01-15-11-00-00-654321/
├── node_1.log
└── ...
这里有个很贴心的设计:latest 是个软链接,永远指向最近一次运行的日志目录。我在调试时经常用这个,省得翻目录。
⚠️ 注意: 日志文件会不断增长。我曾经遇到过磁盘写满导致系统崩溃的情况。建议设置日志轮转,或者挂载单独的日志分区。
1.4 如何设置日志级别?
有两种方式。第一种是代码里设置:
// C++ 示例
rclcpp::Logger logger = rclcpp::get_logger("my_node");
rclcpp::set_logger_level(logger, rclcpp::LoggerLevel::Debug);
// Python 示例
import rclpy
logger = rclpy.logging.get_logger('my_node')
logger.set_level(rclpy.logging.LoggingSeverity.DEBUG)
第二种是通过命令行:
ros2 run my_package my_node --ros-args --log-level debug
我个人更推荐第二种。为什么?因为不用改代码,上线时直接改成 --log-level info 就行。你想想看,改代码还要重新编译,多麻烦。
1.5 避坑指南
🛠️ 我曾经踩过的坑:
- DEBUG日志里打印了敏感数据(比如GPS坐标),结果日志文件被其他人看到了。建议生产环境关掉DEBUG。
- 日志文件没有轮转,导致一个文件几十GB。用
logrotate工具可以解决。 - 多个节点写同一个日志文件,导致内容交错。ROS2默认每个节点一个文件,这个设计很合理。
好了,关于ROS2日志系统的基本概念就这些。记住一句话:日志是你的第一道防线。遇到问题先看日志,别急着改代码。这个习惯能帮你省下大量时间。
可可精品资料库