0

I am running a complex multithreaded Java application and facing some issue with logging exceptions.

There's a class ExceptionLogger which handles exception, here's the code snippet.

public class ExceptionLogger {

    private enum EXTYPE {
        ERROR, INFO, WARNING
    }

    private static Logger logger;;
private  static void log(String message, EXTYPE msgtype) {

    boolean append = true;
    try {
        FileHandler fh = new FileHandler("messages.log", append);
        fh.setFormatter(new Formatter() {
            @Override
            public String format(LogRecord rec) {
                StringBuffer buf = new StringBuffer(1000);
                buf.append(new java.util.Date());
                buf.append(' ');
                buf.append(rec.getLevel());
                buf.append(' ');
                buf.append(formatMessage(rec));
                buf.append('\n');
                return buf.toString();
            }
        });
        logger = Logger.getLogger("messages");
        logger.addHandler(fh);

        switch (msgtype) {
        case WARNING:
            logger.warning(message);
            break;
        case ERROR:
            logger.severe(message);
            break;
        case INFO:
            logger.info(message);
            break;
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    public static synchronized void logEx(Exception e) {
        // if(e.getMessage().compareTo("Widget is disposed")==0) return;
        log("Error message :" + e.getMessage(), EXTYPE.ERROR);
        e.printStackTrace();
        log("cause :" + e.getCause(), EXTYPE.INFO);

    }


}

Now the issue is that when multiple thread log exceptions multiple files are created like messages.log.1 messages.log.2 ...
Even though I have declared it as synchronized function, shouldn't the threads wait to log their exception, instead of creating new files.

Also 1 more thing with the e.getMessage() just gets me message like null pointer exception... No reference to class or line no. is there. How to get that as well. The code is soon going into production and I cannot rely on e.printStacktrace for debugging.

1
  • 2
    Why not use one of several mature logging frameworks for java? There's the java.util.logging package, log4j, slf4j, etc. You won't have to concern yourself with threading issues. Commented Jun 19, 2011 at 6:09

1 Answer 1

1

I see that you use java.util.logging.Logger. Instead of creating FileHandler on every call to log, do it in static section of ExceptionLogger. And initialize logger when you declare it.

private static Logger logger = Logger.getLogger("messages");
static {
    FileHandler fh = new FileHandler("messages.log", append);
    fh.setFormatter(new Formatter() {
        @Override
        public String format(LogRecord rec) {
            StringBuffer buf = new StringBuffer(1000);
            buf.append(new java.util.Date());
            buf.append(' ');
            buf.append(rec.getLevel());
            buf.append(' ');
            buf.append(formatMessage(rec));
            buf.append('\n');
            return buf.toString();
        }
    });
    logger = Logger.getLogger("messages");
    logger.addHandler(fh);
}

Then instead of having your custom signature for log, just use

public void log(Level level,
                String msg)

for regular messages or

public void log(Level level,
                String msg,
                Throwable thrown)

for exceptions.

See http://download.oracle.com/javase/6/docs/api/java/util/logging/Logger.html

And there are much better ways to configure it via properties.

Ultimately, you probably don't need custom class as you can just use Logger directly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.