0

In my application, I use log4j. all the logs are written in a file, but if an error STDERR not handled by my logs occurs, it is redirected in an other file. For example, the non-handled NullPointerException appear in this other file.

I need to add the date/time before the exception. I use a custom PrintStream for that :

Main.java

public class Main {
    MyPrintStream ps;

    public static void main(String[] args) {
        System.setErr(new MyPrintStream(System.out));
        Integer i = null;
        String str = i.toString();
    }
}

MyPrintStream.java

public class MyPrintStream extends PrintStream {
    public MyPrintStream(OutputStream out) {
        super(out);
    }

    @Override
    public void println(String string) {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        super.println(simpleDateFormat.format(date) + " " + string);
    }
}

Output:

Exception in thread "main" java.lang.NullPointerException
2018-03-21 18:05:53.749     at test.Main.main(Main.java:9)

What I need:

2018-03-21 18:05:53.749 Exception in thread "main" java.lang.NullPointerException
 at test.Main.main(Main.java:9)

In my output, there is a date for each line. I tried to override the print method, and there is 3 times the date. How to display the date only once, at the beginning of the exception ?

I have an other possible solution, it is to display a log with log4j each time this kind of non-handled exception occur, but I don't know how to do if the exception is not catched...

Skartt
  • 551
  • 2
  • 7
  • 19

1 Answers1

0

I found a solution. I could do an log4j appender to redirect stderr, and my files would be the sames.

I can use the UncaughtExceptionHandler to add the date on the non-catched errors:

public static void main(String[] args) {


        Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                Date date = new Date(); // faire le new Date() ici, en dehors du block, garanti d'avoir une heure au plus juste, mais les traces pourraient ĂȘtre au final dans le dĂ©sordre dans le fichier
                synchronized (System.err) {
                   System.err.print(simpleDateFormat.format(date) );
                           System.err.print(" Exception in thread \""+t.getName()+"\" "); 
                   e.printStackTrace(System.err);
                }
             }
        });

        Integer i = null;
        String str = i.toString();

    }

I can redirect System.err to a file if I want.

Skartt
  • 551
  • 2
  • 7
  • 19