"Internet Architecture" Software Architecture-Java Log System

I have understood why there are so many jar packages in the log system. After a few days of logging, the system will blow up the online disk. How to configure and use log specifically, some configuration is Info is a log, error is a log, it is very annoying to find, if there is no problem online, we rarely care, if there is a problem, it is really annoying to find the corresponding log Through. If it is a distributed development, if the log management does not use a unified tool like elk, and it is scattered on different machines, there are 10 machines that need to go to 10 machines to look for logs in turn. Is it very troublesome? Today, let’s do the whole log at once. The system understands.

What are the log printing components in JAVA

name description
log4j
logback
log4j2
java.util.logging
  • Assuming that the Spring framework wants to print logs, which component should be selected?

I found that none of them can be selected, only based on the log component actually used by the application. Otherwise, multiple copies of the log will be printed. How to find the logging component actually used by the application, Apache Commons Loging, solves this problem

  • Apache Commons Loging (JCL)

Commons Loging itself only provides a log interface. What is the specific implementation of dynamically searching for corresponding components at runtime? For example: log4j, jdk14looger, etc. However, this dynamic binding method will cause binding failure when the system is particularly large. Now the more popular slf4j solves this problem based on static binding?

  • slf4j

Sl4j itself also only provides a log interface. Unlike commons logging, it uses the following jar packages added to the classPath to indicate which implementation is used:
• slfj-log4j12.jar (indicating log4j)
• slf4j-jdk14.jar (indicating specified jdk Looging)
• slf4j-jcl.jar (indicating specified jcl)
• log4j-slf4j-impl (indicating specified log4j2)
• logback-classic (indicating specified logback)

  • Facade pattern

Both JCL and slf4j use a facade mode (facade mode)
, which hides the complexity of the system and provides an interface for clients to access the system. This type of design pattern is a structural pattern. A unified access interface is provided for a group of interfaces in the subsystem. This interface makes the subsystem easier to access or use.

Simply put, this mode is to encapsulate some complex processes into an interface for easier use by external users. In this mode, 3 roles are designed.

1. Facade role: the core of the appearance model. It is called by the customer role, and it is familiar with the functions of the subsystem. According to the needs of the customer's role, several combinations of functions have been reserved internally.

2. Subsystem role: Realize the function of the subsystem. It is unknown to the customer role and facade. It can have mutual interaction within the system, and it can also be called by the outside world.

3. Customer role: complete the function to be realized by calling Facede.

The history of the log

The first to appear was log4j of the Apache open source community. This log is indeed the most widely used logging tool and has become the de facto standard for java logging. However, at that time, Sun added the JUL log implementation in jdk1.4 in an attempt to fight log4j, but it caused confusion. This is also a point of criticism. Of course, there are other logging tools, which will inevitably cause confusion for developers. Because these logging systems are not related to each other, replacement and unification have become a trickier thing. Imagine that your application uses log4j, and then uses a library from another team. They use JUL. Your application must use two logging systems. Then there is a second library that uses simplelog. It is estimated that you will be broken at this time. What is this going to do? This situation is left to you to figure out a solution, how can you solve it? To abstract, an interface layer is abstracted, and each log implementation is adapted or transferred, so that these libraries provided to others can directly use the abstraction layer. Yes, the open source community provides the commons-logging abstraction, which is called JCL, which is the logging framework. It does an excellent job of achieving mainstream-compatible logging (log4j, JUL, simplelog), basically unifying the world, even the most famous Spring also relies on JCL. It seems that things are indeed beautiful, but the beautiful days are not long, and the addition of another excellent log framework slf4j led to a more chaotic scene. Coincidentally, the author of slf4j (Ceki Gülcü) is the author of log4j. He felt that JCL was not good enough, so he wanted to make a more elegant one by himself. So the slf4j log system was born and realized a parent-child for slf4j—— Logback is indeed more elegant, but because many code bases have used JCL before, although there are bridge conversions between slf4j and JCL, there are still many problems during integration, which is indeed very annoying for many novices, because it is better than log4j alone. The times are much more "complex", you can pay attention to this, there are indeed many complaints. It should be over at this point, but Ceki Gülcü felt that he had to go back and save his "big brother"-log4j, so log4j2 was born, and log4j2 also participated in the slf4j log system. It will be more chaotic in the future.

