ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
16

ROS log file change of time-stamping format

asked 2014-06-25 04:26:17 -0600

Default format of time stamping in ROS logs are in unix time format i.e [ INFO] [1403686233.193723830]: i want this to be changed to ISO 8601 format i.e 2014-06-19T19:12:32Z

i found a option to disable it using export ROSCONSOLE_FORMAT but not able to change format.

how can i do this ?

edit retag flag offensive close merge delete

Comments

1

I am interested in this as well. Did you find a solution?

SR gravatar image SR  ( 2014-11-21 04:49:46 -0600 )edit

I want that, too!

Stephan gravatar image Stephan  ( 2015-09-25 04:31:55 -0600 )edit
1

It looks like it just uses the output stream operator of ros::Time : https://github.com/ros/ros_comm/blame...

Stephan gravatar image Stephan  ( 2015-09-25 04:35:23 -0600 )edit

Did you find a solution? I am also looking for it.

Orchaldir gravatar image Orchaldir  ( 2016-04-22 05:46:23 -0600 )edit

Any update on this? I too would like this option

shoemakerlevy9 gravatar image shoemakerlevy9  ( 2017-04-10 14:43:05 -0600 )edit

I've been looking for this too. This seems like a significant flaw in the logging system, I am going nuts looking through log files constantly translating the timestamps to find out when things really occurred.

knxa gravatar image knxa  ( 2017-09-26 02:02:54 -0600 )edit

It would be nice if were possible to use bash to process the console string, like put a date -d@${time} to convert the time or ${${file}: -20} to lop off all but the last 20 characters of the file... though maybe that would slow down console output a lot.

lucasw gravatar image lucasw  ( 2019-08-21 19:15:39 -0600 )edit
1

It is fixed in the ROS Noetic: http://wiki.ros.org/rosconsole#Change...

