javasshjvmerror-loggingjava-console

System Outs and Un handled exceptions from Java App is not having a timestamp when logged


Need help here. We have java apps started from our shell scripts in unix using java command and the output is redirected to a nohup file to ensure we capture any SystemOuts and any unhandled exceptions in a log file.

When the java app logs using the log4j, these logs are fine and they are formatted with a proper time stamp.

But when there are some systemouts in the code or any unhandled exceptions that are thrown back by the jvm process, they are logged in the nohup files but there is no timestamp on these log entries.

Can any one suggest if there are some scripting tweaks or jvm parameters that could help add timestamp to these jvm output logs?

Thanks in advance for the help


Solution

  • Edit the source code and add an uncaught exception handler to every thread.

    Looks something like this:

    package the.package.here;
    
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        updateUncaughtExceptionHandlers();
        ... rest of the code is here
      }
    
      static void updateUncaughtExceptionHandlers() {
        Thread.UncaughtExceptionHandler timestamped = (t, e) -> {
          String timestamp = ZonedDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
          System.err.printf("[%s] Exception in thread \"%s\" ",
            timestamp, t.getName());
            e.printStackTrace(System.err);
        };
    
        Thread.setDefaultUncaughtExceptionHandler(timestamped);
      }
    }
    

    This will take care of uncaught exceptions, but won't take care of anything written out via System.err or System.out.

    To take care of those, you'd use System.setErr() and System.setOut(), making PrintWriters that simply 'wrap' around the original System.out and System.err, and add a timestamp anytime a flag is true, then sets the flag false. The flag starts as true and is re-set to true every time you print a newline symbol.

    I can show you how to do that, too, but before delving any deeper - can you change the source code? If you can't, your only option is to redirect standard out and standard err not to a file but pipe it to a different executable that adds these timestamps.