编程知识 cdmana.com

Java log interpretation

Java journal

Understanding of log facade and log framework

​ The log facade is like a waiter in a hotel , The log frame is like a cook in the back kitchen . For the customer application , I'll order at the hotel , I just need to tell the waiter I want a plate of scrambled eggs with tomatoes , I don't care about everything in the kitchen . Because although the chef calls this dish 『 fried eggs with tomatoes 』A Instead, the chef called the dish 『 Scrambled egg with tomato 』 Of B The cook . however , Customers don't need to care , He just gives 『 fried eggs with tomatoes 』 Give your order to the waiter , It's OK for the waiter to translate it to the cook .

therefore , For someone who knows ” There are many names for scrambled eggs with tomatoes ” For the waiter , No matter how the cook changes , He can accurately help users place orders .

The existing logging framework

JUL(java util logging)、logback、log4j、log4j2
JCL(Jakarta Commons Logging) Also known as Commons-Logging、slf4j( Simple Logging Facade for Java)

Log facade
JCL、slf4j
Log implementation
JUL、logback、log4j、log4j2

1 JUL

JUL Full name Java util Logging yes java Native logging framework , There is no need to refer to a third-party library when using it , Compared with other log frameworks, it is easy to use , Learn easy , It can be used flexibly in small applications .

Blog to explain the source code

https://blog.csdn.net/qq8266734465/article/details/87629392

1.1 Introductory cases

//  Quick start 
@Test
public void testQuick()throws Exception{
    
    // 1. Get the logger object 
    Logger logger = Logger.getLogger("com.itheima.JULTest");
    // 2. Log output 
    logger.info("hello jul");

    //  General methods for logging 
    logger.log(Level.INFO,"info msg");


    //  Through placeholders   Output variable values in the same way 
    String name = "itcast";
    Integer age = 13;
    logger.log(Level.INFO," User information :{0},{1}",new Object[]{
    name,age});

}

Output results

5 month  04, 2022 12:57:28  Afternoon  com.itheima.JULTest testQuick
 Information : hello jul
5 month  04, 2022 12:57:28  Afternoon  com.itheima.JULTest testQuick
 Information : info msg
5 month  04, 2022 12:57:28  Afternoon  com.itheima.JULTest testQuick
 Information :  User information :itcast,13

1.2 The level of logging

* java.util.logging.Level The log level is defined in :
    SEVERE( Maximum value )
    WARNING
    INFO ( Default level )
    CONFIG
    FINE
    FINER
    FINEST( The lowest value )
*  There are two special levels :
    OFF, Can be used to turn off logging .
    ALL, Enable logging of all messages .

//  The level of logging 
@Test
public void testLogLevel()throws Exception{
    
    // 1. Get the logger object 
    Logger logger = Logger.getLogger("com.itheima.JULTest");
    // 2. Log output 
    logger.severe("severe");
    logger.warning("warning");
    logger.info("info"); //  Default log output level 
    logger.config("config");
    logger.fine("fine");
    logger.finer("finer");
    logger.finest("finest");

}

Output results

5 month  04, 2022 12:58:48  Afternoon  com.itheima.JULTest testLogLevel
 serious : severe
5 month  04, 2022 12:58:48  Afternoon  com.itheima.JULTest testLogLevel
 Warning : warning
5 month  04, 2022 12:58:48  Afternoon  com.itheima.JULTest testLogLevel
 Information : info

Default output info Above level

1.3 Custom log level

//  Custom log level 
@Test
public void testLogConfig()throws Exception{
    
    // 1. Get the logger object 
    Logger logger = Logger.getLogger("com.itheima.JULTest");


    //  Turn off system default configuration 
    logger.setUseParentHandlers(false);

    //  Custom configuration log level 
    //  establish ConsolHhandler  Console output 
    ConsoleHandler consoleHandler = new ConsoleHandler();

    //  Create a simple format conversion object 
    SimpleFormatter simpleFormatter = new SimpleFormatter();

    //  Association 
    consoleHandler.setFormatter(simpleFormatter);
    logger.addHandler(consoleHandler);


    //  Configure the specific log level 
    logger.setLevel(Level.ALL);
    consoleHandler.setLevel(Level.ALL);


    //  scene FileHandler  File output 
    FileHandler fileHandler = new FileHandler("/logs/jul.log");

    //  Association 
    fileHandler.setFormatter(simpleFormatter);
    logger.addHandler(fileHandler);

    // 2. Log output 
    logger.severe("severe");
    logger.warning("warning");
    logger.info("info"); //  Default log output level 
    logger.config("config");
    logger.fine("fine");
    logger.finer("finer");
    logger.finest("finest");

}

