0

I have an service that runs at boot time that starts a shell script that starts a java program. The stdout/stderr from the program is dumped to a log file, typically this ends up just being runtime exceptions. The problem is, however, while it works to log the exceptions to the log file, it doesn't have any kind of date stamp to let me know when that exemption happened.

nohup /my/program/start.sh >> /my/log.lg 2>&1&

How can I capture the exceptions and log them with a time/date stamp?

Robin Green
  • 32,079
  • 16
  • 104
  • 187
MABeatty1978
  • 115
  • 1
  • 3
  • 14

1 Answers1

1

System.out & System.err

Java supports both stdout & stderr standard streams via the System class as a pair of PrintStream objects already instantiated for your convenience.

Example:

System.out.println( "Bonjour tous le monde." ) ;
System.err.println( "Oops, a tear in the fabric of space-time has occurred." ) ;

If your expected output failed to appear, check your Java code. Perhaps a logging framework has been used to divert such output.

Instant

…and log them with a time/date stamp

As for a timestamp, generally best to do all your logging in UTC rather than a particular time zone. Use the Instant class.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). The current moment may be captured in milliseconds or microseconds rather than nanoseconds, depending on your implementation of Java and the limitations of your host OS and hardware.

By default, Instant::toString generates a string in standard ISO 8601 format such as 2018-01-23T12:34:56.123456Z.

System.out.println( "Current moment is: " + Instant.now().toString() ) ;
System.err.println( "Oops, error occurred at: " + Instant.now() ) ;

Logging exceptions

How can I capture the exceptions…

Study the Oracle Tutorial on exceptions, specifically the section, Catching and Handling Exceptions.

Wrap the code where an exception might be thrown with a try-catch.

try {
    …
} catch (ExceptionType name) {
    …
} catch (ExceptionType name) {
    …
}

Example from the Tutorial.

try {
    …

} catch (IndexOutOfBoundsException name) {
    System.err.println( "IndexOutOfBoundsException: " + e.getMessage() );

} catch (IOException name) {
    System.err.println( "Caught IOException: " + e.getMessage() );

}

Insert your timestamps as desired.

try {
    …

} catch (IndexOutOfBoundsException name) {
    System.err.println( "Caught IndexOutOfBoundsException at " + Instant.now() + ": " + e.getMessage() );

} catch (IOException name) {
    System.err.println( "Caught IOException at " + Instant.now() + ": " + e.getMessage() );

}

Logging framework

Eventually, you may choose to handle all such progress & error reporting through a logging framework. You can direct your output through any combination of destinations including standard streams, local log files, pagers/SMS, and remote logging services.

I suggest using the slf4j façade. You can plug already-used legacy logging tools into slf4j via adapters, or for greenfield work use the direct implementation of slf4j, Logback.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154