Spring Boot-Log Configuration (Ultra Detailed)
Update log:
20170810 update via application.yml passes parameters to the logback.
Short books do not support catalogs. Take a screenshot.
Default Logback:
By default, Spring Boot logs with Logback and outputs to the console at the INFO level. You should have seen a lot of INFO-level logs when running applications and other examples.
As you can see from the diagram above, the log output content elements are as follows:
- Time Date: Accurate to milliseconds
- Log level: ERROR, WARN, INFO, DEBUG or TRACE
- Process ID
- Separator: - Identifies the start of the actual log
- Thread name: bracketed (console output may be truncated)
- Logger name: The class name of the source code is usually used
- Log Content
Add Log Dependency
If spring-boot-starter-logging is added to a maven dependency:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency>
However, in actual development we do not need to add this dependency directly.
You will find that spring-boot-starter contains spring-boot-starter-logging, which is the default log framework logback for Spring Boot. Thymeleaf is useful in engineering, and the Thymeleaf dependency includes spring-boot-starter, and ultimately I just need to introduce Thymeleaf.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
console output
Log levels range from low to high:
TRACE < DEBUG < INFO < WARN < ERROR < FATAL.
If set to WARN, no information below WARN will be output.
Log output to the console is configured at the ERROR, WARN, and INFO levels by default in Spring Boot.
You can also enable Debug mode by launching your application, the debug flag (recommended for development), either of the following:
- Add the--debug flag after running the command, such as: $Java -jar springTest. Jar--debug
- In application. When debug=true is configured in properties, the core Logger (containing embedded containers, hibernate, spring) outputs more, but the logs you apply yourself do not output at the DEBUG level.
If writing this line of code every time is cumbersome, you can use annotations, but you need lombok:
-
Add dependencies:
//annotation compile 'org.projectlombok:lombok:1.16.18'
-
Install lombok plug-ins:
- Go to File > Settings > Plugins
- Click on Browse repositories...
- Search for Lombok Plugin
- Click on Install plugin
- Restart Android Studio
- Allow annotation processing, Settings -> Compiler -> Annotation Processors
You can use the {} placeholder to concatenate strings instead of the'+'to concatenate strings.
File Output
By default, Spring Boot outputs logs to the console and does not write to log files.
I like using Spring Boot in application.properties or application.yml configuration, so you can only configure simple scenes, save paths, log formats, and so on. Complex scenes (distinguishing info from error's logs, producing a log file each day, etc.) are not enough. You can only customize the configuration, as shown below.
By default, a spring is generated in the set path. Log file.
If you want to write a log file other than console output, you need to write it in application. Set logging in properties. File or logging.path property.
- logging.file, the settings file, can be an absolute path or a relative path. Examples: logging.file=my.log
- logging.path, which sets the directory under which spring is created. Log file and write to the log content, such as logging.path=/var/log
If only logging is configured. File, an XXX is generated under the current path of the project. Log log file.
If only logging is configured. Path, generate a log file called spring in the / var/log folder. Log
Note: Both cannot be used at the same time. If they are used at the same time, only logging will be used. File Effective
By default, log files are sliced once when they reach 10MB in size, resulting in new log files at the default levels of ERROR, WARN, INFO
Level control
All supported logging systems can set the logging level in the Spring environment (for example, in application.properties)
The format is:'logging.level.* = LEVEL'
logging.level`: Log level control prefix,*For package name or Logger name `LEVEL`: option`TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
Give an example:
logging.level.com.dudu=DEBUG: com.dudu All under Pack class with DEBUG Level Output logging.level.root=WARN: root Log to WARN Level Output
Custom Log Configuration
Depending on the log system, you can organize the profile name according to the following rules to load it correctly:
- Logback: logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
- Log4j: log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
- Log4j2: log4j2-spring.xml, log4j2.xml
- JDK (Java Util Logging): logging.properties
Spring Boot officially recommends preferring file names with-spring for your log configuration (for example, logback-spring.xml instead of logback.xml), named logback-spring. The log configuration file for XML for which spring boot can add some spring boot-specific configuration items (mentioned below).
Default naming rules and placed under src/main/resources
If you want to have full control of the log configuration, but you don't want to use logback.xml as the name of the Logback configuration, application.yml can pass logging. The config property specifies a custom name:
logging.config=classpath:logging-config.xml
Although it is not generally necessary to change the name of the configuration file, this is useful if you want to use different log configurations for different runtime profiles.
Normally this property is not needed, but directly in logback-spring. Using springProfile configuration in xml, logging is not required. Config specifies that different environments use different profiles. The springProfile configuration is described below.
Attributes contained in the root node
- scan: When this property is set to true, the configuration file will be reloaded if it changes, defaulting to true.
- scanPeriod: Sets the time interval to monitor 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, logback internal log information will be printed out to see the status of the logback in real time. The default value is false.
The root node ``` has five child nodes, which are described in detail below.
Child Node One``
The root node is a required node to specify the most basic level of log output with only one level attribute.
Level: Used to set the printing level, case-independent: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF, cannot be set to INHERITED or synonym NULL.
Default is DEBUG.
It can contain zero or more elements, identifying that the appender will be added to the loger.
<root level="debug"> <appender-ref ref="console" /> <appender-ref ref="file" /> </root>
Child Node Two: ```Set Context Name
Each logger is associated with a logger context, which is named "default" by default. However, you can use a different name to distinguish records from different applications. Once set and cannot be modified, you can print the log context name through%contextName. Generally, we do not use this property, but we can have or not.
<contextName>logback</contextName>
Child Node Three: ```Set Variable
The label used to define the value of a variable has two attributes, name and value. Where the value of name is the name of the variable and the value of value is the value defined by the variable. Defined values are inserted into the logger context. Once you have defined a variable, you can make'${}'use it.
<property name="logback.logdir" value="/Users/inke/dev/log/tomcat"/> <property name="logback.appname" value="app"/>
Here you can see later through the application.yml passes the parameter over.
Child Node Four: ```
Appnders are used to format log output nodes with two attributes, name and class, and classes to specify which output policy is commonly console output policy and file output policy.
ConsoleAppender console output:
-
Example 1:
<?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"> <!--Presentation 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 level of log output--> <root level="INFO"> <!--appender Will be added to this loger--> <appender-ref ref="consoleLog1"/> <appender-ref ref="consoleLog2"/> </root> </configuration>
You can see both layout and encoder, which can convert events to formatted log records, but console output uses layout and file output uses encoder for specific reasons http://blog.csdn.net/cw_hello1/article/details/51969554 -
Example 2:
<?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"> <!--Presentation 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 level of log output--> <root level="INFO"> <!--appender Will be added to this loger--> <appender-ref ref="consoleLog1"/> <appender-ref ref="consoleLog2"/> </root> </configuration>
Output log:
18:15:22.148 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - Log Output info 18:15:22.148 logback-demo [http-nio-9010-exec-1] WARN c.e.demo.controller.UserContorller - Log Output warn 18:15:22.148 logback-demo [http-nio-9010-exec-1] ERROR c.e.demo.controller.UserContorller - Log Output error 18:15:22.148 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - name:inke , age:33 18:15:22.149 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - name:inke , age:33
``Indicates that the log is coded:
- %d{HH: mm:ss.SSS} - Log Output Time
- %thread - The process name of the output log, which is useful in Web applications and asynchronous task processing
- %-5level - log level, with 5 characters left aligned
- %logger{36} - Name of the log exporter
- %msg - Log message
- %n - Platform Line Break
ThresholdFilter is a system-defined interceptor, for example, we use ThresholdFilter to filter logs below the ERROR level and not output to a file. If you don't remember to comment it out, otherwise your console will find no logs~
Output to File RollingFileAppender
Another common way to export logs to files is to increase the number of logs as the application runs longer and longer, so it is not a good idea to export them to the same file. RollingFileAppender is used to slice file logs:
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--If you just want to Info Level log, just filter info Or will it output Error Log because Error High-level, So we use the following strategy to avoid output Error Log--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--filter Error--> <level>ERROR</level> <!--Prohibit when matched--> <onMatch>DENY</onMatch> <!--Allow without matching--> <onMismatch>ACCEPT</onMismatch> </filter> <!--Log name, if not File Property, then only use FileNamePattern File Path Rules If there are both<File>and<FileNamePattern>,So the log for the day is<File>,Tomorrow will automatically bring today The log was renamed as today's date. That is,<File> All logs are for that day. --> <File>${logback.logdir}/info.${logback.appname}.log</File> <!--Scroll strategy, scroll by time TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--File Path,Defines how to slice your logs - archive your daily logs into a file,To prevent the log from filling up the entire disk space--> <FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <!--Keep logs for the last 90 days only--> <maxHistory>90</maxHistory> <!--Used to specify the maximum size of the log file, then at this value, the old log will be deleted--> <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <!--Log Output Encoding Formatting--> <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 to Error Level log, then need to be filtered, default is info Level, ThresholdFilter--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>Error</level> </filter> <!--Log name, if not File Property, then only use FileNamePattern File Path Rules If there are both<File>and<FileNamePattern>,So the log for the day is<File>,Tomorrow will automatically bring today The log was renamed as today's date. That is,<File> All logs are for that day. --> <File>${logback.logdir}/error.${logback.appname}.log</File> <!--Scroll strategy, scroll by time TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--File Path,Defines how to slice your logs - archive your daily logs into a file,To prevent the log from filling up the entire disk space--> <FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <!--Keep logs for the last 90 days only--> <maxHistory>90</maxHistory> <!--Used to specify the maximum size of the log file, then at this value, the old log will be deleted--> <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <!--Log Output Encoding Formatting--> <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern> </encoder> </appender>
If there are and at the same time, the log is split by date, and the code comments are clearly written.
If you want to distinguish between Info and Error-level logs, you need to use a strategy of filtering rules, and the code comments are clearly written.
Child Node Five``
Used to set the log printing level for a package or a specific class, and to specify it. `` There is only one name attribute, an optional level, and an optional addtivity attribute.
- name: Used to specify a package or a specific class that is constrained by this loger.
- Level: Used to set the print level, case-independent: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF, and a special value INHERITED or synonym NULL, which represents the level at which a superior is enforced. If this property is not set, the current loger will inherit the level of the parent.
- addtivity: Whether to pass print information to the superior loger. The default is true.
There are two situations in which loger s are actually used
Let's first see how the code works
package com.dudu.controller; @Controller public class LearnController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @RequestMapping(value = "/login",method = RequestMethod.POST) @ResponseBody public Map<String,Object> login(HttpServletRequest request, HttpServletResponse response){ //The log level is divided from low to high into TRACE < DEBUG < INFO < WARN < ERROR < FATAL. If set to WARN, no information below WARN will be output. logger.trace("Log Output trace"); logger.debug("Log Output debug"); logger.info("Log Output info"); logger.warn("Log Output warn"); logger.error("Log Output error"); Map<String,Object> map =new HashMap<String,Object>(); String userName=request.getParameter("userName"); String password=request.getParameter("password"); if(!userName.equals("") && password!=""){ User user =new User(userName,password); request.getSession().setAttribute("user",user); map.put("result","1"); }else{ map.put("result","0"); } return map; } }
This is a login judgment. We import the logs, print different levels of logs, and then follow the logback-spring. Configuration in XML to see which levels of logs are printed.
First: Configuration with loger, no level, no appender
logback-spring.xml adds the loger configuration as follows:
<logger name="com.dudu.controller"/>
Printing of logs for all classes under the `controller` package will be controlled, but there is no need to set the print level, so inherit the log level `info'from his superior; `addtivity'is not set and defaults to true, passing the print information of this `loger` to a higher level; The `appender'is not set, and this `loger' does not print any information on its own. Set the print level of root to "info" and specify an appender with the name "console".
When executing com.dudu.controller. When using the login method of the LearnController class, LearnController is at package com. Dudu. In the controller, so execute ``` first, passing the log information with level `info'and greater than `info' to root, which does not print itself;
root receives information from subordinates and gives it to an appender named "console" which has been configured to print the information to the console.
The printout is as follows:
16:00:17.407 logback [http-nio-8080-exec-8] INFO com.dudu.controller.LearnController - Log Output info 16:00:17.408 logback [http-nio-8080-exec-8] WARN com.dudu.controller.LearnController - Log Output warn 16:00:17.408 logback [http-nio-8080-exec-8] ERROR com.dudu.controller.LearnController -
Second: Configuration with multiple loger s, level specified, appender specified
logback-spring.xml adds the loger configuration as follows:
<configuration> ... <!--logback.LogbackDemo: Full path of class --> <logger name="com.dudu.controller.LearnController" level="WARN" additivity="false"> <appender-ref ref="console"/> </logger> </configuration>
Control com. Dudu. Controller. Log printing for the LearnController class at WARN level;
The additivity property is false, indicating that the print information for this loger is no longer passed to the higher level;
An appender named "console" was specified;
Execute com at this time. Dudu. Controller. When the login method of the LearnController class is executed, ``` is executed first, and the log information at the level of `WARN'and greater than `WARN' is given to the appender process named `console'specified by this loger, which logs in the console and no more print information is passed to the upper root.
The printout is as follows:
16:00:17.408 logback [http-nio-8080-exec-8] WARN com.dudu.controller.LearnController - Log Output warn 16:00:17.408 logback [http-nio-8080-exec-8] ERROR com.dudu.controller.LearnController - Log Output error
Of course, if you change additivity="false" to additivity="true", you will print twice, because the print information is passed to the higher level, the logger itself prints once, and the root prints again after it receives it.
Be careful:
<configuration> ... <logger name="com.example.demo.controller" level="WARN" additivity="false"> <appender-ref ref="consoleLog"/> </logger> <logger name="com.example.demo.controller"/> <logger name="com.example.demo"/> </configuration>
If the ranges overlap, the ranges are small and valid.
Multiple Environment Log Output
<configuration> ... <!-- testing environment+development environment. Multiple separated by commas. --> <springProfile name="test,dev"> <logger name="com.example.demo.controller" level="DEBUG" additivity="false"> <appender-ref ref="consoleLog"/> </logger> </springProfile> <!-- production environment. --> <springProfile name="prod"> <logger name="com.example.demo.controller" level="INFO" additivity="false"> <appender-ref ref="consoleLog"/> </logger> </springProfile> </configuration> 1234567891011121314151617 application.yml`Increase the configuration of environment selection`active: dev server: port: 9010 spring: profiles: active: dev datasource: url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8 username: root password: root mybatis: type-aliases-package: org.larry.springboot.entity mapper-locations: classpath:mapper/**/*.xml check-config-location: true
Active: [test, dev, prod], automatically uses the logger log of the springProfile configured above, depending on the active environment
##Custom log path (application.yml)
application.yml Add Log Related Custom Configuration
logback: logdir: /Users/inke/dev/log/tomcat/sell appname: sell
At logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!--application.yml Pass parameter, cannot use logback Incoming<property>Label --> <springProperty scope="context" name="appname" source="logback.appname"/> <springProperty scope="context" name="logdir" source="logback.logdir"/> <contextName>${appname}</contextName> <!--Output to console ConsoleAppender--> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <!--Presentation 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> </appender> . . . . . .
Reference resources:
https://juejin.im/post/58f86981b123db0062363203
http://blog.csdn.net/vitech/article/details/53812137