Output results

5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 serious : severe
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 serious : severe
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 Warning : warning
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 Warning : warning
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 Information : info
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 Information : info
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 To configure : config
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 detailed : fine
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 More detailed : finer
5 month  04, 2022 1:08:02  Afternoon  com.itheima.JULTest testLogConfig
 Very detailed : finest

1.4 Logger Father son relationship between

​ JUL in Logger There's a father son relationship between them , This parent-child relationship is stored in a tree structure ,JUL A top-level is created during initialization RootLogger As all Logger Father Logger, Store as the root node of the tree structure . And the parent-child relationship is related through a path .

// Logger Object parent-child relationship 
@Test
public void testLogParent()throws Exception{

    Logger logger1 = Logger.getLogger("com.itheima");
    Logger logger2 = Logger.getLogger("com");

    //  test 
    System.out.println(logger1.getParent() == logger2);
    //  Top level parent of all loggers  LogManager$RootLogger,name ""
    System.out.println("logger2 Parent:"+logger2.getParent() + ",name:" + logger2.getParent().getName());

    //  Turn off the default configuration 
    logger2.setUseParentHandlers(false);

    //  Set up logger2 The level of logging 
    //  Custom configuration log level 
    //  establish ConsolHhandler  Console output 
    ConsoleHandler consoleHandler = new ConsoleHandler();

    //  Create a simple format conversion object 
    SimpleFormatter simpleFormatter = new SimpleFormatter();

    //  Association 
    consoleHandler.setFormatter(simpleFormatter);
    logger2.addHandler(consoleHandler);


    //  Configure the specific log level 
    logger2.setLevel(Level.ALL);
    consoleHandler.setLevel(Level.ALL);

    logger1.severe("severe");
    logger1.warning("warning");
    logger1.info("info");
    logger1.config("config");
    logger1.fine("fine");
    logger1.finer("finer");
    logger1.finest("finest");
}

Output results

true
logger2  Parent:[email protected],name:

5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 serious : severe
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 Warning : warning
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 Information : info
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 To configure : config
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 detailed : fine
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 More detailed : finer
5 month  04, 2022 1:09:02  Afternoon  com.itheima.JULTest testLogParent
 Very detailed : finest

Try creating it yourself

Logger logger3 = Logger.getLogger("com.itheima.JULTest");
System.out.println(logger3.getParent()==logger1);
System.out.println(logger3.getParent().getParent()==logger2);
true
true

Find out JUL A top-level is created during initialization RootLogger( In fact, the name of the package is the beginning )

1.5 Load custom configuration file

//  Load custom configuration file 
@Test
public void testLogProperties()throws Exception{
    

    //  Read configuration file , Through class loader 
    InputStream ins = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
    //  establish LogManager
    LogManager logManager = LogManager.getLogManager();
    //  adopt LogManager Load profile 
    logManager.readConfiguration(ins);

    //  Create a logger 
    Logger logger = Logger.getLogger("com.itheima");

    logger.severe("severe");
    logger.warning("warning");
    logger.info("info");
    logger.config("config");
    logger.fine("fine");
    logger.finer("finer");
    logger.finest("finest");

}

logging.properties

# RootLogger  The default processor specified by the top-level parent element is :ConsoleHandler
handlers= java.util.logging.FileHandler

# RootLogger  The default log level of the top-level parent element is :ALL
.level= ALL

#  Customize  Logger  Use 
com.itheima.handlers = java.util.logging.ConsoleHandler
com.itheima.level = CONFIG

#  Turn off the default configuration 
com.itheima.useParentHanlders = false