The design of slf4j is indeed more elegant. It adopts a more familiar way-separation of interface and implementation. There is a pure interface layer-slf4j-api project. This basically defines the log interface completely, so for development, only need Just use this. If you have an interface, you must implement it. The most respected implementation is logback. Logback fully implements the slf4j-api interface and has better performance than log4j. It also implements new features such as variable parameter placeholder log output methods. I just mentioned that the use of log4j is more common, so it is still necessary to support this group of users. slf4j-log4j12 also implements slf4j-api, which is regarded as an adapter for log4j. In the same reasoning, there will be adapters for JUL slf4j-jdk14 and so on. In order to enable users who use JCL and other logging systems to easily switch to slf4j, various bridge projects are given, such as: jcl-over-slf4j will bridge all calls to JCL to slf4j, It can be seen that the api and JCL of jcl-over-slf4j are the same, so these two jars cannot coexist. jul-to-slf4j bridges the call to jul to slf4j, and log4j-over-slf4j bridges the call to log4j to slf4j.

log append file

Configuration of log4j2

  • HelloSlf4j
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloSlf4j {
    
    
    private static Logger logger = LoggerFactory.getLogger(HelloSlf4j.class);

    public static void main(String[] args) {
    
    
      /*  org.apache.log4j.Logger logger1=   org.apache.log4j.Logger.getLogger(HelloSlf4j.class);
        logger1.error("log4-error - abcd");
        logger1.info("log4- info -abcd");*/


        for (int i = 0; i < 2000; i++) {
    
    
            logger.error("slf4j- error - abcd");
            logger.info("slf4j- info -abcd");
        }
    }
}

  • log4j2.xml
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="error">
    <!-- 定义输出源 -->
    <Appenders>
        <Console name="Console" target="SYSTEM_ERR">
            <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/>
        </Console>
        <!--  测试环境使用-->
        <File name="file" fileName="logs/all.log" append="false">
            <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/>
        </File>
        <RollingFile name="rollingFile" fileName="logs/all-3.log"
                     filePattern="logs/$${date:yyyy-MM-dd}/all-%d{yyyy-MM-dd-HH}-%i.zip">
            <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="2 KB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>


        <RollingFile name="errorRollingFile" fileName="logs/error2.log"
                     filePattern="logs/$${date:yyyy-MM-dd}-error/error-%d{yyyy-MM-dd-HH}-%i.log">
            <PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="2 KB"/>
            </Policies>
            <DefaultRolloverStrategy max="5"/>
        </RollingFile>
    </Appenders>

    <!--  具体的日志配置 name =-->
    <Loggers>
        <AsyncRoot  level="debug">
            <AppenderRef ref="errorRollingFile"/>
        </AsyncRoot>
    </Loggers>
</Configuration>
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>tuling-logging</groupId>
    <artifactId>tuling</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--slf4j门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!--  log4j2 桥接包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.3</version>
        </dependency>

        <!--  log4j2 实现 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.3</version>
        </dependency>
        <!--  log4j2 实现 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.3</version>
        </dependency>







        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.8.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.lmax/disruptor -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.4</version>
        </dependency>

    </dependencies>


</project>

PS: Log4j 2 includes the next-generation asynchronous log system based on the LMAX separation library. In a multi-threaded environment, the asynchronous log system improves the performance (throughput and latency) by 10 times compared with Log4j 1.x and Logback. The original text is as follows:

Log4j 2 contains next-generation Asynchronous Loggers based on the LMAX Disruptor library. In multi-threaded scenarios Asynchronous Loggers have 10 times higher throughput and orders of magnitude lower latency than Log4j 1.x and Logback.

Guess you like

Origin blog.csdn.net/zhugeaming2018/article/details/110367800