Java foundation - log usage

Keywords: log4j Java Apache xml

If log and exception handling are combined properly, it will bring great value to project maintenance.

Log: a detailed record of a process and experience.
Project Log: it is the detailed record of the project development process, which is generally recorded by the project manager.
Log in the code: the programmer records the details of a certain development process, which is the work every programmer needs to do in the project.
The log in the code plays a very important role in the project. The level of detail of log records determines whether the system is easy to maintain. There are many frameworks of log records in Java project, and how to choose the model in the project will be confused.

The theme of our Chat discussion is: logs in Java code are mainly written to Java programmers. This Chat will explain Java logs from the following six aspects:

  • 1, The role of logs in a project
  • 2, Confusion of using Java log
  • 3, Java log evolution history
  • 4, Java log examples using different frameworks
  • 5, What are the principles of logging in a project
  • 6, A recommended project Java log instance

Through this Chat learning, I hope that you can deepen your understanding of the log processing process, unify the specification, and get the harvest when coding, and easily master the Java log processing from scratch, and can be applied to the actual project.

1, The role of logs in a project

Log log is mainly used to record the operation of the program, so as to facilitate debugging after deployment of the program, and also to facilitate the persistence of these information (if the log information is not saved to a file or database, the information will be lost).

1. View the current running status of the program

If we want to know the current operation of the program, we can analyze it by viewing the output of the application log in real time.

For example, enter an action address in the browser, and the url is responsible for performing some batch processing. After the action runs, if the processing is relatively time-consuming, the execution result of the program cannot be directly seen in the browser. At this time, you can open the system log, and the execution of the url can be easily analyzed by outputting information from the log.

2. View program history running track

If we want to know the running status of the diachronic program, we can analyze it by looking at the output of the application diachronic log.

For example, if you want to know the amount of users' visits at the end of last week, you can open the system log record at the end of last week for analysis; if you want to know whether a certain scheduled task of yesterday was executed normally, you can open the system log of yesterday, find the output information of the scheduled task accurately, and then judge whether the scheduled task was executed.

3. Troubleshooting system problems

Troubleshooting system problems is the most familiar flavor of programmers. In the process of project maintenance, any problem needs to be checked by programmers. At this time, if there is no clear log record, it is difficult to find out the cause of the problem.

An excellent programmer must be a master of logging. If the logging is good and handled properly, it's easy to troubleshoot problems.

Have you ever met a situation where a problem occurs, some people can quickly locate the problem and solve it; some people have been working for a long time, but haven't found the cause of the problem yet.

In fact, the person who quickly locates the problem must record a detailed log, so when the problem occurs, by checking the log when the problem occurs, you can quickly find out the cause of the problem.

4. Optimize system performance

By recording the running time of the program, we can judge the time consumed by the program from the beginning to the end of execution, so as to judge whether the system performance is up to the standard, and provide the judgment basis for the system performance optimization.

5. The cornerstone of safety audit

More and more attention has been paid to network security, so system security is a very important part of the project process, and security audit is also a very important part of the system.

Through the analysis of the system log, we can judge some illegal attacks, illegal calls, and security risks in the process of system processing.

For example, everyone is usually working on the operation system, in which when the operator processes some data through the interface, if there is no clear log operation record, a piece of data is deleted or modified, it is impossible to find who operates it, but if the corresponding record is made, the data will be deleted or modified at a glance.

Through the above five points, it shows the important role of log in the project maintenance process.

Whether a system is easy to maintain or not is largely based on how the code log of the programmer is recorded in the process of program development.

The more clear the log record is, the easier it will be to maintain it. Some programmers do not have the awareness of log record, or do not understand the log record clearly, or do not know how to record the log, which will inevitably bring a big hole to the later maintenance of the project.

When the project manager asks you to solve an online problem, you just meet the code written by a person who has no habit of logging. At this time, you can feel the pain and want to be rude.

Therefore, as a programmer, it is a basic skill of programmer's career to master the recording method of code log. When writing code, keeping a good log record is a way of "benefiting others and self-interest". Not writing a log record is a way of "harming others but not self-interest".

2, Confusion of using Java log

Most programmers can realize the importance of log in the project, but there will be a lot of confusion about how to do it, how to do it, and what tools to use.

1. Tool confusion

As a java programmer, fortunately, Java has a very powerful log library with powerful functions and performance. Unfortunately, there are more than one such log library. I believe that every reader will be puzzled by the use of logging tools such as JUL (Java Util Log), JCL (Commons Logging), Log4j, SLF4J, Logback, Log4j2, etc.

