optparse-plus icon indicating copy to clipboard operation
optparse-plus copied to clipboard

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

Open ledestin opened this issue 4 years ago • 4 comments

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.

ledestin avatar Oct 22 '20 10:10 ledestin

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

davetron5000 avatar Oct 22 '20 11:10 davetron5000

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.

ledestin avatar Oct 23 '20 08:10 ledestin

Ah, ok, thanks for the details.

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

https://github.com/davetron5000/optparse-plus/blob/3c0a84a6280d81bab38e5ca2a2701c48cefc8935/lib/optparse_plus/cli_logger.rb#L97-L98

This is what BLANK_FORMAT looks like:

https://github.com/davetron5000/optparse-plus/blob/3c0a84a6280d81bab38e5ca2a2701c48cefc8935/lib/optparse_plus/cli_logger.rb#L41-L43

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

davetron5000 avatar Oct 24 '20 16:10 davetron5000

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.

ledestin avatar Oct 27 '20 07:10 ledestin