Monday, August 27, 2012

Logging : Customized logging and rotating the logs using java.util.logging package


In this example, I have created handler, formatter, holder and test classes.

MyFormatter.java: This class formats the data before the logging into log.

package com.lnn.logging;
import java.util.Calendar;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class MyFormatter extends Formatter {
      private String message;

      @Override
      public String format(LogRecord record) {
            StringBuilder builder = new StringBuilder();
            builder.append(Calendar.getInstance().getTime());
            builder.append(' ');
            builder.append(record.getLevel());
            builder.append(' ');
            builder.append(getMessage());
            builder.append(' ');
            builder.append(record.getThreadID());
            builder.append(' ');
            builder.append(record.getSequenceNumber());
            builder.append(' ');
            builder.append(record.getSourceClassName());
            builder.append(' ');
            builder.append(record.getSourceMethodName());
            builder.append(' ');
            builder.append(formatMessage(record));
            builder.append("\r\n");
            return builder.toString();
      }

      public String getMessage() {
            return message;
      }

      public MyFormatter(String message) {
            this.message = message;
      }
}

MyHandler.java: This class logs the data and rotates the log after reaching logging limit.

package com.lnn.logging;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

public class MyHandler extends Handler {
      private int limit = 1024 * 1024;
      private String fileName = "Leninkumar.log";
      private BufferedWriter bufferedWriter;
      private File file = null;

      private File getFile() {
            return file;
      }

      public String getFileName() {
            return fileName;
      }
     
      public MyHandler() {
            open();
      }
     
      public MyHandler(String fileName) {
            this.fileName = fileName;
            open();
      }

      public MyHandler(String fileName, int limit) {
            this(fileName);
            this.limit = limit;
      }

      protected String newFileName() {
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            return getFileName() + "_" + sdf.format(cal.getTime());
      }

      protected void open() {
            try {
                  file = new File(getFileName());
                  bufferedWriter = new BufferedWriter(new FileWriter(file, true));
            } catch (Exception e) {
                  throw new RuntimeException("Exception occured while opening a logger.", e);
            }
      }

      private void rotate() {
            try {
                  close();
                  File newFile = new File(newFileName());
                  getFile().renameTo(newFile);
                  open();
            } catch (Exception e) {
                  throw new RuntimeException("Exception occured while rotating a logger.", e);
            }
      }

      @Override
      public void publish(LogRecord record) {
            if (!isLoggable(record)) {
                  return;
            }
            try {
                  synchronized (bufferedWriter) {
                        if (getFile().length() > limit) {
                              rotate();
                        }
                        if (getFormatter() != null) {
                              bufferedWriter.write(getFormatter().format(record));
                        } else {
                              bufferedWriter.write(Calendar.getInstance().getTime() + record.getMessage());
                        }
                        bufferedWriter.flush();
                  }
            } catch (Exception e) {
                  throw new RuntimeException("Exception occured while publishing a log.", e);
            }
      }

      @Override
      public void flush() {
      }

      @Override
      public void close() throws SecurityException {
            try {
                  if (bufferedWriter != null) {
                        bufferedWriter.close();
                  }
            } catch (Exception e) {
                  throw new RuntimeException("Exception occured while closing a log.", e);
            }
      }
}

MyLogHolder.java: This class creates and holds the logger instance.

package com.lnn.logging;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyLogHolder {
      private static ThreadLocal<Logger> threadLocal = new ThreadLocal<Logger>();
     
      public static Logger getLogger() {
            Logger logger = threadLocal.get();
            if (logger == null) {
                  logger = Logger.getAnonymousLogger();
                  logger.setLevel(Level.ALL);
                  Formatter formatter = new MyFormatter("Add this every time.");
                  // For 1 MB log file
                  Handler handler = new MyHandler("Leninkumar.log", 1024 * 1024);
                  handler.setFormatter(formatter);
                  logger.addHandler(handler);
                  // To set Log Level                
                  threadLocal.set(logger);
            }
            return logger;
      }    
}

MyLoggerTest.java: This class tests the logging functionality.

package com.lnn.logging;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyLoggerTest {
      public static void main(String[] args) throws SecurityException, IOException {
            Logger logger = MyLogHolder.getLogger();

            for (int i = 0; i < 10000; i++) {
                  logger.log(Level.ALL, "This is my message for log." + i);
            }
      }
}

No comments:

Post a Comment