The following section 3: "Java log evolution history" and section 4: "Java log examples using different frameworks" will help you to solve the problem of using java log framework.

2. Use confusion

Some programmers, even if they know what logging tools are used to write Java programs, may have trouble with how to write, what to write, and under what circumstances to write log records.

The following section 5: "what principles should be followed for logging in the project" will help you understand what principles should be followed for logging.

Some programmers know which Java framework to use and the principle of logging. They may be confused about how to operate in the project.

3. Practical confusion

The following section 6: "a recommended project Java log instance", will show you the application examples in the specific project process.

3, Java log evolution history

The first one is Log4j in the Apache open source community. This log is indeed the most widely used logging tool and has become the de facto standard for Java logs.

However, at that time, Sun company, the main developer of Java, thought that it was orthodox. In JDK 1.4, it added the log implementation of JUL (under the java.util.logging package) in an attempt to fight against Log4j, but it caused the confusion of Java developers' logging situation, which has been criticized so far.

Of course, there are other log tools, which are basically independent, and these log systems are not related to each other.

Why does the appearance of JUL lead to the confusion of development situation?

Imagine that your project application uses Log4j, and then uses a third-party library, and the third-party library uses JUL, so your application must use Log4j and JUL at the same time, and then need to use another third-party library, but this third-party library uses simplelog other than Log4j and JUL, at this time, all kinds of logworkers in your application It's bound to crash programmers. Because these logging tools are not related to each other, replacing and unifying logging tools has become a tricky task.

If you encounter this kind of problem, how to solve it?
To solve this problem, we will use a design pattern - "adapter pattern", that is, abstract the problem, abstract an interface layer, and adapt each log implementation, so that the libraries provided to others can directly use the abstract interface layer.

In order to solve this thorny problem in daily development, the Apache open source community provides a log framework as an abstraction of logs, called commons logging, also known as JCL (Java Common Logging). JCL abstracts various log interfaces, abstracts an interface layer, and adapts each log implementation, so that the libraries provided to others can be used directly The abstract layer is enough. It really completes the implementation of compatible mainstream logs (Log4j, JUL, Simplelog, etc.) and better solves the above problems. It basically unifies the Jianghu. Even the top Spring relies on JCL.

But the good days are not long. As Ceki G ü lc ü, the author of the elder Log4j, he thinks that JCL is not good enough, so he came out again and created a more elegant log framework SLF4J (this is also the abstract layer), that is, the Simple Logging Facade for Java, and implemented a son-in-law logback for SLF4J, which is indeed better Elegant.

Finally, Ceki G ü lc ü felt that he had to take care of his "eldest son", Log4j, and transform Log4j, so-called Log4j2, to support JCL and SLF4J at the same time.

With the emergence of SLF4J, the Java log system becomes confused.

The following is a schematic diagram of the current Java log system:

Log4j, JUL and Logback are not compatible with each other and have no common Interface, so commons logging and SLF4J abstract a common Interface through adapter mode, and then implement the log according to the specific log framework used.

Both java common logging and SLF4J are log interfaces for users to use without implementation. Log4j, JUL, Logback, etc. are the real implementation of logs.

When we call the log interface, the interface will automatically find the appropriate implementation and return a suitable instance to serve us. These processes are transparent, and users do not need to perform any operations.

tool Official website
Log4j http://logging.apache.org/log4j/1.2
JCL http://commons.apache.org/proper/commons-logging/
SLF4J http://www.slf4j.org
Logback http://logback.qos.ch
Log4j2 https://logging.apache.org/log4j/2.x/

4, Java log examples using different frameworks

1. Log4j

Log4j introduction

Log4j (Log for Java) is an open source project of Apache. By using log4j, you can control the output of log information to log files and the output format of each log. By defining the level of each log information, you can control the generation process of logs more carefully. These can be configured flexibly through a configuration file without modifying the application code.

Log4j instructions

(1) Select jar package

Add log4j-1.2.17.jar to Libraries. If you use maven project, you can also choose to add a dependency in pom.xml as follows:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

(2) log4j.properties configuration

Log4j has three main components: recorder, Appender and layout. These three types of components work together to enable developers to record messages according to message types and levels, and control the format and reporting location of these messages at runtime.

Log4j only four levels are recommended, with the priority from high to low being ERROR, WARN, INFO and DEBUG.

For example, if the INFO level is defined, only those equal to or higher than this level can be processed, then ALL the DEBUG level log information in the application will not be printed out. ALL, print ALL logs; OFF, turn OFF ALL log output.

