Article directory
1. Origin
Many developers have a habit of printing critical information at important steps in the program. In this way, the execution state of the program can be seen, and when the program encounters a problem, it can be quickly located. Before the emergence of a log framework, developers used System.out
other methods to print log information. This approach has some obvious drawbacks:
- Inefficiency, if more logs are printed, it will affect the program speed
- Inflexible, the format of the log, the location where the log file is saved is not easy to modify.
- Maybe you want to print more logs in the test environment, and some logs will be removed in the production environment.
Just like some of the above problems, the log framework slowly appeared. The function of the logging framework is very simple, nothing more than printing logs. So the author thought of the facade mode. When developing, the developer selects the facade to call the method, and then prints it. Different implementations are performed by referencing different jar packages.
2. Log frame selection
Log facade (abstraction layer) | Implementation class |
---|---|
Log4j、 JUL(java.util.logging)、Log4j2 、Logback |
Shows the usual log facade and log implementation, since JCL
it is no longer updated. jboss-logging
This framework is generally not used in business development. Therefore, in general business development, the facade SpringBoot
will be given priority .SLF4j
SLF4j、Log4j、Logback
It's from the same people, Logback
yes Log4j
an upgraded version. Therefore, generally in SpringBoot
development, log printing is generally used SLF4j+Logback
.
Note: Just Log4j2
like Log4j
the name is similar, in fact, there is no particularly big connection.
3. SLF4j usage problems
In SpringBoot development, SLF4j
the facade method needs to be called for log printing, otherwise this facade mode is meaningless.
As far as the above picture is concerned, application
for our application, it can be considered as the SpringBoot project here. Explanation from left to right:
- When
SLF4j
the package is referenced, although the log can be printed, it will eventually be printed to an empty location, which/dev/null
is an empty folder of linux. This will be explained later, in short, it will not be saved. - If you want to use
logback
the log framework as the project, you can uselogback
the jar that can be applied.SLF4j
Andlogback
is a matching use. - If you want to use
log4j
it, it's a bit embarrassing, because you werelog4j
born earlier,log4j
and you didn't think about adapting it when you were codingSLF4j
. Therefore, if you want to useSLF4j+log4j
it, you need to add an adaptation layer and introduceslf4j-log412.jar
it for adaptation. - The latter three are not used much, so I won't elaborate too much.
4. Compatibility issues
Maybe we use the logback
logging framework in our project, but it does not require other code to use this framework. Like Spring (commons-logging), Hibernate (jboss-logging), MyBatis, etc. This kind of strange logging framework must be adapted by the logging framework used in our project.
How to make all logs in the system unified to slf4j?
1. Exclude other logging frameworks in the system first; if commons-logging.jar is used, replace it with jcl-over-slf4j.jar and so on.
2. Replace the original logging framework with an intermediate package;
3. We import other implementations of slf4j
Question: If you use commons-logging.jar and replace it with jcl-over-slf4j.jar, will there be no error when compiling?
Likejcl-over-slf4j.jar
an adaptation jar
, with jar
allcommons-logging.jar
the classes and methods this has, but with modified implementations. As shown in the figure below, jcl
the package name and class name are commons-logging
the same, so that no compilation error will be reported.
In this way, the code of the core jar is replaced to achieve the realization of replacing its original log framework.
appendix
facade pattern
When an interface has multiple implementations, using the Facade pattern can be a good way to divide the code. For example, the database connection class javax.sql.DataSource
, which is an official connection interface. Manufacturers of various databases can implement this interface when they want to connect to the database through java code. For example: the implementation class of mysql is com.mysql.cj.jdbc.MysqlDataSource
.