The log is an essential feature for each java application, and log4j is one of many uses. Generally, we use the java code logger.info(“Hello World”); to log a String value. it will output “Hello World” in the appender destination.
But how about logging a java object like this logger.info(new LogJavaObjectInfo());. Generally, it will output data like INFO [main] (LogJavaObjectInfo.java:18) – com.dev2qa.java.basic.log4jexample.LogJavaObjectInfo@3941a79c.
This is not human-readable and friendly. To resolve this issue, we have the below solutions.
1. Create a Java Class To Implements The org.apache.log4j.or.ObjectRenderer Interface.
- The custom class name is com.dev2qa.java.basic.log4jexample.LogJavaObjectInfoRenderer.
- You should override the method doRender(Object obj) to return customize String value when logging obj ( This renderer decorated java object ).
public class LogJavaObjectInfoRenderer implements ObjectRenderer { @Override public String doRender(Object obj) { // Convert the obj parameter to LogJavaObjectInfo class object. LogJavaObjectInfo logJavaObjectInfo = (LogJavaObjectInfo)obj; // Invoke the converted object's method. String ret = logJavaObjectInfo.getUserName() + " : " + logJavaObjectInfo.getMessage(); return ret; } }
- Set The Renderer Class in Eclipse Java Project resources / log4j.properties file. Please see the first line configuration of the below content.
# This means when log LogJavaObjectInfo object, use LogJavaObjectInfoRenderer to output String data. log4j.renderer.com.dev2qa.java.basic.log4jexample.LogJavaObjectInfo=com.dev2qa.java.basic.log4jexample.LogJavaObjectInfoRenderer # Define root logger, logger level is INFO, appender name is appender1 log4j.rootLogger = INFO, appender1 # Set appender1 to be a Console appender that will print log data to console. log4j.appender.appender1=org.apache.log4j.ConsoleAppender # Define appender1's layout log4j.appender.appender1.layout=org.apache.log4j.PatternLayout log4j.appender.appender1.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
- Log the LogJavaObjectInfo Object ( instance of the class com.dev2qa.java.basic.log4jexample.LogJavaObjectInfo ) in the below java source code.
public class LogJavaObjectInfo{ private String userName; private String message; public static void main(String[] args) { // Get root logger. Logger logger = Logger.getRootLogger(); // Create a new object. LogJavaObjectInfo logJavaObjectInfo = new LogJavaObjectInfo(); // Set object's properties. logJavaObjectInfo.setUserName("Jerry"); logJavaObjectInfo.setMessage("Welcome to dev2qa.com"); // Log the object use root logger. logger.info(logJavaObjectInfo); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
- Run the above source code will get the below output. This is user-friendly enough and human-readable.
INFO [main] (LogJavaObjectInfo.java:25) - Jerry : Welcome to dev2qa.com
2. Override The LogJavaObjectInfo Class toString() Method.
- LogJavaObjectInfo.toString().
@Override public String toString() { StringBuffer retBuf = new StringBuffer(); retBuf.append("This message is generated from toString() method. "); retBuf.append(this.getUserName()); retBuf.append(" : "); retBuf.append(this.getMessage()); return retBuf.toString(); }
- Now you can remove the object renderer configuration in log4j.properties file and run LogJavaObjectInfo main method again, you can get below output.
INFO [main] (LogJavaObjectInfo.java:25) - This message is generated from toString() method. Jerry : Welcome to dev2qa.com
3. Example Project Full Source Code.
- Below is the example project source files list.
D:\WORK\DEV2QA.COM-EXAMPLE-CODE\JAVACOREEXAMPLEPROJECT\SRC\COM\DEV2QA\JAVA\BASIC\LOG4JEXAMPLE log4j.properties Log4jBasicExample.java LogJavaObjectInfo.java LogJavaObjectInfoRenderer.java
- log4j.properties
# Define com.dev2qa.java.basic.log4jexample class logger log4j.logger.com.dev2qa.java.basic.log4jexample = warn, appender1 # Set appender1 to be a Console appender which will print log data to console. log4j.appender.appender1=org.apache.log4j.ConsoleAppender # Define appender1's layout log4j.appender.appender1.layout=org.apache.log4j.PatternLayout log4j.appender.appender1.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n # Define root logger, logger level is INFO, appender name is appender2 log4j.rootLogger = info, appender2 # Appender2 will save log data to file. log4j.appender.appender2=org.apache.log4j.FileAppender log4j.appender.appender2.File=C:/WorkSpace/logData.log log4j.appender.appender2.layout=org.apache.log4j.PatternLayout log4j.appender.appender2.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
- Log4jBasicExample.java
package com.dev2qa.java.basic.log4jexample; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; public class Log4jBasicExample { public static void main(String[] args) { //You can specify log4j.properties location if you do not save it in CLASSPATH directory. PropertyConfigurator.configure("C:/WorkSpace/dev2qa.com/Code/src/com/dev2qa/java/basic/log4jexample/log4j.properties"); Logger rootLogger = Logger.getRootLogger(); // Get this class related logger object. Logger logger = Logger.getLogger(Log4jBasicExample.class); logger.debug("This is debug message."); logger.info("This is info message."); logger.warn("This is warn message."); logger.error("This is error message."); logger.fatal("This is fatal message."); rootLogger.debug("This is rootLogger debug message."); rootLogger.info("This is rootLogger info message."); rootLogger.warn("This is rootLogger warn message."); rootLogger.error("This is rootLogger error message."); rootLogger.fatal("This is rootLogger fatal message."); } }
- LogJavaObjectInfo.java
package com.dev2qa.java.basic.log4jexample; import org.apache.log4j.Logger; public class LogJavaObjectInfo{ private String userName; private String message; public static void main(String[] args) { // Get root logger. Logger logger = Logger.getRootLogger(); // Create a new object. LogJavaObjectInfo logJavaObjectInfo = new LogJavaObjectInfo(); // Set object's properties. logJavaObjectInfo.setUserName("Jerry"); logJavaObjectInfo.setMessage("Welcome to dev2qa.com"); // Log the object use log4j root logger. logger.info(logJavaObjectInfo); } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { StringBuffer retBuf = new StringBuffer(); retBuf.append("This message is generated from toString() method. "); retBuf.append(this.getUserName()); retBuf.append(" : "); retBuf.append(this.getMessage()); return retBuf.toString(); } }
- LogJavaObjectInfoRenderer.java
package com.dev2qa.java.basic.log4jexample; import org.apache.log4j.or.ObjectRenderer; public class LogJavaObjectInfoRenderer implements ObjectRenderer { @Override public String doRender(Object obj) { // Convert the obj parameter to LogJavaObjectInfo class object. LogJavaObjectInfo logJavaObjectInfo = (LogJavaObjectInfo)obj; // Invoke the converted object's method. String ret = logJavaObjectInfo.getUserName() + " : " + logJavaObjectInfo.getMessage(); return ret; } }