0

Ok, so the problem I'd like to solve is having tests in CI being overly verbose. Now I could turn down the logging in general, but that would hurt when you actually need to debug one. What I think I'd like to do is accumulate all the logs in memory, and then set the actual level to emit when the suite has errored or succeeded, then emit/append the logs that need to be. Bonus points if I could somehow do this by inspecting the exception stack when it fails. Is this possible?

possible duplicate really it's the same question, but in 6 years we've gotten log4j2 and junit5, so I guess I'm wondering if this has changed.

xenoterracide
  • 16,274
  • 24
  • 118
  • 243
  • why don't you send the logs to a file, and in case of failure, have the CI save the log file in its "artifacts" or whatever your CI calls it? – Renato Feb 05 '21 at 19:55
  • @Renato not much point, CI will let me view the raw file when it's done anyways. – xenoterracide Feb 05 '21 at 20:26

2 Answers2

1

Nope, that watcher is still it (write your own, in other words), because your request is still bizarre. Time isn't going to change this.

Logging frameworks love to write ASAP, not later. After all, maybe the VM is about to hard-crash and that is the absolute worst time of all to cache some writes - the very log statements that provide insights into the hard crash are now lost to the ether.

Normally, the solution is to use tools that read the log files and process them in some fashion - usually, by chucking most of the lines out as you copy and zip them up for the ages, keeping the full dump (and uncompressed) only for the most recent few logs.

Key principle there being: A separate process (may not even be written in java) that does this later.

Can you configure your CI system to do this? That sounds like the right approach: Log at a pretty verbose level, and have the CI system strip the logs down to a much more strict level after the tests ran if the tests were successful.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • hah, I can't configure our CI system at all. It's managed by another team. Also haven't really noticed a CI system that can, out of the box anyways. – xenoterracide Feb 05 '21 at 20:00
  • Man it bugs me when someone responds with "Why the heck would you ever want to do THAT?" The OP stated clearly why they wanted to do it, and the reasoning is very rational. I work on a product currently that generates so much log traffic that we have to wrap 100 log files every 5 minutes. But when something goes wrong, we need all that information for the item that failed. We don't need it for all the successful jobs. – John Calcote Apr 25 '22 at 18:54
  • @JohnCalcote The question is a properly asked X/Y: _I have problem X, and I believe a proper solution is Y; can someone advise me about Y?_ -- and this answer answers X instead, and is accepted. You seem to have utterly missed the point and should reread the answer - it gives you the _right_ approach to dealing with this scenario. – rzwitserloot Apr 25 '22 at 19:24
  • @rzwitserloot - your use case (system is about to crash) is a small corner case. The real issue here is that we're logging 1000% more than we need to. A possible solution is to keep logged information in memory long enough to determine if it even needs to be logged before filling up the disk with it. A way around "the system is about to crash" is to install a crash handler that logs all in-memory buffers. I know - that doesn't always work, but as I said, the OP's original question was not about how to get the right data to disk before the process crashes. – John Calcote Apr 26 '22 at 20:30
  • This isn't a small corner case; it's rarely relevant, but when it is, it is very important, so, 'tiny number * gigantic number = ????'. Black Swan event - same principle at work. You still misunderstand the answer. The solution is a separate process that compresses/selects relevant stuff from the firehose. There are tons of tools out there, because it doesn't fall afoul of that corner case you so denigratingly decided to handwave away. – rzwitserloot Apr 26 '22 at 22:03
1

For JUnit 4 the library System Rules allows you to suppress output that is written to the console for successful tests. You have to add the rules SystemErrRule and SystemOutRule to your test.

@Rule
public final SystemErrRule muteSystemErr
    = new SystemErrRule().muteForSuccessfulTests();

@Rule
public final SystemOutRule muteSystemOut
    = new SystemOutRule().muteForSuccessfulTests();

Disclaimer: I'm the author of System Rules.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72