Pages

Thursday, 10 April 2014

Logging in a clustered environment using Log4j

Logging using Socket Appender.

The logs should be stored in a centralized machine or sever when the application is stored in a clustered environment. Let’s get a scenario where every information level of logs goes in a clustered machine and error level log go in a server or centralized machine. So every cluster will have an information level log and if an error occurs it will show in a centralized machine.


There are four classes (Class1, Class2, Class3, Class4) these classes behave as a clustered application and ClassMain which contain the main method behave as a manager of this cluster. This cluster means class 1 2 3 4 will store the info level logs through RolingFileAppender, show the message in the console using ConsoleAppender and send the error level logs to a centralized machine using SocketAppender.

log4j.xml is the file which is defined in the application; every cluster will have the same property file and log4j-server.xml will be deployed in a centralized machine.

The command for starting socket server:-

java -classpath {Jar Path}\jars\log4j-1.2.17.jar org.apache.log4j.net.SimpleSocketServer
4712 {property file path}\log4j-server.properties 

package com.sun.log.a;
import org.apache.log4j.Logger;
import com.sun.log.main.ClassMain;
/**
* Class1 containing log method which calls log method of main class.
*
* @author Suraj Bhambhani
*
*/
public class Class1 {
static Logger logger = Logger.getLogger("Class1");
/**
* Create logs for Class1 logger
*
* @return Logger
*/
public static Logger Log() {
ClassMain.log(logger);
return logger;
}
}
view raw Class1 hosted with ❤ by GitHub
package com.sun.log.a;
import org.apache.log4j.Logger;
import com.sun.log.main.ClassMain;
/**
* Class2 containing log method which calls log method of main class.
*
* @author Suraj Bhambhani
*
*/
public class Class2 {
static Logger logger = Logger.getLogger("Class2");
/**
* Create logs for Class1 logger
*
* @return Logger
*/
public static Logger Log() {
ClassMain.log(logger);
return logger;
}
}
view raw Class2 hosted with ❤ by GitHub
package com.sun.log.b;
import org.apache.log4j.Logger;
import com.sun.log.main.ClassMain;
/**
* Class3 containing log method which calls log method of main class.
*
* @author Suraj Bhambhani
*
*/
public class Class3 {
static Logger logger = Logger.getLogger("Class3");
/**
* Create logs for Class3 logger
*
* @return Logger
*/
public static Logger Log() {
ClassMain.log(logger);
return logger;
}
}
view raw Class3 hosted with ❤ by GitHub
package com.sun.log.b;
import org.apache.log4j.Logger;
import com.sun.log.main.ClassMain;
/**
* Class4 containing log method which calls log method of main class.
*
* @author Suraj Bhambhani
*
*/
public class Class4 {
static Logger logger = Logger.getLogger("Class4");
/**
* Create logs for Class4 logger
*
* @return Logger
*/
public static Logger Log() {
ClassMain.log(logger);
return logger;
}
}
view raw Class4 hosted with ❤ by GitHub
package com.sun.log.main;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.log4j.Logger;
import com.sun.log.a.Class1;
import com.sun.log.a.Class2;
import com.sun.log.b.Class3;
import com.sun.log.b.Class4;
/**
* ClassMain containing main method which calls all classes logs.
*
* @author Suraj Bhambhani
*
*/
public class ClassMain {
static SimpleDateFormat sd = new SimpleDateFormat("HH:mm:ss.SSS");
static Logger logger = Logger.getLogger(ClassMain.class);
/**
* Iterating to get all logs from the classes
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
Class1.Log();
Class2.Log();
Class3.Log();
Class4.Log();
}
}
/**
* Generic log method which log.
*
* @param logger
*/
public static void log(Logger logger) {
logger.error(logger.getName() + " Type Error "
+ sd.format(new Date()).toString());
logger.info(logger.getName() + " Type Info "
+ sd.format(new Date()).toString());
logger.trace(logger.getName() + " Type Trace "
+ sd.format(new Date()).toString());
logger.warn(logger.getName() + " Type Warn "
+ sd.format(new Date()).toString());
}
}
view raw ClassMain hosted with ❤ by GitHub
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<!--Socket appender for sending the logs to remote machine -->
<appender name="socketAppender" class="org.apache.log4j.net.SocketAppender">
<param name="Port" value="4712" />
<param name="RemoteHost" value="localhost" />
<param name="ReconnectionDelay" value="60000" />
</appender>
<!-- Console appender to print the logs in remote machine console -->
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d] [%t] %c %m%n" />
</layout>
</appender>
<!-- Generate a file using rolling file appender of a particular logger -->
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="ALL" />
<param name="append" value="true" />
<param name="file" value="/Log/Local.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d] [%t] %c %m%n" />
</layout>
</appender>
<!-- Sending the logs to the server machine by using socket appender -->
<logger name="Class1" additivity="false">
<level value="ERROR" />
<appender-ref ref="socketAppender" />
</logger>
<logger name="Class2" additivity="false">
<level value="ERROR" />
<appender-ref ref="socketAppender" />
</logger>
<!-- Root for defining the root work which is to be happened like console
appender will work for everything -->
<root>
<appender-ref ref="consoleAppender" />
<appender-ref ref="fileAppender" />
</root>
</log4j:configuration>
view raw log4j hosted with ❤ by GitHub
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<!-- Console appender to print the logs in remote machine console -->
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d] [%t] %c %m%n" />
</layout>
</appender>
<!-- Generate a file using rolling file appender of a particular logger -->
<appender name="fileAppender1" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="ALL" />
<param name="file" value="/Log/Desk1.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d] [%t] %c %m%n" />
</layout>
</appender>
<appender name="fileAppender2" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="ALL" />
<param name="file" value="/Log/Desk2.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d] [%t] %c %m%n" />
</layout>
</appender>
<!-- Catch the logs sent by a socket appender and perform the operation
by calling the appropriate appender -->
<logger name="Class1" additivity="false">
<appender-ref ref="fileAppender1" />
</logger>
<logger name="Class2" additivity="false">
<appender-ref ref="fileAppender2" />
</logger>
<!-- Root for defining the root work which is to be happened like console
appender will work for everything -->
<root>
<appender-ref ref="consoleAppender" />
</root>
</log4j:configuration>
view raw log4j-server hosted with ❤ by GitHub
References

No comments:

Post a Comment