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);
            }
      }
}

Friday, August 17, 2012

IOC : Java-based configuration and autowiring


Dean.java:
package com.lnn.ioc;

public class Dean {
      private String name;

      public String getName() {
            return name;
      }

      public void setName(String name) {
            this.name = name;
      }
}
MyBean.java:
package com.lnn.ioc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class MyBean {
      @Autowired
      @Qualifier("hello")
      private Dean dean = null;

      public Dean getDean() {
            return dean;
      }

      public void setDean(Dean dean) {
            this.dean = dean;
      }
}
JavaBeanConfig.java:
package com.lnn.ioc.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.lnn.ioc.Dean;
import com.lnn.ioc.MyBean;

@Configuration
public class JavaBeanConfig {
      @Bean
      public MyBean bean() {
            return new MyBean();
      }

      @Bean
      public Dean dean() {
            Dean dean = new Dean();
            dean.setName("dean");
            return dean;
      }

      @Bean
      public Dean hello() {
            Dean dean = new Dean();
            dean.setName("hello");
            return dean;
      }
}
ioc.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"    
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
      <context:annotation-config/>
      <context:component-scan base-package="com.lnn.ioc.config"/>
</beans>
Test.java:
package com.lnn.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
      public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");
            MyBean bean = context.getBean("bean", MyBean.class);
            System.out.println(bean.getDean().getName());
      }
}