When I was free, I would dive stealthily in the group, screening and diagnosing my friends’ every move and every word. A head teacher’s instant sense, let me feel very happy, slightly enucleated with a trace of boring.

I found this string of chat records among readers of the Warring States Period:

Log4j = Log4j = Log4j = Log4j

There was a moment when I was struck by ten thousand points, and my heart was as sad as a dejected dog. Because there are always some malicious people on the Internet constantly attacking me, saying that my articles are very basic and lack depth – they are my fate of the black spots, do not believe you search “Silent King ii”, you will see their boring attack.

I just want to ask, why, the introductory article has the needs of the introductory group, and I happen to help such a large number of beginners, I should be praised, ok?

(said good don’t care, how care up? Manual dog head)

What the hell, go ahead and stay true to your original intention! This article is about Log4j, the granddaddy of print logging. Logging in Java is an art form, I assure you.

It turns out that printing logs definitely affects program performance, and there’s no denying that it’s one more job. Especially in applications with a lot of transactions, it can be inefficient to flood them with logs.

For performance reasons, it’s important to learn how to gracefully print Java logs. After all, performance is an important factor in determining whether a programmer is good or not.

01. Why do I need to print logs in Java

System.out.println() is probably the most common way to print a log when learning Java. Almost every Java beginner has done this, even some old ones.

The reason for printing logs in this way is that it is very convenient and difficult to get started, especially with the help of IDEA, just press the two letters so on the keyboard to call system.out.println ().

In a local environment, it is fine to print logs using system.out.println (), and you can see the information on the console. In production, system.out.println () becomes useless.

The information printed by the console is not saved to the log file and can only be viewed immediately. It is acceptable in the case of a single screen of logs. If the log volume is very large, the console will not fit at all. More advanced logging apis (such as Log4j and java.util.logging) are required.

They can store a large amount of log information in a file and control the size of each file. If it is full, it is stored in the next file for easy lookup.

02. Select the importance of different log levels

When using Java logs, it is important to pay attention to the log levels, such as common DEBUG, INFO, WARN, and ERROR.

The DEBUG level is the lowest. This level is used to print debugging information. It is not recommended in the production environment.

The INFO level is higher and is used when important information needs to be printed.

WARN, which records warning information such as client and server disconnection or database connection loss.

ERROR is of a higher level than WARN and is used to record errors or exceptions.

FATAL, used when a program has a FATAL error, meaning that the program may have stopped abnormally.

OFF, the highest level, means that no messages will be output.

This level is based on Log4j, as opposed to java.util.logging, which provides more logging levels such as SEVERE, FINER, and FINEST.

03. How does error logging affect performance

Why does bad logging affect program performance? The more times you log, the more times you perform file IO operations, which can affect application performance.

While the upgrade to a solid state drive has made reading and writing speed much faster, the disk is still too slow for memory and CPU. It’s like the speed difference between a horse-drawn carriage and a Mercedes.

This is why it is important to choose a log level. Logging is mandatory for programs, so all you can control is the level of logging, and what logs are printed at that level.

For DEBUG level logs, be sure to use the following methods:

if(logger.isDebugEnabled()){ 
    logger.debug("DEBUG is on"); 
} 
Copy the code

Print logs only when the DEBUG level is enabled, which is common when you look at a lot of source code.

Keep in mind that in a production environment, you should never enable DEBUG level logging. Otherwise, your program will slow down while logging a lot, and it may explode disk space without you noticing.

04. Why Log4j rather than Java.util.logging

Java.util. logging is a native logging API and Log4j is a third-party library, but I recommend using Log4j because it is better to use. Java.util. logging has more logging levels than Log4j, but is unnecessary.

Another benefit of Log4j is the flexibility of adjusting the logging level without having to restart the Java program. You can configure log4j’s log level, output environment, and log file recording mode using the log4j.properties file.

Log4j is also thread-safe and can be used safely in multi-threaded environments.