#  Output to log file  handler  object 
#  Specify the log file path  /logs/java0.log
java.util.logging.FileHandler.pattern = /java%u.log
#  Specifies the log file content size 
java.util.logging.FileHandler.limit = 50000
#  Specify the number of log files 
java.util.logging.FileHandler.count = 1
#  Appoint  handler  Object log message format object 
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
#  Specifies that the log content is appended 
java.util.logging.FileHandler.append = true


#  Output to the console  handler  object 
#  Appoint  handler  The log level of the object 
java.util.logging.ConsoleHandler.level = ALL
#  Appoint  handler  The log message format object of the 
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
#  Appoint  handler  The character set of the object 
java.util.logging.ConsoleHandler.encoding = UTF-8

#  Specify the log message format 
java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n

1.6 Log principle analysis

  1. initialization LogManager
    1. LogManager load logging.properties To configure
    2. add to Logger To LogManager
  2. From the single example LogManager obtain Logger
  3. Set level Level, And specify logging LogRecord
  4. Filter Provides more granular control beyond the log level
  5. Handler Is used to process the log output location
  6. Formatter It's used to format LogRecord Of

[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-19XeDXUl-1652095248574)(C:\Users\HONOR\AppData\Roaming\Typora\typora-user-images\image-20220504131805304.png)]

2 Log4j

​ Log4j yes Apache Under an open source log framework , By using Log4J, We can control the log information output to the console 、 file 、 Even in the database . We can control the output format of each log , By defining the output level of the log , It can control the output process of log more flexibly . Convenient for project debugging .
Official website : http://logging.apache.org/log4j/1.2/

2.0 Log4j Guide package is required for use

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

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

2.1 Introductory cases

@Test
public void testQuick1() throws Exception {
    
    //  Initialize system configuration , No profile required 
    BasicConfigurator.configure();
    //  Create a logger object 
    Logger logger = Logger.getLogger(Log4jTest.class);
    //  Log output 
    logger.info("hello log4j");
    //  The level of logging 
    logger.fatal("fatal"); //  Serious mistakes , Generally, it will cause system crash and termination 
    logger.error("error"); //  error message , But it will not affect the operation of the system 
    logger.warn("warn"); //  Warning message , There may be problems 
    logger.info("info"); //  Program running information , Database connection 、 The Internet 、IO Operation etc. 
    logger.debug("debug"); //  Debugging information , Generally used in the development phase , Record program variables 、 Parameters, etc. 
    logger.trace("trace"); //  Tracking information , Record all process information of the program 
}

Output results

0 [main] INFO com.itheima.Log4jTest  - hello log4j
4 [main] FATAL com.itheima.Log4jTest  - fatal
4 [main] ERROR com.itheima.Log4jTest  - error
5 [main] WARN com.itheima.Log4jTest  - warn
6 [main] INFO com.itheima.Log4jTest  - info
6 [main] DEBUG com.itheima.Log4jTest  - debug

2.3 Level of logging

*  Every Logger It's all at a log level (log level), Used to control the output of log information . Log level from high to low 
 by :
    fatal  Point out that each serious error event will cause the application to exit .
    error  Point out that in spite of the wrong Events , But it still does not affect the continued operation of the system .
    warn  Indicates a potential error situation .
    info  Generally and at the coarse-grained level , Emphasize the whole process of the application .
    debug  Generally used at the fine-grained level , Great for debugging applications .
    trace  It's program tracking , It can be used to output variables in the running program , Displays the process executed .
*  There are two special levels :
    OFF, Can be used to turn off logging .
    ALL, Enable logging of all messages .

notes : Generally only used 4 A level , The priority is from high to low ERROR > WARN > INFO > DEBUG

2.4 Log4j Components

Log4J Mainly by Loggers ( Loggers )、**Appenders( Output terminal )** and Layout( Log formatter ) form .
Loggers
Control the output level of the log and whether the log is output ;

Appenders Specify the output mode of the log ( Output to console 、 Documents, etc. );

Layout Control the output format of log information .

2.4.1 Loggers

