When it's empty , I would sneak in a group , To every move of my friends 、 Word by word screening diagnosis . A head teacher's sense of immediacy , It makes me feel very happy , It's a little bit boring .
see , I found such a series of chatting records among readers during the Warring States period :
Even a little partner didn't know “ Log ” What does that mean? , I don't know how to learn , And the little friend said , Only know Log4j!
For a moment , I took 10000 critical hits , I feel so sad in my heart , Like a despondent dog . Because there are always some malicious people attacking me on the Internet , Tell me about the introduction to my article , No depth —— They are the sunspots of my destiny , If you don't believe it, search for it “ Silent king two ”, You can see their insipid attack .
I just want to ask , What's up? , The entry article has the entry group need , And I happened to help such a large number of beginners , I should be praised, OK ?
( I don't care what I said , Why do you care about it ? Manual formation )
What about him , I did it my way Well , It's right to keep your original mind ! This article will talk about Log4j, The originator of this print log .Java The journal printing in is actually an art work , by my troth , This sentence is by no means a hoax .
The fact proved that , Printing log will affect the performance of the program , This is undeniable , After all, one more job . Especially in programs where transactions are very frequent , It's really inefficient to have a lot of logs .
Based on performance considerations , It's necessary for my friends to learn how to print gracefully Java journal . After all , performance It is an important consideration whether a programmer is good or not .
01、 Why do you need to be in Java Print log in
System.out.println()
I'm afraid we are learning Java When , The most common way to print a log , Almost every Java All beginners have done this , Even some old birds .
The reason why the log is printed like this , Because it's convenient , It's very difficult to get started , Especially in IDEA With the help of the , Just press... On the keyboard so
Two letters will call up System.out.println()
.
In the local environment , Use System.out.println()
It's OK to print the log , You can see the information on the console . But if it's in a production environment ,System.out.println()
It becomes useless .
The information printed out by the console is not saved to the log file , Can only be viewed instantly , In the case of one screen log, you can also accept . If the log volume is very large , The console doesn't fit . So you need more advanced logging API( such as Log4j and java.util.logging).
They can save a lot of log information to files , And control the size of each file , If the full , Just store it to the next one , Easy to find .
02、 The importance of choosing different log levels
Use Java In the Journal , Be sure to pay attention to the level of the log , For example, the common DEBUG、INFO、WARN and ERROR.
DEBUG The lowest level , When you need to print debugging information , Use this level , It is not recommended to use in a production environment .
INFO Higher level , When important information needs to be printed , Just use this. .
WARN, Used to record some warning information , For example, the connection between the client and the server is disconnected , Database connection lost .
ERROR Than WARN A higher level , Information used to record errors or exceptions .
FATAL, Use when a program has a fatal error , This means that the program may have stopped abnormally .
OFF, highest level , It means that all messages will not be output .
This level is based on Log4j Of , and java.util.logging Somewhat different , The latter provides more logging levels , for instance SEVERE、FINER、FINEST.
03、 How bad logging affects performance
Why does the wrong logging affect the performance of the program ? Because the more times you log , It means executing files IO The more times you operate , This means that it will affect the performance of the program , can get Well ?
Although the ordinary hard disk upgrade to solid-state disk , Reading and writing speed is much faster , But disk is relative to memory and CPU Come on , Still too slow ! It's like the speed gap between a carriage and a Benz .
That's why it's important to choose the log level . For the program , Logging is required , So what you can control is the level of the log , And the logs printed at this level .
about DEBUG Level of the log , Be sure to record in the following way :
if(logger.isDebugEnabled()){
logger.debug("DEBUG Is open ");
}
When DEBUG The level is to print the log when it is on , This way can be found when you look at a lot of source code , Very common .
Bear in mind , In production environment , Never turn it on DEBUG Level of logging , Otherwise, the program will slow down when it logs a lot , There's also the possibility that you don't notice , Quietly bursting disk space .
04、 Why choose Log4j instead of java.util.logging
java.util.logging Native log API,Log4j Belongs to the third party class library , But I suggest using Log4j, because Log4j Better to use .java.util.logging Log level ratio of Log4j more , But you don't have to , It becomes redundant .
Log4j Another good thing about , No need to restart Java The program can adjust the level of logging , Very flexible . Can pass log4j.properties File to configure Log4j Log level of 、 Output environment 、 How log files are recorded .
Log4j Is it thread safe , It can be used safely in a multithreaded environment .
Let's take a look first java.util.logging How to use :
package com.itwanger;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* @author Wechat search 「 Silent king two 」, Reply key 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 information ");
}
}
The program will run in target Create a directory called javautillog.txt The file of , The contents are shown below :
Let's take a look at Log4j How to use .
First step , stay pom.xml Introduce in the file Log4j package :
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
The second step , stay resources Create under directory log4j.properties file , The contents are shown below :
### Set up ###
log4j.rootLogger = debug,stdout,D,E
### Output information to console ###
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 = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### Output DEBUG Log above level to =debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = 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 ERROR Log above level to =error.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%n
1) Configuration root Logger, The syntax is shown below :
log4j.rootLogger = [ level ] , appenderName, appenderName, …
level It's the priority of the log , The order from high to low is ERROR、WARN、INFO、DEBUG. If this is defined as INFO, So low level DEBUG Log information will not be printed out .
appenderName It refers to where to output log information , You can specify multiple places , The current configuration file contains 3 A place to , Namely stdout、D、E.
2) Configure the destination of the log output , The syntax is shown below :
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.option = valueN
Log4j The following destinations are offered 5 Kind of :
- org.apache.log4j.ConsoleAppender: Console
- org.apache.log4j.FileAppender: file
- org.apache.log4j.DailyRollingFileAppender: Produce a file every day
- org.apache.log4j.RollingFileAppender: A new file is generated when the file size exceeds the threshold
- org.apache.log4j.WriterAppender: Send log information in stream format to any specified place
3) Configure the format of log information , The syntax is shown below :
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.option = valueN
Log4j The format provided is as follows 4 Kind of :
- org.apache.log4j.HTMLLayout:HTML form
- org.apache.log4j.PatternLayout: Customize
- org.apache.log4j.SimpleLayout: Contains the level of log information and the information string
- org.apache.log4j.TTCCLayout: Include the time when the log was generated 、 Threads 、 Categories and so on
The parameters of the custom format are as follows :
- %m: The message specified in the output code
- %p: Output priority
- %r: The number of milliseconds it took to output the log information from the start of the output application
- %c: Output the full name of the class
- %t: Output the name of the thread where the log is located
- %n: Output a carriage return line feed
- %d: The point in time when the log is output
- %l: Where the output log occurs , Including the name of the class 、 The thread of 、 Method name 、 Lines of code , such as :
method:com.itwanger.Log4jDemo.main(Log4jDemo.java:14)
The third step , Write a usage Demo:
package com.itwanger;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
* @author Wechat search 「 Silent king two 」, Reply key PDF
*/
public class Log4jDemo {
private static final Logger logger = LogManager.getLogger(Log4jDemo.class);
public static void main(String[] args) {
// Record debug Level information
logger.debug("debug.");
// Record info Level information
logger.info("info.");
// Record error Level information
logger.error("error.");
}
}
1) obtain Logger object
To use Log4j Words , You need to get Logger object , It is used to print log information . The usual format is as follows :
private static final Logger logger = LogManager.getLogger(Log4jDemo.class);
2) Print log
With Logger After the object , You can print the log according to different priorities . The common ones are the following 4 Kind of :
Logger.debug() ;
Logger.info() ;
Logger.warn() ;
Logger.error() ;
The program will run in target Two files are generated in the directory , A man named debug.log, The contents are shown below :
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.
The other is called error.log, The contents are shown below :
2020-10-20 20:53:27 [ main:3 ] - [ ERROR ] error.
05、 Print log's 8 A little trick
1) In print DEBUG Level of logging , Remember to use isDebugEnabled()
! The guys must be very curious , Why do this ?
Let's take a look first isDebugEnabled()
Method source code :
public
boolean isDebugEnabled() {
if(repository.isDisabled( Level.DEBUG_INT))
return false;
return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
}
Internal use isDisabled()
Method to judge the log level , If DEBUG If it's forbidden , Just return false 了 .
Let's take a look at debug()
Method source code :
public
void debug(Object message) {
if(repository.isDisabled(Level.DEBUG_INT))
return;
if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
forcedLog(FQCN, Level.DEBUG, message, null);
}
}
Why , It doesn't work isDisabled()
Method judgment ? Don't use isDebugEnabled()
Isn't it just to add to the lily ? Direct use logger.debug()
Is it not fragrant ? Let me explain to my friends .
If we need to attach a method to get the parameter value when printing log information , It looks like this :
logger.debug(" User name is :" + getName());
If getName()
The method takes as long as 6 second , That's over ! Although the log level in the configuration file defines INFO,getName()
The method will still carry out stubbornly 6 second , After that debug()
, It's going to collapse !
Mingming INFO When debug()
It's not enforced , signify getName()
It doesn't need to be implemented , But it was executed 6 second , Isn't it stupid ?
if(logger.isDebugEnabled()) {
logger.debug(" User name is :" + getName());
}
Change to the way above , So make sure this is the moment getName()
It's not enforced , Right ?
For the sake of program performance ,isDebugEnabled()
It becomes necessary ! If say debug()
There was no reference , There is no need to judge DEBUG Is enabled .
2) Choose the printing level of log information carefully , Because it's so important ! If you can only use the log to see what's wrong with the program , The necessary information must be printed , But it prints too much , It will affect the performance of the program .
therefore , The INFO Of info()
, The DEBUG Of debug()
, Don't use it casually .
3) Use Log4j instead of System.out
、System.err
perhaps e.printStackTrace()
To print logs , The reason has been mentioned before , I won't go back to .
4) Use log4j.properties File to configure the log , Even though it's not required , Using this file makes the program more flexible , There's a taste of my own territory that I'm in charge of .
5) Don't forget to print the log with the full name of the class and the thread name , In multithreaded environment , This is especially important , Otherwise, it will be too difficult to locate the problem .
6) Try to be complete when printing log information , Don't be too default , Especially when there are exceptions or errors ( There are two types of information to keep : Crime scene information and exception stack information , If you don't do it , adopt throws Keywords up ), In order to avoid some useless log information when looking for problems .
7) To distinguish between log information , Add a prefix to the output of a certain type of log information , For example, add... To all database level logs DB_LOG
, When such a log is very large, you can use grep
In this way Linux Command quick positioning .
8) Don't print the password in the log file 、 Bank account number and other sensitive information .
06、 summary
Printing a journal is really an art work , It will seriously affect the performance of the server . The most terrible thing is , Logged , But it turns out that fart doesn't work , It's just a day ! Especially in the production environment , The problem is not recorded , But there is a certain randomness in the recurrence , By then , It's really called that every day should not , It's not working !
Uh huh , Actually, I've finished writing the entire log system , Include Log4j、 SLF4J、Logback、Log4j His brother Log4j 2, But I think if I send them separately , More favorable SEO( Look at my heart for the flow , Manual formation ). If you really need to see the full version , I have also prepared for you , Click on the link below to download PDF:
https://pan.baidu.com/s/1dPwsQhT5OMVapE7hGi7vww Extraction code :fxxy
It's not easy to code words , Ask for a compliment every day , Move your golden finger ,bug One less ( flee .