Let’s take a look at how java.util.logging is used:

package com.itwanger;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/ * * *@authorWechat search "silent King 2", reply keyword PDF */
public class JavaUtilLoggingDemo {
    public static void main(String[] args) throws IOException {
        Logger logger = Logger.getLogger("test");
        FileHandler fileHandler = new FileHandler("javautillog.txt");
        fileHandler.setFormatter(new SimpleFormatter());
        logger.addHandler(fileHandler);
        logger.info("Little messages."); }}Copy the code

A javautillog. TXT file is generated in the target directory as follows: javautillog.txt

Again, take a look at how Log4j is used.

The first step is to introduce the Log4j package into the POM.xml file:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
Copy the code

Second, create a log4j.properties file in the Resources directory as follows:

Set # # # # # # log4j. RootLogger = debug, stdout, D, E to the console # # # # # # outputs, 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 = [% - 5 p] % d {MM - dd yyyy - HH: MM: ss, SSS} method: % l % n % m % n # # # the DEBUG output Level above the log to = debug. The log # # # log4j. Appender. D = org.. Apache log4j. DailyRollingFileAppender log4j. Appender. D.F ile. = the 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 to = ERROR. The ERROR level above the log 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%nCopy the code

1) Configure the root Logger with the syntax as follows:

Log4j. rootLogger = [level], appenderName, appenderName,...Copy the code

Level indicates the log priority, including ERROR, WARN, INFO, and DEBUG in descending order. If INFO is defined here, low-level DEBUG log messages will not be printed.

An appenderName is a place to export log information to. Multiple places can be specified. The current configuration file has three places: stdout, D, and E.

2) Configure the log output destination. The syntax is as follows:

Log4j. Appender. AppenderName = fully. Qualified.. The name of the appender. Class log4j. Appender. AppenderName. Option1 = value1... log4j.appender.appenderName.option = valueNCopy the code

Log4j provides the following five destinations:

  • Org, apache log4j. ConsoleAppender: console
  • Org, apache log4j. FileAppender: file
  • Org, apache log4j. DailyRollingFileAppender: every day to create a file
  • Org, apache log4j. RollingFileAppender: file size over threshold to create a new file
  • Org, apache log4j. WriterAppender: the log information in any of stream format sent to the designated place

3) Configure the format of log information. The syntax is as follows:

log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class log4j.appender.appenderName.layout.option1 = Value1... log4j.appender.appenderName.layout.option = valueNCopy the code

Log4j provides the following four formats:

  • Org, apache log4j. HTMLLayout: HTML form
  • Org, apache log4j. PatternLayout: custom
  • Org, apache log4j. SimpleLayout: string contains log information level and information
  • Org, apache log4j. TTCCLayout: contains the logs generated time, threads, categories, etc

The parameters of the custom format are as follows:

  • %m: Outputs the message specified in the code
  • %p: indicates the output priority
  • %r: indicates the number of milliseconds spent from the start of the application to the output of the log information
  • %c: The full name of the output class
  • %t: indicates the name of the thread where the log is generated
  • %n: outputs a carriage return newline character
  • %d: indicates the time when logs are outputted
  • %l: indicates the location of the output log, including the class name, thread name, method name, and line of code, for example:method:com.itwanger.Log4jDemo.main(Log4jDemo.java:14)

Step 3: Write a Demo:

package com.itwanger;

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

/ * * *@authorWechat search "silent King 2", reply keyword PDF */
public class Log4jDemo {
    private static final Logger logger = LogManager.getLogger(Log4jDemo.class);

    public static void main(String[] args) {
        // Records debug information
        logger.debug("debug.");

        // Record info level information
        logger.info("info.");

        // Record information at the error level
        logger.error("error."); }}Copy the code

1) Get the Logger object

To use Log4j, you need to get the Logger object, which is responsible for printing the log information. The usual format is as follows:

private static final Logger logger = LogManager.getLogger(Log4jDemo.class);
Copy the code

