在 ROS2 开发与部署过程中,日志功能是调试和故障排查的重要工具,但默认配置下日志无大小限制的特性,可能导致日志文件失控膨胀 —— 笔者曾遇到某项目中hardware_simulator_node节点生成 156G 日志文件,直接占满 234G 根分区的极端情况。本文将从 “定位问题→清理日志→长效防护” 三个维度,详解 ROS2 日志的治理方案。

一、第一步:精准定位超大日志文件

日志膨胀的核心是 “看不见的大文件”,需先通过命令定位问题文件:

1. 全局扫描大文件

通过find命令查找系统中大于 100M 的文件(重点关注 ROS2 日志目录):

bash

运行

# 查找所有大于100M的文件,按大小排序(排除权限错误)
find / -type f -size +100M 2>/dev/null | xargs ls -lh | sort -rhk5

ROS2 日志默认存储路径为:

  • root 用户/root/.ros/log/
  • 普通用户~/.ros/log/

2. 聚焦 ROS2 日志目录

直接查看 ROS2 日志目录的大小:

bash

运行

# 查看root用户的ROS2日志占用
du -sh /root/.ros/log/

# 普通用户则执行
du -sh ~/.ros/log/

二、第二步:彻底清理日志并释放空间

找到超大日志文件后,需分 “删除文件” 和 “释放句柄” 两步操作,避免 “删了文件但空间没释放” 的坑。

1. 删除超大日志文件

直接删除确认无用的日志文件(以 root 用户为例):

bash

运行

# 删除单个超大日志文件
rm -f /root/.ros/log/hardware_simulator_node_23540_1764047783025.log

# 批量删除大于100M的ROS2日志
find /root/.ros/log -type f -size +100M -delete

2. 释放被进程占用的文件句柄

若删除文件后磁盘空间仍未恢复,大概率是ROS2 节点仍持有已删除文件的句柄。通过lsof排查:

bash

运行

# 查找被删除但仍被进程占用的ROS2日志文件
lsof | grep deleted | grep -i ros

输出示例:

plaintext

hardware_ 23540 root 3w REG 8,2 167465906176 /root/.ros/log/xxx.log (deleted)

此时需终止对应的 ROS2 节点进程(替换为实际 PID):

bash

运行

# 强制终止进程(释放文件句柄)
kill -9 23540

# 或通过进程名批量终止
pkill -9 hardware_simulator_node

3. 验证清理效果

清理完成后,通过df -h查看磁盘空间是否恢复:

bash

运行

df -h /

三、第三步:长效防护 —— 避免日志再次膨胀

清理只是应急手段,真正的解决方案是从 “代码、配置、运行时” 三层限制日志输出。

1. 代码层面:降低日志级别,减少冗余输出

ROS2 日志分为DEBUG/INFO/WARN/ERROR/FATAL五级,建议将非关键日志降级为DEBUG(默认不输出):

cpp

运行

// 非关键提示改为DEBUG(默认不打印)
RCLCPP_DEBUG(this->get_logger(), "已发布打印机开始信号");

// 仅保留错误/警告级别的关键日志
RCLCPP_WARN(this->get_logger(), "无效命令,请输入print_start/exit");
RCLCPP_ERROR(this->get_logger(), "发布信号失败!");

2. 系统层面:配置 logrotate 自动轮转日志

创建logrotate配置文件,让系统自动切割、压缩、删除旧日志:

bash

运行

# 编辑ROS2日志轮转配置
nano /etc/logrotate.d/ros2_logs

写入以下内容(适配 root 用户,普通用户需修改路径):

plaintext

/root/.ros/log/*.log {
    size 50M         # 日志达到50M即轮转
    rotate 2         # 仅保留2份旧日志
    compress         # 压缩旧日志
    copytruncate     # 截断原文件(不中断节点日志输出)
    missingok        # 忽略不存在的文件
    notifempty       # 空文件不轮转
}

测试配置生效:

bash

运行

logrotate -f /etc/logrotate.d/ros2_logs

3. 运行时层面:强制限制日志级别

启动 ROS2 节点时,通过参数强制仅输出ERROR级别日志(彻底杜绝冗余输出):

bash

运行

# 仅输出ERROR级别日志
ros2 run your_package hardware_simulator_node --ros-args --log-level ERROR

# 调试时可临时改为WARN级别
ros2 run your_package hardware_simulator_node --ros-args --log-level WARN

四、总结:日志治理的核心逻辑

ROS2 日志膨胀的本质是 “无限制输出 + 无自动清理”,治理需遵循 “预防大于治理” 的原则:

  1. 应急处理:定位大文件→删除文件→释放句柄;
  2. 长效防护:代码降级日志 + 系统自动轮转 + 运行时限制级别。

通过这套组合方案,既能解决当下的磁盘爆满问题,又能从根源上避免日志失控,让 ROS2 节点稳定运行的同时,不再成为磁盘空间的 “吞噬者”。

Logo

立足具身智能前沿赛道,致力于搭建全球化、开源化、全栈式技术交流与实践共创平台。

更多推荐