​ Loggers , Responsible for collecting and processing log records , An instance is named as a class “XX” Of full quailied name( The fully qualified name of the class ),Logger Is case sensitive , Its naming has inheritance mechanism : for example :name by org.apache.commons Of logger Will inherit Name by org.apache Of logger.
​ Log4J There's a special logger be called “root”, He is everything logger The root of the , That means everything else logger Will inherit directly or indirectly from root.root logger It can be used Logger.getRootLogger() Method to get .
​ however , since log4j 1.2 Since Edition , Logger Classes have replaced Category class . For those familiar with earlier versions of log4j For people who ,Logger Classes can be treated as Category Alias of class .

Customize Logger

# RootLogger To configure 
log4j.rootLogger = trace,console
#  Customize Logger
log4j.logger.com.itheima = info,file
log4j.logger.org.apache = error

2.4.2 Appenders

Appender Used to specify where the log is output , You can also specify the output destination of the log .Log4j Common output destinations
There are the following :

Output class effect
ConsoleAppender Output the log to the console
FileAppender Output the log to a file
DailyRollingFileAppender Output the log to a log file , And output to a new file every day
RollingFileAppender Output log information to a log file , And specify the size of the file , When the file size reaches the specified size , Will automatically change the name of the file , At the same time, a new file is generated
DBCAppenderJ Save the log information to the database

Appender Output ==> Console , file , database

# Specify the output level and output end of the log 
log4j.rootLogger=INFO,Console
#  Console output configuration 
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#  File output configuration 
log4j.appender.A = org.apache.log4j.DailyRollingFileAppender
# Specify the output path of the log 
log4j.appender.A.File = D:/log.txt
log4j.appender.A.Append = true
# Use custom log formatter 
log4j.appender.A.layout = org.apache.log4j.PatternLayout
# Specifies the output format of the log 
log4j.appender.A.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] -
[%p] %m%n
# Specifies the file encoding for the log 
log4j.appender.A.encoding=UTF-8

#mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Sql=INSERT INTO
log(project_name,create_date,level,category,file_name,thread_name,line,all_categ
ory,message) values('itcast','%d{yyyy-MM-dd
HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

2.4.3 Layouts

Layout device Layouts Used to control the format of the log output , Let's output logs in various formats we need .Log4j Commonly used
Of Layouts:

Formatter type effect
HTMLLayout Format the log output as HTML Form
SimpleLayout Simple log output format , The format of the printed log is (info - message)
PatternLayout The most powerful formatting period , You can output the log according to the custom format , If no conversion format is specified , It's the default conversion format

stay log4j.properties In profile , We define the log output level and output side , Configure the output of logs in the output side
Format .

* log4j  A similar  C  Linguistic  printf  The print format of the function formats the log information , The specific place holder and its meaning are as follows :
    %m  Output the log information specified in the code 
    %p  Output priority , And  DEBUG、INFO  etc. 
    %n  A newline (Windows The newline character of the platform is  "\n",Unix  The platform is  "\n")
    %r  The output starts from the application to the output  log  The number of milliseconds that information takes 
    %c  Output the full name of the class to which the print statement belongs 
    %t  Output the full name of the thread that generated the log 
    %d  Output server current time , The default is  ISO8601, You can also specify the format , Such as :%d{yyyy year MM month dd Japan 
    HH:mm:ss}
    %l  Where the output log time occurs , Including the name of the class 、 Threads 、 And the number of lines in the code . Such as :
    Test.main(Test.java:10)
    %F  The name of the file where the output log message was generated 
    %L  Line number in the output code 
    %%  Output one  "%"  character 
    
    
*  Can be in  %  Add a modifier between the and characters to control the minimum width 、 Maximum width and text on its way . Such as :
    %5c  Output category name , The minimum width is 5,category<5, Right alignment by default 
    %-5c  Output category name , The minimum width is 5,category<5,"-" The number specifies left alignment , There will be spaces 
    %.5c  Output category name , The maximum width is 5,category>5, It will cut off the extra characters on the left ,<5 No 
     There will be spaces 
    %20.30c category name <20 Fill in the blanks , And right ,>30 character , Cut off the characters from the left 

2.5 Practical summary

Test project

private static Logger logger = Logger.getLogger(Test.class);

@Test
public void testQuick2() throws Exception {
    
    // System.out.println("This is println message.");

    //  Record debug Level information 
    logger.debug("This is debug message.");
    //  Record info Level information 
    logger.info("This is info message.");
    //  Record error Level information 
    logger.error("This is error message.");
}

log4j.properties

  Appoint  RootLogger  Top level parent element default configuration information 
#  Specify the log level =trace, The use of  apeender  by =console
log4j.rootLogger = trace,console

#  Customize  logger  Object settings 
log4j.logger.com.itheima = info,console
log4j.logger.org.apache = error

#  Specifies the output of the console log  appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
#  Specify the message format  layout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#  Specify the content of the message format 
log4j.appender.console.layout.conversionPattern = [%-10p]%r  %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n


# %m    Output the log information specified in the code 
# %p    Output priority , And  DEBUG、INFO  etc. 
# %n    A newline (Windows The newline character of the platform is  "\n",Unix  The platform is  "\n")
# %r    The output starts from the application to the output  log  The number of milliseconds that information takes 
# %c    Output the full name of the class to which the print statement belongs 
# %t    Output the full name of the thread that generated the log 
# %d    Output server current time , The default is  ISO8601, You can also specify the format , Such as :%d{yyyy year MM month dd Japan  HH:mm:ss}
# %l    Where the output log time occurs , Including the name of the class 、 Threads 、 And the number of lines in the code . Such as :Test.main(Test.java:10)
# %F    The name of the file where the output log message was generated 
# %L    Line number in the output code 
# %%    Output one  "%"  character 

#  Log file output  appender  object 
log4j.appender.file = org.apache.log4j.FileAppender
#  Specify the message format  layout
log4j.appender.file.layout = org.apache.log4j.PatternLayout
#  Specify the content of the message format 
log4j.appender.file.layout.conversionPattern = [%-10p]%r  %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#  Specify the path to save the log file 
log4j.appender.file.file = /logs/log4j.log
#  Specifies the character set of the log file 
log4j.appender.file.encoding = UTF-8

#=====================================================================
#  Split by file size  appender  object 
#  Log file output  appender  object 
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
#  Specify the message format  layout
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
#  Specify the content of the message format 
log4j.appender.rollingFile.layout.conversionPattern = [%-10p]%r  %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#  Specify the path to save the log file 
log4j.appender.rollingFile.file = /logs/log4j.log
#  Specifies the character set of the log file 
log4j.appender.rollingFile.encoding = UTF-8
#  Specify the size of the log file content 
log4j.appender.rollingFile.maxFileSize = 1MB 
#  Specify the number of log files 
log4j.appender.rollingFile.maxBackupIndex = 10


#  Split according to the rules of time  appender  object 
log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender
#  Specify the message format  layout
log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout
#  Specify the content of the message format 
log4j.appender.dailyFile.layout.conversionPattern = [%-10p]%r  %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#  Specify the path to save the log file 
log4j.appender.dailyFile.file = /logs/log4j.log
#  Specifies the character set of the log file 
log4j.appender.dailyFile.encoding = UTF-8
#  Specify Date splitting rules 
log4j.appender.dailyFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss


#mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=123456
log4j.appender.logDB.Sql=INSERT INTO log(project_name,create_date,level,category,file_name,thread_name,line,all_category,message) values('itcast','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

Be careful If you want to output the data to It needs to be in the root directory log4j.rootLogger add to

for example

Export to database

log4j.rootLogger = trace,console ,logDB

Preparing the database

CREATE TABLE `log` (
`log_id` int(11) NOT NULL AUTO_INCREMENT,
`project_name` varchar(255) DEFAULT NULL COMMENT ' Item name ',
`create_date` varchar(255) DEFAULT NULL COMMENT ' Creation time ',
`level` varchar(255) DEFAULT NULL COMMENT ' priority ',
`category` varchar(255) DEFAULT NULL COMMENT ' The full name of the class ',
`file_name` varchar(255) DEFAULT NULL COMMENT ' The name of the file where the output log message was generated  ',
`thread_name` varchar(255) DEFAULT NULL COMMENT ' The thread name of the log event ',
`line` varchar(255) DEFAULT NULL COMMENT ' Line No ',
`all_category` varchar(255) DEFAULT NULL COMMENT ' Location of log events ',
`message` varchar(4000) DEFAULT NULL COMMENT ' The message specified in the output code ',
PRIMARY KEY (`log_id`)
);

3 JCL Study

Its full name is Jakarta Commons Logging (Commons-Logging), yes Apache A general log provided API.
It is for " be-all Java Log implementation " Provide a unified interface , It also provides an implementation of logging itself , But the function is very often weak
(SimpleLog). So it's not usually used alone . It allows developers to use different specific logging implementation tools : Log4j, Jdk
My own journal (JUL)
JCL There are two basic abstract classes :Log( Basic recorder ) and LogFactory( Responsible for creating Log example ).

The blog explains in detail

https://blog.csdn.net/lingyiwin/article/details/114992351

4 SLF4J

The blog explains in detail

https://blog.csdn.net/lingyiwin/article/details/115054926

5 LOGBACK

5.1 Logback It is mainly divided into three modules :

logback-core: The basic modules of the other two modules
logback-classic: It is log4j An improved version of , At the same time, it completely realizes slf4j API
logback-access: Access module and Servlet Container integration is provided through Http To access the function of the log

The subsequent log code is through SLF4J Log facade to build a log system , So there is no difference in the code , Mainly by modifying the configuration
Document and pom.xml rely on

5.2 pom

dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
<!--junti  unit testing -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

5.3 logback To configure

logback The following types of configuration files will be read in turn :

  • logback.groovy
  • logback-test.xml
  • logback.xml If none exists, the default configuration is used

5.4 test

package com.itheima;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogbackTest {
    

    public static final Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class);
//  Quick start 
    @Test
    public void testQuick()throws Exception{
    

        //  Log output 
        LOGGER.error("error");
        LOGGER.warn("wring");
        LOGGER.info("info");
        LOGGER.debug("debug");//  Default level 
        LOGGER.trace("trace");
    }
}

5.5 logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--  Configure centralized management properties   We can change the attribute directly  value  value   Format :${name} -->
    
     <!--  Log output format : %-5level %d{yyyy-MM-dd HH:mm:ss.SSS} date  %c Full name of the class  %M by method %L Is line number  %thread Thread name  %m perhaps %msg For information  %n Line break  -->
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n"></property>
   
    
   
    
    
    <!-- Define log file save path properties -->
    <property name="log_dir" value="/logs"></property>


    
    
    
    <!-- Console log output  appender-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- Control the output stream object   Default  System.out  Change it to  System.err-->
        <target>System.err</target>
        <!-- Log message format configuration -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>
    
    
    

    <!-- Log file output  appender-->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- Log file save path -->
        <file>${log_dir}/logback.log</file>
        <!-- Log message format configuration -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>
    
    
    

    <!--html  Format log file output  appender-->
    <appender name="htmlFile" class="ch.qos.logback.core.FileAppender">
        <!-- Log file save path -->
        <file>${log_dir}/logback.html</file>
        <!--html  Message format configuration -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>%-5level%d{yyyy-MM-dd HH:mm:ss.SSS}%c%M%L%thread%m</pattern>
            </layout>
        </encoder>
    </appender>
    
    


    <!-- Log splitting and archive compression  appender  object -->
    <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- Log file save path -->
        <file>${log_dir}/roll_logback.log</file>
        <!-- Log message format configuration -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <!-- Specify split rules -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- Declare the split file name according to time and compressed format -->
            <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!-- Split according to file size -->
            <maxFileSize>1MB</maxFileSize>
        </rollingPolicy>
        <!-- Log level filter -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- Log filtering rules -->
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
    

    <!-- Asynchronous log -->
    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <!-- Specify a specific  appender-->
        <appender-ref ref="rollFile"/>
    </appender>


    <!--root logger  To configure -->
    <root level="ALL">
        <appender-ref ref="console"/>
        <appender-ref ref="async"/>
    </root>

    <!-- Customize  looger  object  additivity="false"  Customize  logger  Whether the object inherits  rootLogger -->
    <logger name="com.itheima" level="info" additivity="false">
        <appender-ref ref="console"/>
    </logger>
</configuration>

6 LOG4J2

The blog explains in detail

https://blog.csdn.net/weixin_32265569/article/details/110723441

7 @SLF4J annotation

https://blog.csdn.net/cslucifer/article/details/80953400

8 SpringBoot Journal and AOP

8.0 yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456
# To configure mapper Location of the mapping file for 
mybatis:
  mapper-locations: classpath:mapper/*Dao.xml


#  Print sql
logging:
  level:
    com.atguigu.log.mapper : debug


8.1 pom

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>

    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--log4j2-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>

    </dependency>
    <!-- aop -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
</dependencies>

8.2 Sql

CREATE TABLE `logs`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NULL DEFAULT NULL,
  `user_action` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `create_time` timestamp(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

8.3 pojo

package com.atguigu.log.pojo;

import java.sql.Date;
import java.sql.Timestamp;

public class SysLog {
    

    private Long id;
    private Long user_id;
    private String user_action;
    private Timestamp create_time;

    public Long getId() {
    
        return id;
    }

    public void setId(Long id) {
    
        this.id = id;
    }

    public Long getUser_id() {
    
        return user_id;
    }

    public void setUser_id(Long user_id) {
    
        this.user_id = user_id;
    }

    public String getUser_action() {
    
        return user_action;
    }

    public void setUser_action(String user_action) {
    
        this.user_action = user_action;
    }

    public Timestamp getCreate_time() {
    d
        return create_time;
    }

    public void setCreate_time(Timestamp create_time) {
    
        this.create_time = create_time;
    }
}

8.4 Mapper

package com.atguigu.log.mapper;

import com.atguigu.log.pojo.SysLog;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SysLogMapper {
    

    void insert(SysLog entity);
}

resource/mapper/SysLogDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.log.mapper.SysLogMapper">



    <insert id="insert">
        insert into logs values(#{id},#{user_id},#{user_action},#{create_time});
    </insert>
</mapper>

8.5 service

package com.atguigu.log.service;


import com.atguigu.log.pojo.SysLog;

/** * @author Promise * @createTime 2018 year 12 month 18 Japan   Afternoon 9:29:48 * @description  Log interface  */
public interface SysLogService {
    

    /** *  Inserting log  * @param entity * @return */
    void insertLog(SysLog entity);
}

Impl

package com.atguigu.log.service;


import com.atguigu.log.mapper.SysLogMapper;
import com.atguigu.log.pojo.SysLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("sysLogService")
public class SysLogServiceImpl implements SysLogService {
    

    @Autowired
    private SysLogMapper sysLogMapper;
    @Override
    public void insertLog(SysLog entity) {
    
        // TODO Auto-generated method stub
        sysLogMapper.insert(entity);

    }
}

8.6 Custom annotation

package com.atguigu.log.annotation;



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** * @author Promise * @createTime 2018 year 12 month 18 Japan   Afternoon 9:26:25 * @description  Define a method level @log annotation  */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    
    String value() default "";
}

