Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, is there a way to get a callback every time something is written to stderr?

Tags:

java

stderr

I would like to have my own java code run when anything is written to stderr, but can't seem to find a way to do this generically. The goal is to either receive a callback or override something that prints to the error console perhaps where anytime an error is written such as with log's error function or Exception's printStackTrace, my code would be able to intercept the text. How might this be possible in Java?

like image 923
Brett Drake Avatar asked Apr 21 '21 18:04

Brett Drake


2 Answers

You can call System.setErr(PrintStream err) and set it to a PrintStream that does whatever you like. A Throwable will use System.err when printing its stack trace, so your PrintStream would get used.

like image 86
eis Avatar answered Oct 05 '22 19:10

eis


Like @eis said, you can set your own PrintStream. Here is an example of how you could register such a callback when something is written to the stderr.

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.function.Consumer;

public class PrintStreamExample {
    public static void main(String... args) {
        System.setErr(new PrintStream(new MyOutputStream(i -> System.out.println(i)), true));

        throw new IllegalArgumentException("boo");
    }

    private static class MyOutputStream extends OutputStream {
        private final Consumer<String> consumer;
        private final StringBuffer stringBuffer = new StringBuffer();

        public MyOutputStream(Consumer<String> consumer) {
            this.consumer = consumer;
        }

        @Override
        public void write(int b) throws IOException {
            stringBuffer.append((char) b);
        }

        @Override
        public void flush() {
            if (!stringBuffer.isEmpty()) {
                consumer.accept(stringBuffer.toString().trim());
                stringBuffer.delete(0, stringBuffer.length());
            }
        }
    }
}

So note that in this case the callback (the Consumer) is just printing to System.out which of course is silly in this context but in a real-world example I can imagine you might want to put a message on Kafka or something like that.

like image 33
Jonck van der Kogel Avatar answered Oct 05 '22 20:10

Jonck van der Kogel