日志系统和log4cxx

我们都知道ROS有默认的日志工具,用rosclean check检查日志所在路径和占用的大小,一般放在~/.ros/log,可以定义环境变量ROS_LOG_DIR改变日志存放的位置。rosclean purge可以清除日志,日志记录了所有的输出信息

应该就是rosconsole这个东西,它在启动时会加载$ROS_ROOT/config/rosconsole.config作为配置文件。另外可以定义配置文件供log4cxx使用,定义环境变量ROSCONSOLE_CONFIG_FILE为配置文件的路径。

一般做成launch文件,这样使用方便,编辑灵活:

1
2
3
4
5
<launch>
<env name="ROSCONSOLE_CONFIG_FILE"
value="$(find log_test)/setting.conf"/>
<node pkg="log_test" type="log_test" name="log_test" output="screen"/>
</launch>

package和可执行文件的名称都是log_test,配置文件由环境变量指定路径。

日志消息有三个不同的目的地:控制台,话题/rosout,日志文件。相比于控制台输出,rosout话题输出的主要作用是它在一个流中包含了系统中所有节点的日志消息。查看话题/rosout中的消息:

1
rostopic echo /rosout

也可以使用图形界面查看:rqt_consolerqt_console订阅的是话题/rosout_agg,话题由节点rosout收集话题/rosout聚合之后发布。

我写的一个节点订阅了5个话题,这几个话题是单片机发布的,在回调函数里输出对应消息类型的变量信息,日志信息最终在output.txt中,注意输出信息是用逗号隔开,这样用EXCEL打开可以将各部分隔开,实现表格效果:

ROS_INFO中文显示问号

显然这是编码问题,在ROS_INFO之前加入下面代码中的一行:

1
2
3
// 设置区域为中文,或者直接取所有枚举的并集,不必仔细研究了
// setlocale(LC_CTYPE, "zh_CN.utf8");
setlocale(LC_ALL, "");

自定义ROS日志的格式

默认的日志输出是这样的:

1
2
[ INFO] [1556115082.590417546]: msg:91
[ INFO] [1556115083.591389486]: msg:12

其实看源码rosconsole.cpp可知ROS日志就是基于log4cxx。我们可以修改环境变量ROSCONSOLE_FORMAT定制格式,格式包括以下选项:
1
2
3
4
5
6
7
8
9
severity
message
time
thread
logger
file
line
function
node

看一下rosconsole.cpp源码部分:

1
2
3
4
5
6
7
8
9
const char* g_format_string = "[${severity}] [${time}]: ${message}";
Formatter g_formatter;
format_string = getenv("ROSCONSOLE_FORMAT");
if (format_string)
{
g_format_string = format_string;
}

g_formatter.init(g_format_string);

从中可以发现源码里先给了个默认格式,我们也可以针对环境变量自己设置格式.

网上有人问能不能自定义日志信息的颜色,结果发现在函数Formatter::print里,各等级的日志信息的颜色已经写死了,比如levels::Fatal对应COLOR_RED,所以不能自定义了.

根据环境变量,我们可以这样修改:

1
export ROSCONSOLE_FORMAT='[${severity}][${node}] [${function}] line_${line}  ${message}'

只保留等级、节点名、函数、行号、信息,结果是这样的:
1
2
3
[ INFO][/Pub] [main] line_19  msg:13
[ INFO][/Pub] [main] line_19 msg:37
[ INFO][/Pub] [main] line_19 msg:73

界面日志工具

ROS提供两个带界面的日志工具:rqt_console和rqt_logger_level

命令如下:

1
2
rosrun rqt_console rqt_console
rosrun rqt_logger_level rqt_logger_level

使用很简单,就不详细解释了




参考:
rosconsole
log4j.properties配置详解
ROS 程序编写之日志
rosconsole.cpp