AppenderName is to specify where the log information is output to, and multiple output destinations can be specified at the same time.

Create log4j.properties in the src root directory, and modify the configuration according to your own requirements. The contents are as follows:

    #Configure root Logger
    #Change the code to output logs above info level. The files are output separately. One is file, the other is error
    log4j.rootLogger=info,file,error

    #Configure file log information output destination Appender
    #Define the output named file to generate a log file every day
    log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
    #Specifies the minimum output level bit of log information INFO, default to DEBUG
    log4j.appender.file.Threshold=INFO
    #Specifies that the current message is output to the jpm/log4j/log.log file
    log4j.appender.file.File=/jpm/log4j/log.log
    #Specifies that log files are scrolled by day
    log4j.appender.file.DatePattern=yyyy-MM-dd
    #Configure the format (Layout) of log information Layout is flexible to specify the Layout mode
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    #Format the log. Log4j formats the log information in a print format similar to the printf function in C language
    log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-ddHH:mm:ss}][%-5p][jpm-%c{1}-%M(%L)]-%m%n
    #Specifies the encoding of the output information
    log4j.appender.file.encoding=UTF-8

    #Configure the error log information output destination Appender
    #The output named error is defined to generate a log file every day
    log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
    #Specifies the minimum output level of log information, ERROR, and the default is DEBUG
    log4j.appender.error.Threshold=ERROR
    #Specifies that the current message is output to the jpm/log4j/error.log file
    log4j.appender.error.File=/jpm/log4j/error.log
    #Specifies that log files are scrolled by month
    log4j.appender.error.DatePattern=yyyy-MM
    #Configure the format (Layout) of log information Layout is flexible to specify the Layout mode
    log4j.appender.error.layout=org.apache.log4j.PatternLayout
    #Format the log. Log4j formats the log information in a print format similar to the printf function in C language
    log4j.appender.error.layout.ConversionPattern=[%d{yyyy-MM-ddHH:mm:ss}][%-5p][jpm-%c{1}-%M(%L)]-%m%n
    #Specifies the encoding of the output information
    log4j.appender.error.encoding=UTF-8

    #Make the log of a function output to the specified log file separately
    log4j.logger.saveUserLog=INFO,saveUserLog
    #This configuration is to make the job log output only to the log file specified by itself, which means that the Logger will not be output in the appender of the parent Logger. The default is true
    log4j.additivity.saveUserLog=false
    log4j.appender.saveUserLog=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.saveUserLog.File=/jpm/log4j/saveUserLog.log
    log4j.appender.saveUserLog.DatePattern=yyyy-MM-dd
    log4j.appender.saveUserLog.Append=true
    log4j.appender.saveUserLog.layout=org.apache.log4j.PatternLayout
    log4j.appender.saveUserLog.layout.ConversionPattern=%m%n
    log4j.appender.error.encoding=UTF-8

(3) Code example for output log

    package jpm;

   import org.apache.log4j.Logger;

   public class TestLog4j {

       public static void main(String[] args) {
           final Logger logger = Logger.getLogger(TestLog4j.class);
           final Logger saveUserLog = Logger.getLogger("saveUserLog");

           if (logger.isDebugEnabled()) {
               logger.debug("debug");
           }

           logger.info("info");
           logger.error("error");

           saveUserLog.info("Zhang San,male,26 year,Peking University,2018-05-19,Straight A student");
       }
   }

(4) Log file and log details generated by the above code example

2. Use example of Jul (under java.util.logging package)

JUL introduction

Java Logging API was officially released by Sun company in May 2002. It is a new application program interface provided since J2SE version 1.4. It needs JDK version 1.4 or above to support. java.util.logging. * package is the logging API of JDK.

It is strongly not recommended to use java.util.logging for logging, so the corresponding examples are not provided here.

3. Introduction to Java common logging

Commons logging provides a Log interface for developers who need to build components or libraries that use different Log architectures in different environments, including Log4j and Java Log. There are two basic abstract classes of Commons logging: Log (basic logger) and LogFactory (responsible for creating Log instances). The Log information is abstracted into the Log interface of Commons logging, and the running time of Commons logging determines which Log architecture to use. Because of the powerful function of Log4j, commons logging is generally used with Log4j, which almost becomes a standard tool for Java logging.

4. SLF4J introduction

