Note: This tutorial assumes that you have completed the previous tutorials: ROS tutorials. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Logging with rospy
Description: Logging messages to rosout is easy with rospy and encouraged. When you are running many nodes, seeing the command-line output of your node gets very difficult. Instead, it is much easier to publish a debugging message to rosout and then view it with rqt_console / rxconsole. *console is "over-console" of ROS and lets you view and filter the logging messages from all ROS nodes.Tutorial Level: BEGINNER
Next Tutorial: rospy Makefile
Before we look at how to use this in rospy, you should probably review the rosout verbosity levels so you know how to use the various log levels properly. It's important to use the correct level as others will see these messages as well and need to understand them properly.
rospy API
rospy has several methods for writing log messages, all starting with "log":
rospy.logdebug(msg, *args) rospy.logwarn(msg, *args) rospy.loginfo(msg, *args) rospy.logerr(msg, *args) rospy.logfatal(msg, *args)
These levels have a one-to-one correspondence to the rosout verbosity levels. There are four potential places a log message may end up depending on the verbosity level:
- stdout: loginfo
- stderr: logerr, logfatal, logwarn (ROS 0.9)
- your Node's log file: all
the /rosout Topic: loginfo, logwarn, logerr, logfatal
NOTE: Your messages will not appear on the /rosout Topic until your Node is fully initialized, so you may not see the initial messages. When you see a message in stdout No handlers could be found for logger "rosout", it's likely either the initialization hasn't finished, or you forgot to call rospy.init_node.
Your Node's log file will be in ROS_ROOT/log or ~/.ros/log, unless you override it with the ROS_LOG_DIR environment variable.
If you wish to see logdebug messages on /rosout, you can pass in the log_level parameter to init_node(), e.g.:
rospy.init_node('my_node', log_level=rospy.DEBUG)
Each rospy.log*() method can take in a string msg. If msg is a format string, you can pass in the arguments for the string separately, e.g.
rospy.logerr("%s returned the invalid value %s", other_name, other_value)
Example
Here's a quick example with a talker Node (a runnable entire code example is available here):
On Line 4 and 8 you can see the calls to rospy.loginfo(). These also print to screen as the loginfo also writes to stdout, so you should use it as a drop-in replacement for print.
One of the quick ways to see the Messages on /rosout is to use rostopic echo:
$ rostopic echo rosout --- header: seq: 1 stamp: 1247874193220264911 frame_id: 0 level: 2 name: /talker-13716-1247874192981 msg: hello world 1247874193.14 file: function: line: 0 topics: ['/time', '/chatter', '/rosout']
A better way to see these Messages is to use rqt_console (rxconsole before ROS Groovy), which lets filter and sort the messages appropriately.
Next tutorial: rospy_tutorials/Tutorials/Makefile.