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
- initialization LogManager
- LogManager load logging.properties To configure
- add to Logger To LogManager
- From the single example LogManager obtain Logger
- Set level Level, And specify logging LogRecord
- Filter Provides more granular control beyond the log level
- Handler Is used to process the log output location
- 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