I. Profile multi environment support
1. Multiple Profile files
When we write the main configuration file, the file name can be: application-{profile}.properties/yml
application.properties is used by default
2. yml supports multi document block mode
server: port: 8080 spring: profiles: active: dev ##Activate dev configuration block --- server: port: 8081 spring: profiles: dev --- server: port: 8082 spring: profiles: prod
3. Activate the specified profile
1. Specify spring.profiles.active=dev in the configuration file 2. Activate - Dspring.profiles.active=dev in the JVM parameter 3. Command line java -jar boot-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
II. Configuration file loading location
Spring boot will scan the application.properties or application.yml file in the location as the default configuration file of spring boot
-file:./config/ -file:./ -classpath:/config/ -classpath:/
The above is in the order of priority from high to low. Files in all locations will be loaded, and the high priority configuration content will overwrite the low priority configuration content.
We can also change the default configuration by configuring spring.config.location
3. SpringBoot and log
Common log framework: Jul JCL JBoss logging logback log4j log4j2 slf4j
Interface abstraction layer | Realization |
---|---|
JCL SLF4J JBOSS-LOGGING | log4j JUL(java.util.logging) log4j2 logback |
Select SLF4J and logback for springboot
1. SLF4J
The call of logging method should not directly call the log implementation class, but the method in the log abstraction layer
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); } }
2. Remaining problems
a(slf4j+logback): Spring (commons-logging),Hibernate(jboss-logging),Mybatis,XXX
Unified logging, that is, other frameworks also use SLF4J for output
(1) exclude other log frames from the system first
(2) replace the original log framework with the tundish
(3) import other slf4j implementations, such as logback
3. Spring boot log relationship
The following log dependencies need to be added for spring boot development
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <version>2.2.1.RELEASE</version> <scope>compile</scope> </dependency>
However, in actual development, we do not need to add the dependency directly.
You will find that Spring Boot starter includes Spring Boot starter logging. This dependency is Spring Boot's default logging framework, logback.
Conclusion:
1. The bottom layer of springboot also uses slf4j+logback for logging 2. springboot also replaced SLF4J with other logs 3. springboot also adds an intermediate replacement package 4. If we want to introduce other frameworks, we must remove the default log dependency of this framework For example, Spring (common logging is used by default) <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
4. Log usage
The default configuration of spring boot is written in the logging package under the org.springframework.boot: spring boot: 2.2.1.release file, such as base.xml defaults.xml console-appender.xml and file-appender.xml
springboot has configured the log by default
private Logger logger = LoggerFactory.getLogger(SpringBootTest.class); @Test public void testLog(){ logger.trace("this is trace log.."); logger.debug("this is debug log.."); logger.info("this is info log.."); logger.warn("this is warn log.."); logger.error("this is error log.."); }
Log level from low to high
trace<debug<info<warn<error<fatal
If it is set to WARN, no information below WARN will be output.
You can adjust the level of the input log. springboot uses the info level log by default
logging.file, setting file, can be absolute path or relative path. For example: logging.file=my.log
Logging.path, set the directory, in which the spring.log file will be created and the log content will be written, such as logging.path=/var/log
If only logging.file is configured, a xxx.log log file will be generated under the current path of the project.
If only logging.path is configured, a log file is generated in the / var/log folder as spring.log
Note: both cannot be used at the same time. If they are used at the same time, only logging.file will take effect
By default, when the log file size reaches 10MB, it will be cut once to generate a new log file
Because the following configuration is available in the springboot default configuration file file appender:
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${ROLLING_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern> <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize> </rollingPolicy>
Change log level
logging: # Split file is set to be more than 10MB, with a maximum history of 90 days maxFileSize: 10MB maxHistory: 90 level: root: INFO ##Here is the root level, that is, all the logs of the project. We can also use the package level, that is, the corresponding log level under the specified package path: log ##This property is used to configure the path of the log file file: springboot.log ##This attribute is used to configure the log file name. If this attribute is not configured, the default file name is spring.log pattern: console: ##Log format for console input file: ##Log output format in file ##logging.level.com.lee.boot.dao=WARN set the log level under the specified package to WARN
Log output format:
%d Represents date time %thread Represents the thread name %-5level Level 5 character width from left %logger{50}Express logger Names can be up to 50 characters long, otherwise they are separated by periods %msg:Log message %n Newline character eg: %d{yyyy-MM-dd HH:mm:ss.SSS} {%thread} %-5level %logger{50} -%msg%n
Define your own log profile
Default profile name:
(the default naming rules can be placed under src/main/resources; spring does not use its default configuration.)
logging system | customization |
---|---|
logback | logback-spring.xml OR logback.xml, etc |
log4j2 | log4j2-spring.xml OR log4j2.xml |
java util logging | logging.properties |
If you want to fully control the log configuration, but do not want to use logback.xml as the name of Logback configuration, application.yml can specify a custom name through the logging.config property:
logging.config=classpath:logging-config.xml
logback-spring.xml is recognized by springboot
logback.xml is recognized by the logback log framework
So it is recommended to use logback-spring.xml
logback-spring.xml can use springboot to configure log labels according to test dev prod and other environments
Use with spring.profiles.active=dev, etc. (activate environment)
<springProfile name="dev,staging"> ..... </springProfile> <springProfile name="!dev"> ..... </springProfile>
5. Composition of logback configuration file
Root node < configuration > < configuration >
Properties contained in the root node: scan: when this property is set to true, if the configuration file changes, it will be reloaded. The default value is true. scanPeriod: set the time interval for monitoring whether the configuration file has been modified. If no time unit is given, the default unit is milliseconds. This property takes effect when scan is true. The default time interval is 1 minute. debug: when this property is set to true, the logback internal log information will be printed out and the logback will be viewed in real time Operation status. The default is false.
There are five child nodes under the root.
5.1), < root > node:
The root node is a required node, which is used to specify the most basic log output level. There is only one level attribute, which is used to set the print level. The options are as follows: TRACE,DEBUG,INFO,WARN,ERROR,ALL,OFF The default is DEBUG.
It can contain zero or more elements, and the identifier will be added to the logger.
<root level="debug"> <appender-ref ref="console" /> <appender-ref ref="file" /> </root>
5.2), < contextname > set context name
Each logger is associated with a logger context. The default context name is "default". But you can use a record set to a different name to distinguish between different applications. Once it is set, it cannot be modified. You can print the log context name through% contextName. Generally speaking, we do not use this property. It is optional.
<contextName>logback</contextName>
5.3), < property > set variable
The label used to define the variable value has two attributes, name and value. The value of name is the name of the variable, and the value of value is the value defined by the variable. The value defined by is inserted into the logger context. After defining variables, you can make "${}" use variables.
<property name="logback.logdir" value="/Users/inke/dev/log/tomcat"/> <property name="logback.appname" value="app"/>
5.4),<appender>
appender is used to format the log output node. It has two attributes: name and class. Class is used to specify which output policy is used. Console output policy and file output policy are commonly used.
Console output ConsoleAppender:
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <contextName>logback-demo</contextName> <!--Output to console ConsoleAppender--> <appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender"> <!--Display format layout--> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d -1 %msg%n</pattern> </layout> </appender> <!--Output to console ConsoleAppender--> <appender name="consoleLog2" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d -2 %msg%n</pattern> </encoder> </appender> <!--Specify the most basic log output level--> <root level="INFO"> <!--appender Will be added to this loger--> <appender-ref ref="consoleLog1"/> <appender-ref ref="consoleLog2"/> </root> </configuration>
You can see that both layout and encoder can convert events to formatted log records, but layout is used for console output and encoder is used for file output.
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <contextName>logback-demo</contextName> <!--Output to console ConsoleAppender--> <appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender"> <!--Display format layout--> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern> </pattern> </layout> <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> --> </appender> <!--Specify the most basic log output level--> <root level="INFO"> <!--appender Will be added to this loger--> <appender-ref ref="consoleLog1"/> <appender-ref ref="consoleLog2"/> </root> </configuration>
< encoder > means to code the log:
%d{HH: mm:ss.SSS} -- log output time %thread -- the process name of the output log, which is very useful in Web applications and asynchronous task processing %-5level -- log level, with 5 characters left justified %logger{36} -- the name of the log exporter %msg -- log message %n -- newline for platform
Another common log output to file, with the application running longer and longer, the log will grow more and more, it is not a good way to output them to the same file RollingFileAppender is used to segment file logs:
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <! -- if you just want info level logs, just fi lt ering info will still output Error logs, because the Error level is high, So we use the following strategy to avoid outputting the Error log -- > <filter class="ch.qos.logback.classic.filter.LevelFilter"> <! -- fi lt er error -- > <level>ERROR</level> <! -- prohibit matching -- > <onMatch>DENY</onMatch> <! -- no matching is allowed -- > <onMismatch>ACCEPT</onMismatch> </filter> <! -- log name. If there is no File attribute, only the File path rule of FileNamePattern will be used If there are < File > and < filenamepattern > at the same time, the log of the day is < File > and will automatically set today The log of was renamed today's date. That is, the logs of < File > are of the same day. --> <File>${logback.logdir}/info.${logback.appname}.log</File> [! -- scroll policy, scroll by timebasedrollingpolicy -- > <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <! -- file path, which defines the log segmentation method -- archive the daily logs to a file to prevent the logs from filling the entire disk space -- > <FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <! -- only keep the last 90 days of logs -- > <maxHistory>90</maxHistory> <! -- used to specify the maximum size of the log file. When this value is reached, the old log will be deleted -- > <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <! -- log output code format -- > <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern> </encoder> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <! -- if you just want Error level logs, you need to filter them. The default is info level, thresholdfilter -- > <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>Error</level> </filter> <! -- log name. If there is no File attribute, only the File path rule of FileNamePattern will be used If there are < File > and < filenamepattern > at the same time, the log of the day is < File > and will automatically set today The log of was renamed today's date. That is, the logs of < File > are of the same day. --> <File>${logback.logdir}/error.${logback.appname}.log</File> [! -- scroll policy, scroll by timebasedrollingpolicy -- > <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <! -- file path, which defines the log segmentation method -- archive the daily logs to a file to prevent the logs from filling the entire disk space -- > <FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <! -- only keep the last 90 days of logs -- > <maxHistory>90</maxHistory> <! -- used to specify the maximum size of the log file. When this value is reached, the old log will be deleted -- > <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <! -- log output code format -- > <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern> </encoder> </appender>
If there are < File > and < filenamepattern > at the same time, the logs are divided according to the date.
If you want to distinguish logs at the Info and Error levels, you need to use a policy of filtering rules.
5.5),<loger>
< logger > is used to set the log printing level of a package or a specific class, and to specify < appender >. < logger > has only one name attribute, one optional level and one optional addtivity attribute.
name: used to specify a package or a specific class constrained by this logger.
Level: used to set the printing level regardless of case: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF. There is also a special value of implied or the synonym NULL, which represents the level of enforcing the superior. If this property is not set, the current logger inherits the level of the parent.
addtivity: whether to transfer printing information to the superior logger. The default is true.
There are two situations when using the logger
First: configuration with logger, no level or appender specified
logback-spring.xml add loger configuration as follows:
<logger name="com.dudu.controller"/> <logger name="com.dudu.controller" /> It will control the printing of logs of all classes under the controller package, but it does not use to set the printing level, So inherit his superior's log level "info"
addtivity is not set. It is true by default. The printing information of this logger is passed to the superior;
The appender is not set, and the logger itself does not print any information.
Set the print level of root to "info" and specify an appender named "console".
When executing the login method of com.dudu.controller.LearnController class, LearnController is in the package com.dudu.controller, so first execute ` ', pass the log information with the level of "info" and greater than "info" to root, and do not print itself;
root receives the information from the lower level, and hands it to the configured appender named "console" for processing. The "console" appender prints the information to the console;
Second: configuration with multiple loger s, specify the level, and specify the appender
ogback-spring.xml add logger configuration as follows:
<configuration> <!--logback.LogbackDemo: Full path of class --> <logger name="com.lee.controller.LearnController" level="WARN" additivity="false"> <appender-ref ref="console"/> </logger> </configuration>
Control the log printing of com.lee.controller.LearnController, with the printing level of "WARN";
The additivity property is false, which means that the printing information of this logger is no longer passed to the superior;
6. Log file configuration used in the project
First
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds"> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-M-d HH:mm:ss} %t %p %m%n</pattern> </encoder> </appender> <appender name="springboot" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <Encoding>UTF-8</Encoding> --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/logback/springboot_%d{yyyy-M-d}.log </FileNamePattern> <MaxHistory>10</MaxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-M-d HH:mm:ss} %t %p %m%n</pattern> </encoder> </appender> <appender name="redpigmall" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/logback/redpigmall_%d{yyyy-M-d}.log </FileNamePattern> <MaxHistory>10</MaxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-M-d HH:mm:ss} %t %p %m%n</pattern> </encoder> </appender> <logger name="org.springframework.boot" level="debug" additivity="false"> <appender-ref ref="springboot" /> </logger> <!-- name Package must be able to scan all classes, including startup classes --> <logger name="com.redpigmall" level="debug" additivity="false"> <appender-ref ref="redpigmall" /> </logger> <root level="debug"> <appender-ref ref="stdout" /> </root> </configuration>
The second
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!--Rolling record file--> <appender name="eas" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>/Users/air/Desktop/project/project_my/logs/eas_log/eas.log</File> <!--Rolling strategy:Generate log by day,And automatically compress--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>/Users/air/Desktop/project/project_my/logs/eas_log/eas.log.%d{yyyy-MM-dd}.gz</fileNamePattern> <append>true</append> <maxHistory>10</maxHistory> </rollingPolicy> <encoder> <pattern>[%d{HH:mm:ss.SSS}][%p][%c{40}][%t] %m%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!--Rolling record file--> <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>/Users/air/Desktop/project/project_my/logs/eas_log/error.log</File> <!--Rolling strategy:Generate log by day,And automatically compress--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>/Users/air/Desktop/project/project_my/logs/eas_log/error.log.%d{yyyy-MM-dd}.gz</fileNamePattern> <append>true</append> <maxHistory>10</maxHistory> </rollingPolicy> <encoder> <pattern>[%d{HH:mm:ss.SSS}][%p][%c{40}][%t] %m%n</pattern> <charset>UTF-8</charset> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!--Output log to console,To specifically control which classes to output logs logger Label control--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoding>UTF-8</encoding> <encoder> <pattern>[%d{HH:mm:ss.SSS}][%p][%c{40}][%t] %m%n</pattern> <charset>UTF-8</charset> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level> </filter> </appender> <root level="DEBUG"> <appender-ref ref="console"/> <appender-ref ref="error"/> </root> <!--Printing cn.xqd.eas Content under package,Log level is INFO--> <logger name="cn.xqd.eas" additivity="false" level="INFO" > <appender-ref ref="eas" /> <appender-ref ref="console"/> </logger> <!--Printing cn.xqd.eas.mapper Content under package,Namely Mybatis Related log information,Log level is DEBUG--> <logger name="cn.xqd.eas.dao" level="DEBUG"/> </configuration>