SLF4J (Simple Logging Facade for Java) is the same as commons logging, which provides a facade encapsulation for different log frameworks. It can access a log implementation scheme without modifying any configuration during deployment, and can support multiple parameters, which can be replaced by {} placeholders.

See the Log4J example:

    Logger.debug("Hello " + name);

Because of the problem of string splicing (Note: the above statements will splice strings first, and then determine whether to output this log according to whether the current level is lower than debug. Even if the log is not output, string splicing will be performed). Therefore, many companies generally force the following statements, so that string splicing will be performed only when the current level is debug:

    if (logger.isDebugEnabled()) {
        LOGGER.debug("Hello " + name);
    }

It avoids string concatenation, but it is a bit too cumbersome. SLF4J provides the following simple syntax:

    LOGGER.debug("Hello {}", name);

Its form is similar to the first example, but there is no string splicing problem, and it is not as cumbersome as the second one.

Because of the placeholder function of SLF4J, more and more people use the SLF4J interface in actual development projects.

Why do I need the log interface? Can I just use the specific implementation directly?

Interfaces are used to customize specifications. They can be implemented in multiple ways. When used, they are interface oriented (imported packages are SLF4J packages or JCL packages, rather than specific packages in a certain log framework). That is, they interact with the interface directly and do not use the implementation directly. Therefore, when the implementation needs to be replaced, it is OK to directly replace the implementation without changing the log related code in the code .

For example, SLF4J defines a set of log interfaces. The log framework used in the project is Log4j. All the interfaces that are invoked in the project are SLF4J. Instead of using Log4j directly, the project application calls the interface of SLF4J, which calls the implementation of Log4j, and the entire application does not directly use Log4j, when the project needs to replace a more excellent log framework (logback). )You only need to import the jar of logback and the configuration file corresponding to logback. You don't need to change the log related code logger.info("hello world") in Java code at all, or modify the imported package of log related classes (import org.slf4j.Logger; import org.slf4j.LoggerFactory;).

Therefore, the use of the log facade brings convenience for the subsequent implementation of the specific log system.

5. Example of logback

Introduction to LogBack

LogBack and Log4j are both open source journal tool libraries. LogBack is an improved version of Log4j, which has more features than Log4j, and also brings great performance improvement. LogBack is officially recommended for use with Slf4j, which can flexibly replace the underlying log framework.

Logback is mainly composed of three modules:

  • logback-core
  • logback-classic
  • logback-access

Among them, LogBack core provides the core functions of LogBack and is the foundation of the other two components. The status and function of LogBack classic is the same as Log4J. It is also considered as an improved version of Log4J, and it implements the simple log facade SLF4J. Therefore, when you want to use it with SLF4J, you need to add LogBack classic to the classpath. LogBack access is mainly used as a module to interact with Servlet containers, such as Tomcat or Jetty, which provides some modules to interact with htt P access related functions.

Logback instructions

(1) Select jar package

To use Logback in Java programs, you need to rely on three jar packages, SLF4J API, Logback core, and Logback classic. SLF4J API is not part of Logback, so it is recommended to use SLF4J in combination with Logback.
pom.xml:

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

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
            </dependency>

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
                <version>1.2.3</version>
            </dependency>

(2)logback.xml

Create logback.xml in the src root directory, and modify the configuration according to your own requirements. The content is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!--Log level and priority sorting: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!-- status Used for designation Log4j The level of the print log itself -->
<!--monitorInterval: Log4j It can automatically detect and modify the configuration file and reconfigure itself, and set the interval in seconds -->
<configuration status="WARN" monitorInterval="30">
    <!--Define all first appender -->
    <appenders>
        <!--Configuration of this output console -->
        <console name="Console" target="SYSTEM_OUT">
            <!--Format of output log -->
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
        </console>

        <!--Define the file to export to the specified location -->
        <File name="log" fileName="/jpm/log4j2/logs/log.log" append="true">
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
        </File>

        <!-- This will print all info And below, each time the size exceeds size,Then this size Size logs are automatically saved by year-The folder created in the month is compressed as an archive -->
        <RollingFile name="RollingFileInfo" fileName="/jpm/log4j2/logs/info.log"
            filePattern="/jpm/log4j2/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch) -->
            <!-- DENY,The log will be discarded immediately and will not pass through other filters; NEUTRAL,The next filter in the ordered list goes through and processes the log; ACCEPT,The log will be processed immediately and will not pass through the remaining filters. -->
            <ThresholdFilter level="error" onMatch="DENY"
                onMismatch="ACCEPT" />
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="100 MB" />
            </Policies>
            <!-- DefaultRolloverStrategy If the property is not set, the default value is at most 7 files in the same folder, where 30 -->
            <DefaultRolloverStrategy max="30" />
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="/jpm/log4j2/logs/error.log"
            filePattern="/jpm/log4j2/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT"
                onMismatch="DENY" />
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="100 MB" />
            </Policies>
        </RollingFile>
    </appenders>

    <!--Only defined logger And introduced appender,appender It will take effect. -->
    <loggers>
        <!--Filter out spring and MyBatis Some useless DEBUG information -->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <root level="INFO">
            <appender-ref ref="Console" />
            <appender-ref ref="log" />
            <appender-ref ref="RollingFileInfo" />
            <appender-ref ref="RollingFileError" />
        </root>
    </loggers>

