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

A way to tell that logging to a pipe should be as if it's tty #130

Open
ledestin opened this issue Oct 22, 2020 · 4 comments
Open

A way to tell that logging to a pipe should be as if it's tty #130

ledestin opened this issue Oct 22, 2020 · 4 comments

Comments

@ledestin
Copy link

I'm testing my program with RSpec, by calling it with backticks ./bin/name, and the output includes timestamps. They get in the way.

If there was a way to make it output user-facing output, it'd be awesome. For example, OPTPARSE_PLUS_TTY=1 ./bin/name.

@davetron5000
Copy link
Owner

Is that due to the built-in logging?

If so, a few options you could try:

  • Set --log-level=fatal in your tests. This would only show logs logged at the fatal level.

  • You can check in your script if stdout/stderr is a tty and do something different, e.g:

    if $stdout.tty? || $stderr.tty?
      logger.formatter = -> () {} # bury all log messages
    else

    You can/should make the formatter different so you see the messages, but hopefully you get the idea

  • Of course, there's good 'ole ./bin/name > /dev/null 2>&1 to squelch everything

@ledestin
Copy link
Author

I need error messages, just without timestamps on non-tty ios. I want to emit good error messages if arguments are invalid, and I test expect(conversion_output).to eq "foo: Invalid amount, please use a number".

I do have a workaround by using socat(1), but I'd prefer not to come up with it and replicate it in future projects. When I run my program with socat(1), it thinks it's talking to a tty.

  def run_cmd_with_tty(cmd)
    `LUMIONE_CACHE_DIR=./cache socat -ly - EXEC:'#{cmd}',pty,ctty,stderr`.rstrip
  end

I could use include instead of eq in RSpec, but it adds cognitive load over time, so I'd rather fix this problem than think about it in every test.

@davetron5000
Copy link
Owner

Ah, ok, thanks for the details.

The code right now omits timestamps if it's not a TTY like so:

self.formatter = BLANK_FORMAT if log_device_tty
@stderr_logger.formatter = BLANK_FORMAT if error_device_tty

This is what BLANK_FORMAT looks like:

BLANK_FORMAT = proc { |severity,datetime,progname,msg|
msg + "\n"
}

Since that's public, you could use that either always or only when a flag is given.

In your main executable, you should be able to do something like:

main do
  logger.formatter = OptparsePlus::CLILogger::BLANK_FORMAT

  # ...
end

# or

main do

  if options["omit-message-timestamps"]
    logger.formatter = OptparsePlus::CLILogger::BLANK_FORMAT
  end

  # ...
end

# set this in your tests when you invoke the function
on("--omit-message-timestamps")
```

That all being said, I could see making this more of a builtin feature, but let me know if this works for you

@ledestin
Copy link
Author

Thanks for a quick and comprehensive reply. It would work for me, and having a builtin feature would be great. I originally thought an option would just pollute option list, but now I think that somebody might pipe program output and the option would come in handy.

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

No branches or pull requests

2 participants