8.7 section +aop

package com.atguigu.log.aspect;



import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Date;

import com.atguigu.log.annotation.Log;
import com.atguigu.log.pojo.SysLog;
import com.atguigu.log.service.SysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;




/** * @author Promise * @createTime 2018 year 12 month 18 Japan   Afternoon 9:33:28 * @description  Aspect log configuration  */
@Aspect
@Component
public class LogAsPect {
    

    private final static Logger log = org.slf4j.LoggerFactory.getLogger(LogAsPect.class);

    @Autowired
    private SysLogService sysLogService;

    // Represents matching methods with custom annotations 
    @Pointcut("@annotation(com.atguigu.log.annotation.Log)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
    
        Object result =null;
        long beginTime = System.currentTimeMillis();

        try {
    
            log.info(" I execute... Before the target method !");
            result = point.proceed();
            long endTime = System.currentTimeMillis();
            insertLog(point,endTime-beginTime);
        } catch (Throwable e) {
    
            // TODO Auto-generated catch block
        }
        return result;
    }

    private void insertLog(ProceedingJoinPoint point ,long time) {
    
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        SysLog sys_log = new SysLog();

        Log userAction = method.getAnnotation(Log.class);
        if (userAction != null) {
    
            //  The description on the note 
            sys_log.setUser_action(userAction.value());
        }

        //  Requested class name 
        String className = point.getTarget().getClass().getName();
        //  Requested method name 
        String methodName = signature.getName();
        //  Requested method parameter value 
        String args = Arrays.toString(point.getArgs());

        // from session Get the current login from id
// Long useride = (Long)SecurityUtils.getSubject().getSession().getAttribute("userid");

        Long userid = 1L;// It should be from session Get the name of the current login in id, Here's a simple simulation 

        sys_log.setUser_id(userid);
        sys_log.setCreate_time(new java.sql.Timestamp(new Date().getTime()));

        log.info(" Current login person :{}, Class name :{}, Method name :{}, Parameters :{}, execution time :{}",userid, className, methodName, args, time);

        sysLogService.insertLog(sys_log);
    }