longlongago gravatar image longlongago  ( 2020-12-10 21:32:11 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
5

answered 2018-01-15 17:45:03 -0600

Cerin gravatar image

updated 2019-08-21 19:12:19 -0600

lucasw gravatar image

After much digging around, I found this is possible, but the current logging architecture in ROS Kinetic makes it quite clunky. The problem is that even though ROS uses Python's logging module and provides its own user-customizable logging configuration file, the custom log stream handler defined in rosgraph.roslogging.RosStreamHandler completely ignores the formatting options specified in the configuration file, and hard-codes its own format. Although this is not good, it can still be overridden, but it's a bit more work.

Here's what I did to change the log's timestamp to a datetime.

  1. Define your own logging configuration file by copying the default at /opt/ros/kinetic/share/rosgraph/conf/python_logging.conf and pasting it to somewhere in your project folder (preferrably a "conf" directory).

    test

  2. Create a "logging.py" somewhere in your project folder (preferrably a Python package) and subclass RosStreamHandler like:

    from __future__ import absolute_import
    import os
    import time
    import logging
    import sys
    import datetime
    
    from rosgraph.roslogging import RosStreamHandler as _RosStreamHandler, _logging_to_rospy_names, _defaultFormatter
    
    class RosStreamHandler(_RosStreamHandler):
    
        def emit(self, record):
            level, color = _logging_to_rospy_names[record.levelname]
            record_message = _defaultFormatter.format(record)
            msg = os.environ.get('ROSCONSOLE_FORMAT', '[${severity}] [${time}]: ${message}')
            msg = msg.replace('${severity}', level)
            msg = msg.replace('${message}', str(record_message))
            msg = msg.replace('${walltime}', '%f' % time.time())
            msg = msg.replace('${thread}', str(record.thread))
            msg = msg.replace('${logger}', str(record.name))
            msg = msg.replace('${file}', str(record.pathname))
            msg = msg.replace('${line}', str(record.lineno))
            msg = msg.replace('${function}', str(record.funcName))
            try:
                from rospy import get_name
                node_name = get_name()
            except ImportError:
                node_name = '<unknown_node_name>'
            msg = msg.replace('${node}', node_name)
            time_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            msg = msg.replace('${time}', time_str)
            msg += '\n'
            if record.levelno < logging.WARNING:
                self._write(sys.stdout, msg, color)
            else:
                self._write(sys.stderr, msg, color)
    
  3. In your custom python_logging.conf find the line that says:

     class=rosgraph.roslogging.RosStreamHandler
    

    and change it to point to your new class. If your project's Python package is called "myrobot", and you created logging.py directly inside that, this would look like:

    class=rosgraph.logging.RosStreamHandler
    
  4. Now apply it. To test this, I created a simple test_node.py that looks like:

    #!/usr/bin/env python
    import time
    import inspect
    import rospy
    rospy.init_node('test_node')
    while 1:
        rospy.loginfo("Waiting for 1 second...")
        time.sleep(1)
    

    and associated launch file. To use your custom logging configuration, export the ROS_PYTHON_LOG_CONFIG_FILE environment variable when running any node like:

    export ROS_PYTHON_LOG_CONFIG_FILE=myrobot/config/logging.conf; roslaunch myrobot test_node.launch
    

The output I get is:

[INFO] [2018-01-15 18:36:55]: Waiting for 1 second...
[INFO] [2018-01-15 18:36:56]: Waiting for 1 second...
[INFO] [2018-01-15 18:36:57]: Waiting for 1 second...
[INFO] [2018-01-15 18:36:58]: Waiting for 1 second...

Now clearly, this is a relatively large amount of work to change something relatively minor. Hopefully this is fixed in the next ROS release so it's a lot easier to customize.

edit flag offensive delete link more

Comments

1

+1 for showing your solution, but:

Hopefully this is fixed in the next ROS release

the chances of that happening will be infinitely larger if someone contributes the 'fix'. Perhaps that someone could be you?

gvdhoorn gravatar image gvdhoorn  ( 2018-01-16 02:49:51 -0600 )edit
1

I'll consider it. I've submitted a few pull requests before to fix bugs I've found, and they've always been ignored or rejected, which is really disheartening. I'm happy to contribute, but I also don't want to waste my time.

Cerin gravatar image Cerin  ( 2018-01-26 10:33:11 -0600 )edit
1

Working with an open-source community can be difficult, I agree. It helps if you include maintainers/reviewers in your development process though: that way you can avoid having to redo things because of design decisions that you made that the maintainer isn't comfortable merging.

gvdhoorn gravatar image gvdhoorn  ( 2018-01-27 04:50:15 -0600 )edit

Also: changes to core components -- with a lot of history, and a large installed base -- are under extra scrutiny, as they can have a large impact if something is not up to standards. Haphazerdly introducing changes to components such as the logging systems should be avoided.

gvdhoorn gravatar image gvdhoorn  ( 2018-01-27 04:51:39 -0600 )edit

I assume that a similar change needs to be made for roscpp?

Stephan gravatar image Stephan  ( 2018-07-06 03:17:14 -0600 )edit

it is fixed in ROS Noetic: http://wiki.ros.org/rosconsole#Change...

longlongago gravatar image longlongago  ( 2020-12-10 21:33:09 -0600 )edit

One small suggestion, there is already a .isoformat() method for datetime objects.

Replacement line that is closest to OP requested format (no trailing Z): time_str = datetime.datetime.now().replace(microsecond=0).isoformat()

with space (can be any single char separator) between date and time: time_str = datetime.datetime.now().replace(microsecond=0).isoformat(sep=' ')

with microseconds (remove .replace(microsecond=0)): time_str = datetime.datetime.now().isoformat()

mpsbarra gravatar image mpsbarra  ( 2021-10-20 19:26:52 -0600 )edit
0

answered 2021-12-30 05:33:39 -0600

jason_swee gravatar image

For anyone still interested about this question... The solution present seems to only work for rospy. For roscpp, a workaround which is not so pretty (though quite easy) but you can actually overwrite and undef then define the rosconsole macros, and append a timestamp to its __VA__ or args.

edit flag offensive delete link more
-1

answered 2018-03-30 12:52:31 -0600

You can also just export a format string:

export ROSCONSOLE_FORMAT='[${severity}] [${time} ${node}] [${file}:${function}:${line}]: ${message}'
edit flag offensive delete link more

Comments

2

I explicitly mentioned ROSCONSOLE_FORMAT doesn't work in my question... Your example does not change the formatting of the time component.

Cerin gravatar image Cerin  ( 2018-03-30 17:35:25 -0600 )edit

Question Tools

4 followers

Stats

Asked: 2014-06-25 04:26:17 -0600

Seen: 6,224 times

Last updated: Dec 30 '21