0

I am using a third party jar that has lots of System.out.println(). I am not interested in those messages. It also uses slf4j logs that I am interested in. So how do I filter out System.out.println() messages in my stdout. Is there a quick way? I am trying to avoid writing any script to parse the whole log and keep only the relevant one. I am using maven.

I would prefer to do logger log as stdout and system.out as file.. so that I can see relevant log while build is running in build environment.

Kumar Gaurav
  • 729
  • 3
  • 9
  • 21
  • 1
    Make slf4j to log only to a file, but not the console. Redirect your console output to another file (via Unix `>`, for example). Presto, your messages are separated now. On a side note, I'd think twice before using a library full of `System.out`, as it's likely to be full of other issues too, and a pain to use as a result. – Alex Savitsky Mar 20 '18 at 13:25
  • I'd be surprised if a "real" library both used System.out as well as SLF4J. Are the same messages sent to both? Is it possible that something odd is happening like it's trying to use an SLF4J binding that writes to System.out at the same time as you have a binding trying to go elsewhere? What logging framework are you trying to use? –  Mar 20 '18 at 17:51
  • @Alex I would prefer to do other way.. logger log as stdout and system.out as file. Reason is that then I will be able to see relevant logs during build in build environment.. is there a way to do that? I will also modify OP.. – Kumar Gaurav Mar 20 '18 at 21:07
  • @KumarGaurav Can't you do a `tail` on your log file to see it in real time? – C.Champagne Mar 20 '18 at 21:17
  • @PeterCooperJr. no they are different messages.. its just stupid library that we have been using for some time. We are going to replace it in time. – Kumar Gaurav Mar 20 '18 at 22:08
  • @C.Champagne I want to see logger logs in the live logs that build tools like bamboo shows while building. – Kumar Gaurav Mar 20 '18 at 22:09
  • @AlexSavitsky tagging as couldn't tag in earlier message. We are going to replace that library in some time.. we are using it for quite some time. your comment was helpful however as mentioned in earlier comment, I would like to do it other way. System.out -> file and Logger.log -> console. Any idea? Thanks.. – Kumar Gaurav Mar 20 '18 at 22:11

2 Answers2

1

What I would suggest would be to redirect System.out to slf4j. That way, all logging can be configured in your logging framework in a standardized normal way.

Note that depending on the library you're using to do the redirection, if you have some loggers print to standard output, you may need to carefully configure it so that you don't end up in an infinite loop, where a printed message gets redirected to logging, which gets redirected to printing a message, and so on.

Also note that most build environments & IDEs have support for viewing the contents of a log file while it's being generated, so you don't have to print anything to standard output if you don't want to.

  • great!.. could do it by sending all system.out to debug level.. so that is automatically filtered now in my console. thanks.. – Kumar Gaurav Mar 21 '18 at 13:05
0

Redirect the System.out and System.err.

But be careful: There will be an recursion if you use the Simple Logger

stdout and stderr will redirect to our own implementation of OutputStream (see code comments). Our own implementation redirect the output to slf4j

System.setOut(new PrintStream(new OutputStream() {

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    //
    // Our own implementation of write
    //
    @Override
    public void write(int b) throws IOException {
        //
        // After a line break the line will redirect to slf4j
        //
        if ((b == '\r') || (b == '\n')) {
            // Only 'real' content will redirect to slf4j
            if (buffer.size() != 0) {
                LoggerFactory.getLogger("foo").info(new String(buffer.toByteArray(), "UFT-8"));
            }
            // A new buffer is needed after a line break
            // (there is no 'clear()')
            buffer = new ByteArrayOutputStream();
        }
        buffer.write(b);
    }
}));
System.setErr(new PrintStream(new OutputStream() {

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();


    //
    // Our own implementation of write
    //
    @Override
    public void write(int b) throws IOException {
        if ((b == '\r') || (b == '\n')) {
            if (buffer.size() != 0) {
                LoggerFactory.getLogger("foo").error(new String(buffer.toByteArray(), "UFT-8"));
            }
            buffer = new ByteArrayOutputStream();
        }
        buffer.write(b);
    }
}));
drkunibar
  • 1,327
  • 1
  • 7
  • 7
  • Can you please put few lines why it would work? With a first look, it looks like its setting StdOut and StdErr to a file.. doesn't matter whether it comes from logger or system.out. – Kumar Gaurav Mar 20 '18 at 22:13
  • No file will generate. I've put a few comments to the code – drkunibar Mar 23 '18 at 21:42