Understand why the log system so many JAR packages, the system put a few days of log on the online disk to hit the explosion. In some configurations, Info is a log and ERROR is a log. Searching is very annoying. If there is no problem online, we rarely care about it. If it is distributed development, log management is dispersed on different machines without the use of the unified tool ELK. If 10 machines need to go to 10 machines to find logs in turn, is it very troublesome? Today, let’s figure out the whole log system at one time.
What log printing components are available in JAVA
The name of the | describe |
---|---|
log4j | |
logback | |
log4j2 | |
java.util.logging |
- Assuming the Spring framework wants to print logging, which of these components should be selected?
The discovery cannot be selected, but only based on the logging component actually used by the application. Otherwise, it will print multiple copies of the log. How to find the actual logging component that your application uses Apache Commons Loging solves this problem
- Apache Commons Loging (JCL)
Commons Loging itself provides only a logging interface, which dynamically finds components at run time. For example: log4j, JDk14looger and so on. However, this dynamic binding will fail when the system is too large. The popular SLF4J solution is based on static binding.
- slf4j
Sl4j itself also provides only a logging interface, which, unlike Commons Loging, uses the following JAR packages in the classPath to indicate which implementation to use:
• slfj-log4j12.jar (for specifying log4j) • slf4j-jdk14.jar(for specifying JDK Looging) • slf4j-jcl.jar(for specifying JCL) • Log4j-slf4j-impl (specifying log4j2) • logback-classic(specifying logback)
- Facade pattern
Both JCL and SLF4J use a Facade that hides the complexity of the system and provides clients with an interface to access the system. This type of design pattern is structural. Provides a unified access interface for a set of interfaces in a subsystem that makes it easier to access or use the subsystem.
Simply put, this mode is to encapsulate some complex processes into an interface for external users to use more easily. In this mode, three characters are designed.
1. Facade Characters: The core of the facade pattern. It is invoked by the customer role, which is familiar with the subsystem’s functionality. Several combinations of functions are predetermined internally based on the needs of the customer role.
2. Subsystem roles: Realize the functions of subsystems. It is unknown to the customer role and Facade. It can have internal interaction within the system, but also can be called by the external interface.
3. Customer role: Invoke Facede to accomplish the functionality to be implemented.
The history of journaling
The first was Log4J from the Apache open source community, which is indeed the most widely used logging tool and has become the de facto standard for Java logging. However, when Sun added a JUL logging implementation to jdk1.4 in an attempt to counter log4j, it caused confusion, which was also criticized. Of course, there are other logging tools as well, and this inevitably leads to confusion among developers because these logging systems are not related to each other, making replacement and unification a tricky business. Imagine that your application uses Log4j, and then uses a library from another team that uses JUL. Your application uses two logging systems, and then a second library comes along that uses Simplelog. You’re probably freaking out at this point. What’s going on here? I leave it to you to figure out the situation. How do you solve it? Abstract, abstracting out an interface layer that ADAPTS or transitions to each logging implementation so that libraries that are provided to others use the abstraction layer directly. Yes, the open source community provides a Commons-logging abstraction known as JCL, which stands for logging framework, and does an excellent job of implementing compliant logging implementations (Log4J, JUL, Simplelog). Even spring relies on JCL. Things did look good, but the good times didn’t last long, and then the addition of another excellent logging framework, SLF4J, led to a more chaotic scene. It just so happens that the author of SLf4J (Ceki Gulcu), who is also the author of log4j, decided that JCL was not good enough, so he decided to create a more elegant version of his own. Slf4j logging system was born and implemented a parent of SLF4J logback, which is more elegant. However, since many of the previous codebase already uses JCL, even though there is a bridge conversion between SLF4J and JCL, the integration is still a lot of problems, which can be frustrating for many novices, because it is much more “complex” than the log4j era alone. This should have been the end of it, but Ceki Gulcu decided to go back and save his big brother, Log4j, so log4j2 was born, and log4j2 is also involved in slf4J’s logging system, which is likely to be more chaotic in the future.
Slf4j does have an elegant design, with the familiar approach of separating the interface from the implementation, and a pure interface layer, the SLF4J-API project, which basically completely defines the logging interface, so for development, it is only necessary to use this. The most popular implementation is Logback, which fully implements the SLF4J-API interface and has better performance than Log4j, as well as new features such as variable parameter placeholder log output. Slf4j-log4j12 also implements slF4J-API, which acts as an adapter to log4j. Similarly, there will be an adapter for JUL, slF4J-JDK14, etc. To make it easy for users using the latter implementation of JCL and other logging systems to switch to SLF4J, various bridging projects are presented, such as: Jcl-over-slf4j Bridges all JCL calls to SLf4J. As you can see, jCL-over-SLf4j has the same API as JCL, so the two JARS cannot coexist. Jul-to-slf4j Bridges calls to JUl to slf4j and log4j-over-slf4j Bridges calls to log4j to slf4j.
Log append file
Log4j2 configuration
- 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"); }}}Copy the code
- log4j2.xml
<Configuration status="error">
<! Define the output source -->
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d [%-5level][%t] %m (%C:%F:%L) %n"/>
</Console>
<! -- Test environment use -->
<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>
<! -- Specific log configuration name =-->
<Loggers>
<AsyncRoot level="debug">
<AppenderRef ref="errorRollingFile"/>
</AsyncRoot>
</Loggers>
</Configuration>
Copy the code
- pom.xml
<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 the SNAPSHOT</version>
<dependencies>
<! - slf4j appearance - >
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<! -- log4j2 bridge packet -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.3</version>
</dependency>
<! -- log4j2 implementation -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
<! -- log4j2 implementation -->
<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>We do</version>
</dependency>
</dependencies>
</project>
Copy the code
PS: Log4j 2 includes the next generation of asynchronous logging systems based on the LMAX split library, which provides a 10-fold performance improvement (throughput and latency) over Log4j 1.x and Logback in multi-threaded environments. The original text reads 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.