Logger.getLogger(CLass)

System.out.println() has been used for debugging before. But deploying a project in production environment in this way will degrade the performance of the application because of the numerous console outputs. Log4J becomes a powerful tool for balancing the development and deployment of applications.

Using Log4J in a project is not a difficult task. The simple and crude way is to declare a Logger private property in each class A

  1. private static Logger logger = Logger.getLogger(A.class);  

This is simple, but it brings two problems:

1. Increase system overhead - each class using Log4J adds object attributes.

2. Trouble: Every class using Logger has to declare the above Logger object repeatedly.

It's not hard to find that you can use refactoring to declare a common class Log4jUtils to handle Logger's public operations.

But the problem is not so simple. First of all, to solve a problem, what's the use of A.class in Logger.getLogger(A.class)? Can A.class be blind?

Let's do an experiment. First, simply configure the log4j.properties file.

  1. #Log level, output destination
  2. log4j.rootLogger=debug,stdout  
  3.   
  4. log4j.appender.stdout=org.apache.log4j.Conso  
  5. leAppender  
  6. log4j.appender.stdout.Target=System.out  
  7. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  8. #Output format
  9. log4j.appender.stdout.layout.ConversionPattern=%c %d{ABSOLUTE} %5p %c{1}:%L - %m%n  

Create a new test class

  1. import org.apache.log4j.Logger;  
  2.   
  3. /** 
  4.  * Created by li on 2015/5/24. 
  5.  */  
  6.   
  7. public class LoggerTest {  
  8.     private static Logger logger = Logger.getLogger(Object.class);  
  9.   
  10.     public static void main(String[] args) {  
  11.         logger.debug("Hello World!");  
  12.     }  
  13. }  

View the results:


Combined with log4j.properties configuration
  1. log4j.appender.stdout.layout.ConversionPattern=%c %d{ABSOLUTE} %5p %c{1}:%L - %m%n  
It is not difficult to know the category to which% c output belongs, usually the full name of the class in which it belongs. But what we're tracking is the LoggerTest class, which returns java.lang.Object, which is misleading.

Modify the code of the LoggerTest class at this point

  1. private static Logger logger = Logger.getLogger(LoggerTest.class);  

The results of operation are as follows:

The result is finally there. At this point, I understand the parametric purpose of getLogger(class): tracking the class that generated this log.


Now a new problem arises: how to deal with the parameter problem of getLogger(class) if you want to use a class Log4jUtils to deal with operations such as the declaration of Logger objects?

That is, how to get the type of logger object invoked in Log4jUtils.


The solution to this difficulty can be to use Java Reflection mechanism

Look at the following code:

Class Log4jUtils:

  1. /** 
  2.  * Created by li on 2015/5/23. 
  3.  */  
  4. public class Log4JUtils{  
  5.   
  6.     private static Logger logger =  null;  
  7.   
  8.     public static Logger getLogger(){  
  9.        if (null == logger){  
  10.             //Java 8 discards Reflection.getCallerClass()  
  11.            logger = Logger.getLogger(Reflection.getCallerClass().getName());  
  12.            logger.debug("Caller class name"+Reflection.getCallerClass().getName());  
  13.        }  
  14.         return logger;  
  15.     }  
  16. }  



Modify the code for the LoggerTest class:

  1. /**  
  2.  * Created by li on 2015/5/24.  
  3.  */  
  4.   
  5. public class LoggerTest {  
  6. //    private static Logger logger = Logger.getLogger(LoggerTest.class);  
  7.   
  8.     public static void main(String[] args) {  
  9.         Log4JUtils.getLogger().debug("Hello World!");  
  10.     }  
  11. }  
Operation results:


It's great to see this result. In the future, the project can give up using System.out.println() to print statements.

Keywords: log4j Apache Java

Added by Heavy on Sun, 30 Jun 2019 04:28:18 +0300