</configuration>

(3) Code example for output log

    package jpm.logback;

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

    public class TestLogback {

        public static void main(String[] args) {
            final Logger LOGGER = LoggerFactory.getLogger(TestLogback.class);
            LOGGER.debug("print debug log.");
            LOGGER.info("print info log.");
            LOGGER.error("print error log.");
        }
    }

(4) Print log results


The above example uses SLF4J as the log interface, and Logback as the log example of log implementation.

6. Use example of log4j2

Introduction to Log4j2

Apache Log4j 2 is an upgrade of Log4j. Compared with its predecessor, Log4j 1.x, Apache Log4j 2 has significant improvements. It also provides many improvements available for Logback, and supports JCL and SLF4J.

Log4j2 instructions

(1) Select jar package

The necessary packages of Log4j2 are introduced: log4j API and log4j core.
pom.xml configuration:

  <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.8.2</version>
  </dependency>

  <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.8.2</version>
  </dependency>

(2) log2j configuration file: log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--Log level and priority sorting: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!-- status Used for designation Log4j The level of the print log itself -->
<!--monitorInterval: Log4j It can automatically detect and modify the configuration file and reconfigure itself, and set the interval in seconds -->
<configuration status="WARN" monitorInterval="30">
    <!--Define all first Appender -->
    <appenders>
        <!--Configuration of this output console -->
        <console name="Console" target="SYSTEM_OUT">
            <!--Format of output log -->
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
        </console>

        <!--Define the file to export to the specified location -->
        <File name="log" fileName="/jpm/log4j2/logs/log.log" append="true">
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
        </File>

        <!-- This will print all info And below, each time the size exceeds size,Then this size Size logs are automatically saved by year-The folder created in the month is compressed as an archive -->
        <RollingFile name="RollingFileInfo" fileName="/jpm/log4j2/logs/info.log"
            filePattern="/jpm/log4j2/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--Console output only level And above( onMatch),Other direct rejection( onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT"
                onMismatch="DENY" />
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="100 MB" />
            </Policies>
            <!-- DefaultRolloverStrategy If the property is not set, the default value is at most 7 files in the same folder, where 30 -->
            <DefaultRolloverStrategy max="30" />
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="/jpm/log4j2/logs/error.log"
            filePattern="/jpm/log4j2/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT"
                onMismatch="DENY" />
            <PatternLayout
                pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="100 MB" />
            </Policies>
        </RollingFile>
    </appenders>

    <!--Only defined logger And introduced Appender,It will take effect. -->
    <loggers>
        <!--Filter out Spring and MyBatis Some useless DEBUG information -->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <root level="INFO">
            <appender-ref ref="Console" />
            <appender-ref ref="log" />
            <appender-ref ref="RollingFileInfo" />
            <appender-ref ref="RollingFileError" />
        </root>
    </loggers>

</configuration>

(3) Code example for output log

package jpm.log4j2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TestLog4j2 {

    public static void main(String[] args) {
        final Logger LOGGER = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
        LOGGER.debug("TestLog4j2 debug log.");
        LOGGER.info("TestLog4j2 info log.");
        LOGGER.error("TestLog4j2 error log.");
    }
}

(4) Print log results


(5) About log level

There are 8 levels, from low to high: all < trace < debug < info < warn < error < fatal < off.

  • All: lowest level, used to turn on all logging
  • Trace: it's trace. If the program pushes forward, you can write a trace output, so there should be many traces, but it doesn't matter. We can set the minimum log level to prevent it from outputting
  • Debug: pointing out that fine-grained information events are very helpful for debugging applications
  • Info: messages emphasize the running process of the application at a coarse-grained level
  • Warn: output warning and log below warn
  • Error: output error information log
  • Fatal: output the log that each serious error event will cause the application to exit
  • OFF: the highest level, used to turn OFF all logging

