Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add named loggers to rospy #948

Merged
merged 1 commit into from
Jul 18, 2017

Conversation

ggallagher01
Copy link
Contributor

This change will create (named) child loggers under rospy.rosout. This allows for each named logger to have seperate verbosity setting, this will allow for two different verboisty settings for logging in a single node. Two named loggers can log to rosout at two different verbosity setings, which can help noisy debug logs.

Copy link
Member

@dirk-thomas dirk-thomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the patch fails to run the tests. Please iterate on this and run the tests locally.

@@ -142,20 +143,37 @@ def rospyerr(msg, *args):
def rospywarn(msg, *args):
"""Internal rospy client library warn logging"""
_rospy_logger.warn(msg, *args)

logdebug = logging.getLogger('rosout').debug
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables are public API and can't be changed without breaking compatibility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look at it, I included a bunch of different commit here by accident. I'm cleaning up now

@@ -109,7 +110,7 @@ def parse_rosrpc_uri(uri):
@raise ParameterInvalid: if uri is not a valid ROSRPC URI
"""
if uri.startswith(ROSRPC):
dest_addr = uri[len(ROSRPC):]
dest_addr = uri[len(ROSRPC):]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid any unrelated white space changes in your PR (even if the current file might be "ugly"). It makes backporting changes across branches much more difficult.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at the diff on the GitHub PR and update the PR to avoid any unnecessary changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I thought I got them, I'll fix it up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix this again, I think the file has mixed line endings and my editor is trying to be helpful

@ggallagher01 ggallagher01 force-pushed the rospy_named_loggers branch 2 times, most recently from f251821 to 14f6c53 Compare December 27, 2016 02:20
@ggallagher01 ggallagher01 force-pushed the rospy_named_loggers branch 2 times, most recently from f7d787a to ab08dff Compare January 10, 2017 19:44
@dirk-thomas
Copy link
Member

My previous comment still applies to the updated change. Please avoid any unrelated white space changes in your PR.

Copy link
Member

@dirk-thomas dirk-thomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def _get_digest(*args):
m = hashlib.md5()
for arg in args:
m.update(str(args))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this call update with arg instead of args?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it should be arg instead of args. I'll fix that up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using MD5 for this seems like overkill. What about something like hash(tuple(*args + [str(msg)]))?

(Python's hashdoesn't do the right thing, so you can't use it directly, see ros/genpy#73)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should work, we only want to know the content of the print has changed. I'll test it out tonight.

logfunc = getattr(rospy_logger, level)

if throttle:
caller_id = _frame_record_to_caller_id(inspect.stack()[1])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 1 still correct now that the function is one level more nested?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe 2 is correct now because of the one more level down, I'll verify and fix that up

mikepurvis added a commit to clearpathrobotics/ros_comm that referenced this pull request Jan 31, 2017
mikepurvis added a commit that referenced this pull request Jan 31, 2017
mikepurvis added a commit that referenced this pull request Jan 31, 2017
mikepurvis added a commit that referenced this pull request Feb 7, 2017
mikepurvis added a commit that referenced this pull request Feb 7, 2017
mikepurvis added a commit that referenced this pull request Feb 7, 2017
@ggallagher01
Copy link
Contributor Author

ggallagher01 commented Feb 9, 2017

I resolved all the white space conflicts that my editor injected. Is there a standard line ending that each file should follow? I see this core.py has mixed line endings. I should have unit tests up tomorrow, I have a test program that I used for develpoment I'll port to the test framework.

mikepurvis added a commit that referenced this pull request Feb 9, 2017
mikepurvis added a commit to clearpathrobotics/ros_comm that referenced this pull request Feb 10, 2017
mikepurvis added a commit that referenced this pull request Feb 10, 2017
try:
level = kwargs.pop('logger_level')
except KeyError:
level = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my curiosity, what does this achieve over, eg:

def _base_logger(msg, name=None, throttle=None, level=None, *args, **kwargs):
    rospy_logger = logging.getLogger('rosout')

    if name:
        rospy_logger = rospy_logger.getChild(name)

    logfunc = getattr(rospy_logger, level)

    if throttle:
        caller_id = _frame_record_to_caller_id(inspect.stack()[2])
        _logging_throttle(caller_id, logfunc, throttle, msg, *args)
    else:
        logfunc(msg, *args)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the function using default values in one iteration but I believe i started failing tests and decided to use the keyword arguments instead. I'll rerun the tests and see if I can remember why I switched to using keyword args instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking back through my testing, I had a test case where using the named arguments for name, throttle and level (like above) would interfer with variable length arguments. This happened when testing out code that was using the existing public API, the named variables would end up taking some of the values from the multi length arguments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh of course, that makes sense. In that case, maybe pass the default to pop rather than catching the exception. Eg:

def _base_logger(msg, *args, **kwargs):
    name = kwargs.pop('logger_name', None)
    throttle = kwargs.pop('logger_throttle', None)
    level = kwargs.pop('logger_level', None)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much cleaner, will change that

@ggallagher01 ggallagher01 force-pushed the rospy_named_loggers branch 2 times, most recently from e0cb90c to 71f587e Compare February 17, 2017 19:38
efernandez pushed a commit to clearpathrobotics/ros_comm that referenced this pull request Feb 23, 2017
mikepurvis added a commit that referenced this pull request Feb 24, 2017
mikepurvis added a commit that referenced this pull request Mar 2, 2017
mikepurvis added a commit that referenced this pull request Mar 28, 2017
@ggallagher01
Copy link
Contributor Author

I believe all the the comments have been resolved, please let me know if there is anything else needed

@ggallagher01 ggallagher01 force-pushed the rospy_named_loggers branch from ce667df to 664666d Compare May 10, 2017 02:10
@ggallagher01
Copy link
Contributor Author

cleaned up the review, looks better now. Tests are passing on my local machine.

@ggallagher01
Copy link
Contributor Author

Looks good now, white space should be fixed to only what I changed and tests are now passing.

@ggallagher01
Copy link
Contributor Author

ping @ros/ros_comm-maintainers

All comments I believe are resolved

@DLu
Copy link
Contributor

DLu commented Jul 7, 2017

👍

@dirk-thomas
Copy link
Member

dirk-thomas commented Jul 10, 2017

Sorry for the late response. This looks almost ready. Recently some concerns regarding performance came up though which have been addressed in #1091 for the other logging function. Can you please update the PR to use a similar approach. Thank you.

This will also need to be rebased.

@ggallagher01 ggallagher01 force-pushed the rospy_named_loggers branch from 422e9ec to 60e16b3 Compare July 14, 2017 14:08
…gers under rospy.rosout. This allows for each named logger to have seperate verbosity setting, this will allow for two different verboisty settings for logging in a single node. Two named loggers can log to rosout at two different verbosity setings, which can help noisy debug logs.
@dirk-thomas
Copy link
Member

Thank you for this new feature. Please consider adding some information to the wiki page to mention this to be available as of Lunar and post the link here for future readers.

@dirk-thomas dirk-thomas merged commit 309de11 into ros:lunar-devel Jul 18, 2017
@kartikmohta
Copy link
Contributor

This breaks the Location of the message shown in rqt_console. Now the location of the message is always shown to be core.py:_base_logger:163 instead of the user code location.

@dirk-thomas
Copy link
Member

This breaks the Location of the message shown in rqt_console. Now the location of the message is always shown to be core.py:_base_logger:163 instead of the user code location.

@ggallagher01 Can you please look into this.

@mikepurvis
Copy link
Member

I think the issue here is that we jump up two stack frames in the throttle case, but in the other case we need to jump up one frame (currently nothing):

    if throttle:
         caller_id = _frame_to_caller_id(inspect.currentframe().f_back.f_back)
         _logging_throttle(caller_id, logfunc, throttle, msg, *args)
     else:
         logfunc(msg, *args)

I can verify this and throw up a PR for it.

@mikepurvis
Copy link
Member

Okay, I did dig into this a little more, and it's not quite as simple— the code I pasted only has to do with identifying the caller for the purposes of enforcing throttling. The actual logic which identifies the caller was added only recently in #1043, see:

https://github.com/ros/ros_comm/blob/lunar-devel/tools/rosgraph/src/rosgraph/roslogging.py#L52-L80

It looks like this is a case where the underlying logic built into logging is basically doing the right thing as far as identifying call site, but since that API has been wrapped, it's now pointing at the wrapper rather than user code. AFAICT, there are a couple ways this could be handled:

Since the amount of wrapping is not always consistent:

  • Put a blacklist in findCaller (eg, if you see rospy/core.py, keep going, or if you see base_logger, keep going, etc).
  • In the partial and other pass-thru calls, curry in a number for how many steps out to take.

See some discussion here as well: https://stackoverflow.com/questions/19615876/showing-the-right-funcname-when-wrapping-logger-functionality-in-a-custom-class

@mikepurvis
Copy link
Member

Okay, I've opened #1141 with a potential fix, so we can discuss that and other options there.

@gavanderhoorn
Copy link
Contributor

gavanderhoorn commented Nov 8, 2017

This is a great addition, but wiki/rospy/Overview/Logging does not mention it. Is that an oversight? @ggallagher01: would you be willing to add that?

From rospy equivalent of ROS_*_NAMED on ROS Answes.

@ggallagher31
Copy link

I'll have some time this weekend to add this

@yli-cpr
Copy link
Contributor

yli-cpr commented Sep 20, 2018

I found that http://wiki.ros.org/rospy/Overview/Logging doesn't contain the features this commit adds. It may need to be updated.

Another confusing thing is that on the wiki page, rospy.log*() methods don't take kwargs. But it seems before this change, they did accept kwargs.

I am actually looking at the support of exc_info, one of the 2 kwargs that python Logger supports (the other is extra). See https://docs.python.org/2/library/logging.html.

This ticket probably broke the python logger's kwargs like exc_info, because it doesn't forward kwargs to the logger. Should rospy logging support exc_info and extra?

@mgrrx
Copy link
Contributor

mgrrx commented Sep 21, 2018

@yli-cpr checkout #1289 for the support of kwargs.

@dirk-thomas
Copy link
Member

I'll have some time this weekend to add this

I found that http://wiki.ros.org/rospy/Overview/Logging doesn't contain the features this commit adds. It may need to be updated.

@ggallagher31 Can you please follow up on this and add documentation about this feature to the wiki page.

@timonegk
Copy link

Ping. This feature is still not documented in the ROS wiki. I would be willing to provide the documentation but the wiki site is immutable for me.

@gavanderhoorn
Copy link
Contributor

@timonegk: the wiki is read-only, unless you have an account.

You can register for an account here. After that, you'd have to request write-access (spam protection measure) in ros-infrastructure/roswiki#258.

@timonegk
Copy link

@gavanderhoorn Thank you. I was not aware of the whitelist.

@gavanderhoorn
Copy link
Contributor

I believe it's mentioned after you register.

@timonegk
Copy link

This feature is now documented (http://wiki.ros.org/rospy/Overview/Logging#Named_Logging).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants