当前位置:网站首页>Alibaba development manual mandatory use of slf4j as the secret of the facade, I understand

Alibaba development manual mandatory use of slf4j as the secret of the facade, I understand

2020-11-10 11:24:00 Silent king two

It's been detailed before 、 A comprehensive introduction to Log4j, I believe that my friends have mastered . I'm reading the Songshan version of Alibaba development manual ( No, my little friend , Remember to ask me for ) When , I found one 「 mandatory 」 Log specification of nature :

Log system can not be used directly in application (Log4j、Logback) Medium API, Instead, use the API, for instance SLF4J, Log framework using facade mode , It is helpful to maintain and unify the log processing methods of various classes .

( Why did I knock down this piece of text , Because I found a language fault in Alibaba development manual , Look at the red part below )

( Maintain and unify , Putting unity on the last page is really awkward to read , And a little far fetched , Excuse me, the small edition of the manual is the language taught by the math teacher ?)

See this mandatory statute , I couldn't help asking :“ Why is Alibaba's development manual mandatory SLF4J As Log4J It's the face of ?” What is behind this “ not to be divulged ” The secret of ?

( Please match them by themselves CCTV 12 The kind of stage BGM)

PS: By the way, let's popularize a little knowledge for our friends , Alibaba development manual appears Jakarta It's actually Apache An open source project under the software foundation . Actually Commons It used to belong to Jakarta, Now it's as Apache The next individual project , The description in Alibaba's development manual is no longer appropriate , Change it to Apache Commons Logging It would be more appropriate .

( I can't help but pick a fault for Alibaba's development manual , Please forgive me “ be strict in one 's demands ” The attitude of doing things )

01、SLF4J What is it?

SLF4J yes Simple Logging Facade for Java Abbreviation (for≈4), It's a simple log facade , In appearance mode (Facade pattern, A design pattern , Provide a unified high-level interface for a group of interfaces in the subsystem , Make the subsystem easier to use ) Realization , Support java.util.logging、Log4J and Logback.

SLF4J The author is Log4J and Logback The author of , His GitHub The main page is as follows :

A cold feeling of autumn wind came to my face , Is there any ? Maybe the giant doesn't care to defend him GitHub Home page ? my GitHub The home page is miserable enough , I didn't expect that the giant was worse than me , Finally, I can boast that ,“ I , Silent king two ,GitHub Home page is more than SLF4J、Log4J and Logback The author of Ceki Gulcu It's much greener ......”

1996 Beginning of the year , The European secure electronic market project decided to write its own tracking API, In the end API It evolved into Log4j, It's been introduced and loved .

2002 year 2 month ,Sun Launched their own log pack java.util.logging( It can be called JUL), It is said that the realization idea has drawn lessons from Log4j, After all, at this time Log4j It's very mature .

2002 year 8 month ,Apache I launched my own log package , That's what the Alibaba development manual says JCL(Jakarta Commons Logging).JCL With great ambition , It's in JUL and Log4j Provides an interface of abstract layer based on , User friendly JUL and Log4j Switch between .

but JCL It doesn't seem to be very popular , Some people complain like this :

Ceki Gulcu I also feel that JCL Not good. , Or he wouldn't be in 2005 In 1949, I called myself SLF4J New projects , Right ? But there's always a price to pay ,SLF4J Only interfaces , It didn't come true , You can't force Java and Apache To achieve SLF4J Interface ? It's too hard , Not reality .

But the big guy is called the big guy , It's because he has something amazing beyond ordinary people , He was in SLF4J and JUL、Log4j、JCL Three bridges have been built between them :

Big guy started , Have ample food and clothing , Is there any ? Be cruel and connect your own Log4j Build a bridge .

Facing the domineering power of the giant , I just want to say something feebly ,“ SLF4J This facade is responsible for , You think it's easy to be ?”

02、SLF4J What pain points have been solved

In the spring and Autumn period and the Warring States period , Each country has its own currency , It's not appropriate to use another country's currency , Right ? That's more troublesome when there is trade , The currency is not unified , You can't trade directly , Because money may not be equivalent .

After Qin Shihuang unified the six kingdoms , We have launched a new monetary policy , One currency is used all over the country , Then the problem was solved .

You see , Same thing , The log system has JUL、JCL,Ceki Gulcu I wrote again 2 Kind of ,Log4j and Logback, Each has its own advantages and disadvantages , Plus tens of millions of users , Every man has his hobbyhorse , This leads to different applications may use different logging systems .

Suppose we're developing a system , Intended use SLF4J As a facade ,Log4j As a logging system , We used A frame , and A The facade of the frame is JCL, The log system is JUL, That's equivalent to maintaining two log systems , Right ?

That's tough !

Ceki Gulcu Thinking of this question , And helped us solve ! Look at SLF4J The solution given on the official website .

  • Use jcl-over-slf4j.jar Replace commons-logging.jar
  • introduce jul-to-slf4j.jar

To simulate this process , Let's build one that uses JCL Project .

First step , stay pom.xml Introduce in the file commons-logging.jar:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

The second step , New test class :

package com.itwanger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author  Wechat search 「 Silent king two 」, Reply key  PDF
 */

public class Demo {
    private static Log logger = LogFactory.getLog(Demo.class);
    public static void main(String[] args) {
        logger.info("jcl");
    }
}

This class will pass LogFactory Get one Log object , And use info() Method print a line of log .

In the process of debugging this code, you will find that ,Log There are four implementations of :

If there is no binding Log4j Words , Will default to choose Jdk14Logger—— It returns Logger object , It is java.util.logging.Logger, That is to say JUL.

therefore , You can see the following information in the console :

10 month  21, 2020 3:13:30  Afternoon  com.itwanger.Demo main
Information : jcl

How to use JCL The project was converted to use SLF4J What about ?

The third step , Use jcl-over-slf4j.jar Replace commons-logging.jar, And add jul-to-slf4j.jar、slf4j-log4j12.jar( Will automatically introduce slf4j-api.jar and log4j.jar):

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.25</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>1.7.29</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

Step four , stay resources Create under directory log4j.properties file , The contents are shown below :

###  Set up ###
log4j.rootLogger = debug,stdout,D

###  Output information to console  ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

###  Output DEBUG  Log above level to =debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

Run again Demo class , You'll find that target The directory will generate a name called debug.log The file of , The contents are shown below :

2020-10-21 15:32:06  [ main:0 ] - [ INFO ]  jcl

And you can see the following information on the console :

[INFO ] 2020-10-21 15:32:06,192 method:com.itwanger.Demo.main(Demo.java:12)
jcl

Make a careful comparison , You'll find out , The format of this output is not the same as before , That's why Log4j and JUL The log format is different .

in addition , Have you noticed that ? We didn't change the test class Demo, It still uses JCL obtain Log The way :

private static Log logger = LogFactory.getLog(Demo.class);

But the output format has been switched to Log4j 了 !

SLF4J In addition to providing this solution , binding Log4j Replace JUL and JCL; It also provides binding Logback Replace JUL、JCL、Log4j The plan :

And binding JUL Replace JCL and Log4j The plan :

too strong , Is there any ? If you have, please type in the message area 666.

03、SLF4J Than Log4J Where is the strength

SLF4J In addition to solving the above pain points , Help our applications be independent of any particular logging system , There is also a very powerful feature , That's it SLF4J A place holder is used when printing the log {}, It's a bit like String Class format() Method ( Use %s And so on ), But it's more convenient , This greatly improves the performance of the program .

as everyone knows , Strings are immutable , String concatenation creates many unnecessary string objects , Huge consumption of memory space . but Log4J When printing a log with parameters , Only string concatenation can be used :

String name = " Silent king two ";
int age = 18;
logger.debug(name + ", Age :" + age + ", A very shameless programmer ");

Very heavy , But added SLF4J after , The problem is solved with ease . Let's take a look at Log4j Add to project SLF4J Detailed steps for .

First step , hold log4j The dependency of is replaced by slf4j-log4j12(Maven Will automatically introduce slf4j-api.jar and log4j.jar):

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

The second step , stay resources Create under directory log4j.properties file , Content and Log4j That one Exactly the same :

###  Set up ###
log4j.rootLogger = debug,stdout,D,E

###  Output information to console  ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

###  Output DEBUG  Log above level to =debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

###  Output ERROR  Log above level to =error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

The third step , New test class :

package com.itwanger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author  Wechat search 「 Silent king two 」, Reply key  PDF
 */

public class Log4jSLF4JDemo {
    private static final Logger logger = LoggerFactory.getLogger(Log4jSLF4JDemo.class);

    public static void main(String[] args) {
        logger.debug("{}, A very shameless programmer "," Silent king two ");
    }
}

See? , Using a placeholder is better than “+” The operator is much more convenient . And there's no need to isDebugEnabled() Judge first ,debug() Method is executed before string concatenation .

If it's just Log4J Words , Will first string splicing , Re execution debug() Method , See the sample code :

String name = " Silent king two ";
int age = 18;
logger.debug(name + ", Age :" + age + ", A very shameless programmer ");

When debugging this code , You'll find out , As shown in the figure below :

That means , If the level of the logging system is not DEBUG, The string concatenation operation will be executed more , Wasted performance .

Be careful , There's another one in Alibaba's development manual 「 mandatory 」 Level conventions :

This is because if the parameter is a basic data type , Automatic packing will be carried out first (Integer.valueOf()). The test code is as follows :

logger.debug(" Silent king two ,{} year "18);

You can see it through the decompiler tool :

logger.debug("\u6C89\u9ED8\u738B\u4E8C\uFF0C{}\u5C81", Integer.valueOf(18));

If the parameter needs to call other methods ,debug() The method will then be called .

in other words , If you don't isDebugEnabled() Words , If it's not DEBUG In the case of level , Will perform more automatic boxing and call other methods operation —— The performance of the program is going down !

The results of the test class run and before Log4J The same as , Friends can click the link to jump to Log4j That article In contrast .

04、 summary

A brief summary of this article .

1) When using the log system , Be sure to use SLF4J As a facade .

2)SLF4J Can unify the log system , As the upper level abstract interface , No need to focus on the underlying log implementation , It can be Log4j, It can also be Logback, perhaps JUL、JCL.

3)SLF4J You can use placeholders when printing logs , It improves the performance of the program ( The temporary string is missing , The workload of garbage collection is small ), And make the code beautiful and unified .

4) If you guys know more secrets , It is suggested to post it in the message area .

Uh huh , Actually, I've finished writing the entire log system , Include Log4j、 SLF4J、Logback、Log4j His brother Log4j 2, But I think if I send them separately , More favorable SEO( Look at my heart for the flow , Manual formation ). If you really need to see the full version , I have also prepared for you , Click on the link below to download PDF:

https://pan.baidu.com/s/1dPwsQhT5OMVapE7hGi7vww Extraction code :fxxy

It's not easy to code words , Ask for a compliment every day , Move your golden finger ,bug One less ( flee .

版权声明
本文为[Silent king two]所创,转载请带上原文链接,感谢