    @Pointcut("execution(public * com.atguigu..log.controller..*.*(..))")
    public void pointcutController() {
    }

    @Before("pointcutController()")
    public void around2(JoinPoint point) {
    
        // Get the target method 
        String methodNam = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();

        // Get method parameters 
        String params = Arrays.toString(point.getArgs());

        log.info("get in {} params :{}",methodNam,params);
    }


}

8.8 controller To test

package com.atguigu.log.controller;

import com.atguigu.log.annotation.Log;
import com.atguigu.log.service.SysLogService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class HomeController {
    

    private final static Logger log = org.slf4j.LoggerFactory.getLogger(HomeController.class);

    @RequestMapping("/aop")
    @Log(" test aoplog")
    public Object aop(String name, String nick) {
    
        log.info(" I was executed !");

        return " come on. ";
    }

    @RequestMapping("/hello")
    public String hello(){
    
        return "hello world";
    }
}

8.9 Main startup class

package com.atguigu.log;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@SpringBootApplication
@MapperScan("com.atguigu.log.mapper")
public class SpringbootLogApplication {
    

    public static void main(String[] args) {
    
        SpringApplication.run(SpringbootLogApplication.class, args);
    }
}

8.10 test

① visit localhost:8080/hello

2022-05-04 19:40:18.607  INFO 20780 --- [nio-8080-exec-3] c.a.l.a.LogAsPect                        : get in com.atguigu.log.controller.HomeController.hello params :[]