2) Print logs

Once you have a Logger object, you can print logs with different priorities. There are four common ones:

Logger.debug() ;  
Logger.info() ;  
Logger.warn() ;  
Logger.error() ;
Copy the code

After the program runs, two files are generated in the target directory, one is called debug.log, and the contents are as follows:

2020-10-20 20:53:27  [ main:0 ] - [ DEBUG ]  debug.
2020-10-20 20:53:27  [ main:3 ] - [ INFO ]  info.
2020-10-20 20:53:27  [ main:3 ] - [ ERROR ]  error.
Copy the code

The other one, called error.log, looks like this:

2020-10-20 20:53:27  [ main:3 ] - [ ERROR ]  error.
Copy the code

8 Tips for Printing a Journal

1) Use isDebugEnabled() when printing DEBUG level logs! That little friends must be very curious, why do this?

IsDebugEnabled ();

  public
  boolean isDebugEnabled(a) {
    if(repository.isDisabled( Level.DEBUG_INT))
      return false;
    return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
  }
Copy the code

Internally the isDisabled() method is used to determine the log level. If DEBUG isDisabled, return false.

Debug () ¶

  public
  void debug(Object message) {
    if(repository.isDisabled(Level.DEBUG_INT))
      return;
    if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
      forcedLog(FQCN, Level.DEBUG, message, null); }}Copy the code

Why, isDisabled()? Isn’t using isDebugEnabled() gilding the lily? Doesn’t it smell good to just use Logger.debug ()? Let me explain this to you guys.

If we need to attach a method to get the parameter value when we print the log message, it looks like this:

logger.debug("Username is:" + getName());
Copy the code

If the getName() method takes up to 6 seconds, that’s it! Even though the log level in the configuration file is defined as INFO, the getName() method still executes for a stubborn 6 seconds and then debug(), which is a crash!

Debug () is not executed, which means that getName() does not need to be executed.

if(logger.isDebugEnabled()) {
    logger.debug("Username is:" + getName());
}
Copy the code

Make sure getName() is not executed, right?

For performance reasons, isDebugEnabled() becomes necessary! If debug() is not passed, there is no need to check whether debug is enabled.

2) Choose the printing level of the log message carefully, because it is too important! If logs are the only way to see what is wrong with the program, the necessary information must be printed, but printing too much will affect the performance of the program.

So, the INFO () of this INFO, the DEBUG () of this DEBUG, don’t just use it.

3) Use Log4j instead of System.out, system.err, or e.printStackTrace() to print logs for reasons discussed earlier.

4) Use the log4j.properties file to configure logging, although it is not required and it makes the application more flexible and has a mey-own-me feel.

5) Don’t forget to print the log with the full name of the class and the name of the thread. This is especially important in a multi-threaded environment, otherwise it will be too difficult to locate problems.

6) print log information as far as possible to complete, don’t too default, especially in the case of an exception or error (information to keep two classes: information can be found at the scene of the crime and the exception stack information, if you don’t do processing, thrown up by throws keywords), so that when find problems are some useless log information.

For example, add DB_LOG to all database-level logs. If the logs are very large, you can quickly locate them by running Linux grep.

8) Do not print sensitive information such as passwords and bank accounts in log files.

06,

Printing logs is a real art that can seriously affect server performance. The scariest part is that you keep a log, but it doesn’t work. What a god! Especially in the production environment, the problem is not recorded, but the recurrence has a certain randomness, to that time, it is really called every day should not, called the ground does not work!

Well, I’ve already written the entire logging system, including Log4j, SLF4J, Logback, Log4j and its younger brother Log4j 2, but I think it’s better for SEO to write them separately. If you do need to see the full version, which I have kindly prepared for you, click on the link below to download the PDF:

Pan.baidu.com/s/1dPwsQhT5… The extracted code: fxxy

Code word is not easy, daily request a like, move a goldfinger, bug one less (escape.