Question

I have created a JAVA application. Sometimes, users do invalid operations on it or there are some exceptions that the application encounters when it outputs the errors. However, these outputs are not visible unless I run the application from command line using java -jar myapp.jar

I wish to record all of these to a file in the form of a log but I am unable to find a function or object which is responsible for outputting these errors etc.

To simplify my explanation, assume that my application outputs number from 1 to 10 using a for loop and a Sytem.out command. How can I record everything that is output to the System?

Thanks

Was it helpful?

Solution

Agreed with above, you should use a logging framework. I prefer to use abstractions such as SLF4J.

In this example you can use log4j underneath. Here is an example log4j.properties file you can put in the classpath of your java application.

#Rootlogger logs to console and logfile
log4j.rootLogger=INFO,stdout,logfile


log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=/tmp/apname.log
log4j.appender.logfile.MaxFileSize=1024KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date [thread] priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d [%t] %p [%c] - %m%n

#=============== CREATE A SEPARATE HANDLER FOR LOGGING SPECIFIC PACKAGES
log4j.appender.MYPACKAGEHANDLER=org.apache.log4j.RollingFileAppender
log4j.appender.MYPACKAGEHANDLER.File=/tmp/mypackage.log
# 1/2 GB
log4j.appender.MYPACKAGEHANDLER.MaxFileSize=512MB
# Keep three backup files.
log4j.appender.MYPACKAGEHANDLER.MaxBackupIndex=3
# Pattern to output: message only
log4j.appender.MYPACKAGEHANDLER.layout=org.apache.log4j.PatternLayout
log4j.appender.MYPACKAGEHANDLER.layout.ConversionPattern=%m%n

log4j.additivity.com.techtrip.mypackage=false
log4j.logger.com.techtrip.mypackage=DEBUG, MYPACKAGEHANDLER

Using this config will create two log files with a rolling appender, printing all debug log output of any class that logs in the com.techtrip.mypackage to /tmp/mypackage.log.

Suppose a simple example class with a Logger and a Formatter:

package com.techtrip.mypackage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Foo {

    private Logger logger = LoggerFactory.getLogger(Foo.class);

    private String someString;

    private Foo() {
        super();
    }
    public void setSomeString(String someString) {
        if (logger.isDebugEnabled()){
            logger.debug(String.format("Setting someString %s", someString));
        }

        this.someString = someString;
    }
}

This will log the setter output to the log file. Turn it off by simply changing the property file. Very simple.

OTHER TIPS

Why not use a log framework: http://logback.qos.ch/

With this you can easily switch between file or console.

You can use System.setOut (and setErr) to set the default standard output/error to your own PrintStreams. There is a complete example in this Oracle blog entry (courtesy of archive.org, as the original link is deceased).

However, if it's your own application, you should use a logging framework instead of using the standard output/error.

You have to redefine the streams via the System.setOut() and System.setErr(), but I think it would be a more flexible solution to use an existing logging framework as the Apache Log4J.

you can use System.setOut and System.setErr to set a diffrent PrintStream

Consider using logging library and not System.out. Set it up for example like this :

try {
    // Create a file handler that write log record to a file called logfile.txt
    FileHandler handler = new FileHandler("logfile.txt");

    // Add to the desired logger
    Logger logger = Logger.getLogger("");
    logger.addHandler(handler);
} catch (IOException e) {
}

Code for Simple Log File Generation:

import java.io.FileOutputStream;
import java.io.PrintStream;

public class SimpleLog_with_println {
public static void main(String[] args) {

          String st1 = "This World is Very Nice";
          String st2 = " And Beautiful.";
        try {
            System.setOut(new PrintStream(new FileOutputStream("log1.txt"))); //Create log file in parent directory

            // System.setOut(new PrintStream(new FileOutputStream("C:\\log1.txt"))); //Create log file in specified directory
            System.out.println();
            System.out.println("Now the output is redirected! And String is: " +st1 +st2);
        } catch(Exception e) {}   
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top