Overview
By default, SpringBoot internally uses logback as the framework for system log implementation, which outputs logs to the console and does not write to log files. If it is configured in application.properties or application.yml, only simple scenarios can be configured, save path, log format, etc. Complex scenarios (distinguishing info and error logs, generating a log file every day, etc.) cannot be satisfied, and you can only customize the configuration file logback-spring.xml or logback.xml. This article mainly explains how to customize logabck.xml and give a detailed explanation of the configuration in the logback file.
Detailed logback configuration
First, let's understand logback.
logback is mainly divided into three modules:
- logback-core: is the base module for the other two modules
- logback-classic: It is an extension to the core module, equivalent to an improved version of log4j. The classic module implements the Slf4j API so it is easy to switch directly with other logging frameworks
- logback-access: integrates with the Servlet container to provide http access logging functionality.
Official website configuration document address: logback.qos.ch/manual/conf...
Introduction to Configuration Content Concepts
Logger Context
LoggerContext is responsible for creating loggers and arranging loggers in a tree structure. All other logger s are also obtained through the static method getLogger of the org.slf4j.LoggerFactory class. The getLogger method takes the logger name as a parameter.
Logger
Logger, as a log logger, is mainly used to store log objects after it is associated with the corresponding context of the application, and can also define log types and levels.
Appender
Appender is mainly used to specify the destination of log output, the destination can be console, file, remote socket server, MySQL, PostreSQL, Oracle and other databases, JMS and remote UNIX Syslog daemons, etc.
Layout
Responsible for converting events into strings and outputting formatted log messages.
Configuration introduction
The basic structure of a configuration file: starts with, followed by zero or more elements, with zero or more elements, with at most one element.
Steps for default configuration
- Try to find the file logback-test.xml under the classpath;
- If the file does not exist, look for the file logback.xml;
- If neither file exists, logback automatically configures itself with the BasicConfigurator, which causes logging to be output to the console.
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:When this property is set to true When the configuration file is changed, it will be reloaded. The default value is true. scanPeriod:Sets the time interval for monitoring whether the configuration file is modified. If no time unit is given, the default unit is milliseconds. when scan for true , this property takes effect. The default time interval is 1 minute. debug:When this property is set to true , will print out logback Internal log information, real-time viewing logback Operating status. Default is false. --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- operating environment, dev:develop, test:test, pre:pre-production, pro:Production --> <property name="system_host" value="dev" /> <property file="system.properties" /> <!-- context variable settings,used to define variable values,in name The value is the name of the variable, value is the value defined by the variable. pass<property>The defined value will be inserted into logger in context. After defining the variable, you can make " ${}"to use variables. --> <property name="CONTEXT_NAME" value="logback-test" /> <!-- Log file storage path setting, absolute path --> <property name="logs.dir" value="/opt/logs" /> <!-- Log file storage path setting, tomcat path --> <property name="logs.dir" value="${catalina.base}/logs" /> <!-- Define log file relative input location --> <property name="log_dir" value="log" /> <!-- Log output format settings --> <!-- %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n Logger: %logger Class: %class File: %file Caller: %caller Line: %line Message: %m Method: %M Relative: %relative Thread: %thread Exception: %ex xException: %xEx nopException: %nopex rException: %rEx Marker: %marker newline:%n --> <property name="CUSTOM_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" /> <!-- Context name:<contextName>, each logger are related to logger context, the default context name is " default". but can use<contextName>Set to another name to distinguish records from different applications. Once set, it cannot be modified. --> <contextName>${CONTEXT_NAME}</contextName> <!-- <appender>Yes<configuration>The child node is the component responsible for writing logs. There are two necessary properties name and class. name specify appender name, class specify appender implementation class. --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!-- Format the log. --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- Roll back by day, if you need to roll back by hour, set to{yyyy-MM-dd_HH} --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>log/testC.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- If you roll back and forth by day, the maximum storage time is 30 days, and everything before 30 days will be cleaned up --> <maxHistory>30</maxHistory> <!-- While rolling back by time, roll back by file size --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!-- filter, log only WARN level log --> <!-- If the log level is equal to the configured level, the filter will onMath and onMismatch Accept or reject logs. --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- set filter level --> <level>WARN</level> <!-- Used to configure actions that match the filter criteria --> <onMatch>ACCEPT</onMatch> <!-- Used to configure actions that do not match the filter criteria --> <onMismatch>DENY</onMismatch> </filter> <!-- log output format --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="log_file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- The file name to be written can be a relative directory or an absolute directory. If the upper-level directory does not exist, it will be automatically created, and there is no default value. --> <file>${logs.dir}/logback-test.log</file> <!-- Generate log files in fixed window mode, when the file is greater than 20 MB , a new log file is generated. The window size is 1 to 3, when 3 archives are saved, the oldest log will be overwritten --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- must contain "%i"For example, assuming the minimum and maximum values are 1 and 2, the naming pattern is mylog%i.log,will generate an archive mylog1.log and mylog2.log. File compression options can also be specified, for example, mylog%i.log.gz or no log%i.log.zip --> <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern> <!-- window index minimum --> <minIndex>1</minIndex> <!-- window index max --> <maxIndex>3</maxIndex> </rollingPolicy> <!-- log level filter --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- log level filter --> <level>INFO</level> <!-- Compliant log levels, filtering, ACCEPT:accept --> <onMatch>ACCEPT</onMatch> <!-- Unmatched log level, filtering, DENY:reject --> <onMismatch>DENY</onMismatch> </filter> <!-- The condition that activates the scroll. --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <!-- The size of the active file, the default value is 10 MB --> <maxFileSize>30MB</maxFileSize> </triggeringPolicy> <!-- Format logging events. --> <encoder> <pattern>${CUSTOM_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- Asynchronous output --> <appender name="ASYNC_logback" class="ch.qos.logback.classic.AsyncAppender"> <!-- Do not lose logs.default,If the queue's 80%full,will be discarded TRACT,DEBUG,INFO level log --> <!-- <discardingThreshold>0</discardingThreshold> --> <!-- Change the default queue depth,This value affects performance.The default value is 256 --> <!-- <queueSize>256</queueSize> --> <!-- add additional appender,At most one can be added --> <appender-ref ref="log_file" /> </appender> <!-- Specify the package output path --> <!-- Used to set the log printing level of a package or a specific class, and specify<appender>, name:used to specify logger A package or a specific class of constraints. level:Used to set the print level, case-insensitive: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF,There is another special value INHERITED or synonym NULL,Represents a level that enforces the superior. If this property is not set, the current loger The level of the superior will be inherited. additivity:whether to superior logger Pass printing information. Default is true. (this logger The superior is the one above root) <logger>can contain zero or more<appender-ref>element that identifies this appender will be added to this logger. --> <logger name="org.logback.test" level="DEBUG" additivity="true"> <appender-ref ref="stdout" /> </logger> <!-- special<logger>element, is the root logger. only one level property, which should be already named"root". level:Set the print level, case-insensitive: TRACE, DEBUG, INFO, WARN, ERROR, ALL and OFF,cannot be set to INHERITED or synonym NULL. Default is DEBUG. <root>can contain zero or more<appender-ref>element that identifies this appender will be added to this loger. --> <root> <level value="WARN" /> <!-- if expression, which requires Janino jar --> <!-- Janino 2.6.0 version starts, except janino.jar Besides, commons-compiler.jar Also needs to be in the classpath --> <if condition='property("system_host").contains("dev")'> <then> <appender-ref ref="stdout" /> </then> </if> <appender-ref ref="file" /> </root> </configuration> copy code
Custom logback in SpringBoot
SpringBoot enables custom logback in 3 ways:
- logback-spring.xml exists on the classpath
- There is logback.xml under the classpath
- Specify the file through the configuration item in the configuration file: logging.config: ./logback-rule.xml
If possible, we recommend that you use the -spring variant for your logging configuration or by way of configuration items (for example, logback-spring.xml instead of logback.xml). Spring does not have full control over log initialization if the standard configuration is used.
In this example, we use logback-spring.xml as the configuration file for demonstration.
Create a logback-spring.xml file under src/main/resources to record system output logs and Error logs separately.
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!--Color log output format--> <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}){magenta} %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <!--Non-color log output format--> <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> <!--dev file path: src sibling directory logs,If the parent directory does not exist, it will be automatically created--> <property name="DEV_FILE_PATH" value="./logs" /> <!-- pro file path --> <property name="PRO_FILE_PATH" value="./logs-prod" /> <!-- console output --> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> </encoder> </appender> <!-- Generate output log files on a daily basis --> <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <!--Formatted output:%d represents the date,%thread represents the thread,%-5level: Levels are displayed five characters wide from the left,%logger{36}: logger Yes class full name,The number that follows represents the longest character limit,%msg: log messages,%n newline--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!--Rolling strategy rolls over time--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- rollover daily file name --> <fileNamePattern>${DEV_FILE_PATH}/output-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB --> <!--single file size--> <maxFileSize>10MB</maxFileSize> <!--Days to keep log files--> <maxHistory>60</maxHistory> <!--Used to specify the upper limit size of the log file, when this value is reached, the old log will be deleted-->a <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> </appender> <!-- Generate error log files on a daily basis --> <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- This log file only records ERROR level --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <!--output log to src sibling directory logs middle error.log in file--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--Rotation strategy based on size and time, when the log content exceeds the file size limit, a file will be automatically generated to continue recording and renaming--> <fileNamePattern>${DEV_FILE_PATH}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB --> <maxFileSize>10MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> </appender> <root level="INFO"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </configuration> copy code
Print log in java:
@SpringBootApplication @Slf4j public class LogbackApp { public static void main(String[] args) { SpringApplication.run(LogbackApp.class, args); log.trace("Trace log..."); log.debug("Debug log..."); log.info("Info log..."); log.warn("Warn log..."); log.error("Error log..."); } } copy code
Output result:
\
SpringBoot officially recommends using logback-spring.xml as a custom log configuration file for the logback framework, using logback-spring.xml instead of logback.xml, because the configuration file with the -spring suffix can use some extended functions.
Multi-environment output log file
The node directives in the Logback configuration file allow you to selectively include and troubleshoot parts of the configuration information based on the configuration file active parameter (active). To define different log outputs according to different environments, use the node in logback-spring.xml to define the method as follows:
<!--development environment:print console--> <springProfile name="dev"> <root level="DEBUG"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </springProfile> <!--Production Environment:output to file--> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="consoleAppender" /> <appender-ref ref="fileAppender" /> <appender-ref ref="errorAppender" /> </root> </springProfile> copy code
Add configuration items to the configuration file:
result:
The debug log is printed, indicating that the dev configuration has taken effect.
Read configuration file configuration
This article demonstrates by reading the log file name of the configuration modification output in the configuration file.
- Add configuration items to the configuration file
- The configuration content added to logback-spring.xml is as follows:
<springProperty scope="context" name="logFileName" source="log.file.name" defaultValue="output"/> copy code
- scope: use scope
- name: variable name
- source: read configuration item name
- defaultValue: default name
- Use configuration via ${....}
- As a result, the output log file name was successfully modified
Article code address: github.com/alvinlkk/sp...
Summarize
This article explains how to enhance the output of logs by customizing logback, and I hope it will be helpful to you.