The program will print logs higher than or equal to the set level. The higher the set log level, the less logs will be printed out.

7. Example of JCL (Java Common Logging) + Log4j

JCL (Java Common Logging) + Log4j introduction

The Log interface of Commons logging is used, and it is up to commons logging to decide which Log architecture (such as Log4j) to use at runtime. Now, common logging and Log4j, the general logging tools of Apache, have become the standard tools of Java logging. This combination is a common combination of logging frameworks.

Instructions for using JCL (Java Common Logging) + Log4j

(1) Select jar package

commons-logging-1.2 + log4j1.2.17

pom.xml:

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

 <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.17</version>
 </dependency>

(2) Configure the common logging.properties file

It only needs one line. Put it under classpath. If it is Maven, it is under src/resources. However, if there is no common logging.properties file, but there is log4j.properties configuration under src, it can also output Log4j set logs normally.

    org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

(3) log4j.properties configuration

Please refer to "Log4j operation instructions".

(4) Code example for output log

    package jpm.jcllog4j;

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

    public class TestJclAndLog4j {

        public static void main(String[] args) {
            final Log LOGGER = LogFactory.getLog(TestJclAndLog4j.class);
            LOGGER.debug("TestJclAndLog4j debug log.");
            LOGGER.info("TestJclAndLog4j info log.");
            LOGGER.error("TestJclAndLog4j error log.");
        }
    }

(5) Print log results

8. SLF4J + Log4j use example

SLF4J + Log4j introduction

SLF4j + Log4j and JCL + Log4J are used in the same way. The main difference is that SLF4J uses the binding package (slf4j-Log4j12.jar) to tell which log to implement, while JCL uses the configuration file to get which log to choose.

SLF4J + Log4j instructions

(1) Select jar package

slf4j-api.jar + slf4j-log4j12.jar

pom.xml

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

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

(2) log4j.properties configuration file

Please refer to "Log4j operation instructions".
(3) Code example for output log

    package jpm.slf4jlog4j;

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

    public class TestSlf4jAndLog4j {

        public static void main(String[] args) {
            final Logger LOGGER = LoggerFactory.getLogger(TestSlf4jAndLog4j.class);
            LOGGER.debug("TestSlf4jAndLog4j debug log: {}", "debug");
            LOGGER.info("TestSlf4jAndLog4j info log: {}", "info");
            LOGGER.error("TestSlf4jAndLog4j error log: {}", "error");
        }
    }

(4) Print log results

5, What are the principles of logging in a project

1. Alibaba Java development manual log specification

You can refer to the second section "log specification" in Chapter 2 of Alibaba Java Development Manual (final version). pdf launched by Alibaba last October.

2. Personal experience summary

Note the following points when recording project logs:

Note that log level, especially info and error cannot be mixed;
Pay attention to the accuracy of the recorded information, and remember that the log is not clear;
Note that different code segment log descriptions cannot be repeated;
After catching the exception, record the details of the exception in time and transfer the exception to the outside;
Keep in mind that the logging is for the convenience of later query, so important code must be logged.

6, A recommended project Java log instance

After the analysis of the above code, the log used in our project will generally choose a log interface and a specific log implementation.

So is the log interface JCL or SLF4J? Let's make a comparison between them. The specific log is Log4j, as shown in the following figure:

As can be seen from the above figure, using SLF4J as the log interface is better for the project.

Therefore, in actual projects, I generally recommend SLF4J + Log4j or SLF4J + Logback.

See section 4 for configuration files

The recommended program fragment is as follows:

try {
            LOGGER.info("Query user information according to user code-At first, userId: {}" , userId);
            User user = userService.getUserById(userId);
            LOGGER.info("Query user information according to user code-End, userId: {}" , userId);
        } catch (CustomException e) {
            LOGGER.error("Query user information according to user code-Custom exception:{}" , e.getMessage());
            throw new CustomException("Query user information according to user code-Custom exception{}" , e.getMessage(), e);
        } catch (Exception e) {
            LOGGER.error("Query user information according to user code-Capture exception:{}" , e.toString());
            throw new ServiceException("Query user information according to user code-Capture exception:{}" , e.toString(), e);
        }

At this point, the Java log from the introduction to the end of the practical article, I hope to help you.

Published 16 original articles, won praise 1, visited 481
Private letter follow

Posted by Iron Bridge on Thu, 30 Jan 2020 01:37:40 -0800