② visit localhost:8080/aop

2022-05-04 19:29:47.682  INFO 20780 --- [nio-8080-exec-1] c.a.l.a.LogAsPect                        :  I execute... Before the target method !
2022-05-04 19:29:47.686  INFO 20780 --- [nio-8080-exec-1] c.a.l.a.LogAsPect                        : get in com.atguigu.log.controller.HomeController.aop params :[null, null]
2022-05-04 19:29:47.692  INFO 20780 --- [nio-8080-exec-1] c.a.l.c.HomeController                   :  I was executed !
2022-05-04 19:29:47.692  INFO 20780 --- [nio-8080-exec-1] c.a.l.a.LogAsPect                        :  Current login person :1, Class name :com.atguigu.log.controller.HomeController, Method name :aop, Parameters :[null, null], execution time :10
2022-05-04 19:29:47.710  INFO 20780 --- [nio-8080-exec-1] c.z.h.HikariDataSource                   : HikariPool-1 - Starting...
2022-05-04 19:29:47.835  INFO 20780 --- [nio-8080-exec-1] c.z.h.HikariDataSource                   : HikariPool-1 - Start completed.
2022-05-04 19:29:47.842 DEBUG 20780 --- [nio-8080-exec-1] c.a.l.m.S.insert                         : ==>  Preparing: insert into logs values(?,?,?,?);
2022-05-04 19:29:47.874 DEBUG 20780 --- [nio-8080-exec-1] c.a.l.m.S.insert                         : ==> Parameters: null, 1(Long),  test aoplog(String), 2022-05-04 19:29:47.692(Timestamp)
2022-05-04 19:29:47.877 DEBUG 20780 --- [nio-8080-exec-1] c.a.l.m.S.insert                         : <==    Updates: 1
2022-05-04 19:40:18.607  INFO 20780 --- [nio-8080-exec-3] c.a.l.a.LogAsPect                        : get in com.atguigu.log.controller.HomeController.hello params :[]

We found that the method with custom annotation printed the effect we want

版权声明
本文为[Fairy Pavilion]所创,转载请带上原文链接,感谢
https://cdmana.com/2022/134/202205141336579620.html

Scroll to Top