Introduction to the
Logback is one of the most popular logging tools in the world, with high performance, full functionality and documentation. The author is also the developer of log4j series.
This article introduces the common components and function points of Logback, and provides simple examples
java
How to uselogback
Two key packages are introduced in POM.xml
<! -- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<! -- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
Copy the code
Then create a logback.xml file in the Resources directory, as described in the section full configuration files available
The level of logging
You are advised to use the following levels in descending order
Level | describe |
---|---|
ERROR |
The error event may still allow the application to continue running |
WARN |
Specify potentially hazardous situations |
INFO |
Specifies a message that highlights information about how the application is performing at the coarse-grained level |
DEBUG |
Specifying fine-grained information events is the most useful application debugging |
* * * | |
# # Appender level |
What is an Appender?
ConsoleAppender
(Output logs to the console)
Print the log information in the console
configuration | type | describe |
---|---|---|
encoder |
Encoder | Log Output format |
target |
String | The log output target can be system. out or system. err. The default is system. out |
withJansi |
boolean | Default is false, this is not used, it seems that the output ANSI will have color, see the official website for details |
sample:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<! -- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Copy the code
FileAppender
(Output the log to a file)
FileAppender A subclass of OutputStreamAppender that outputs logs to the specified file. If the file already exists, append or rebuild the file at the end according to the configuration properties
configuration | type | describe |
---|---|---|
append |
boolean | The default is true and the log is appended to the end of an existing file |
encoder |
Encoder | Log Output format |
file |
String | If the file or directory does not exist, it will be created. For example:logs /info.log, which has no default value |
immediateFlush |
boolean | Flush to the file as soon as a log is generated, by setting it to false to improve performance because of frequent Flush buffer; |
sample:
<configuration>
<! -- Use timestamp as filename -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile-${bySecond}.log</file>
<append>true</append>
<! -- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<! -- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Copy the code
RollingFileAppender
(Rolling output)
RollingFileAppender inherits from FileAppender and generates a rolling file according to certain policies. For example, in conjunction with TimeBasedRollingPolicy, a new file is generated when the file reaches a specified time. This will be explained in detail in later chapters.
configuration | type | describe |
---|---|---|
append |
boolean | See a FileAppender configuration |
encoder |
Encoder | See a FileAppender configuration |
file |
String | See a FileAppender configuration |
rollingPolicy |
RollingPolicy | Log scroll policy: Configuring this option causes log files to scroll according to the specified policy |
triggeringPolicy |
TriggeringPolicy | Trigger rollingPolicy: usually used with a rollingPolicy to set the trigger conditions for rolling |
sample:
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<! TimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<! -- Set log naming mode -->
<fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<! Keep log for up to 30 days -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<! When the file exceeds 150MB, the scroll policy is triggered immediately to generate a new file.
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>150</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
</encoder>
</appender>
Copy the code
Log file Policy *Policy(Common)
TimeBasedRollingPolicy
(Scroll by date strategy)
TimeBasedRollingPolicy is probably logBack’s most popular rollingpolicy. TimeBasedRollingPolicy is logBack’s most popular rollingpolicy. TimeBasedRollingPolicy is logBack’s most popular rollingpolicy
configuration | type | describe |
---|---|---|
fileNamePattern |
String | The generated file is similar to errorfile.2018-10-09.log. After the date is added, the name of the file generated every day will not be repeated. This also supports time zone selection, such as %d{YYYY-MM-dd,UTC} |
maxHistory |
int | Log retention period. The historical log files that exceed this period will be deleted by LogBack asynchronously |
totalSizeCap |
int | The total size of the archive, with the maxHistory policy preferred. |
cleanHistoryOnStart |
boolean | The default value is false, which triggers the immediate deletion of the archive. |
Gz or. Zip file names, for example, /wombat/foo.%d.gz
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<! -- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<! -- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Copy the code
SizeAndTimeBasedRollingPolicy
(Scroll policy by size and time)
This is probably the most common one, scrolling logs according to a specified time and file size policy. Without further ado, let’s look at the following example
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<! -- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<! -- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
Copy the code
Note the “% I” conversion flags other than “% d”. Both % I and % d tokens are mandatory. Whenever the current log file reaches maxFileSize before the end of the current time period, it will be archived with the added index, starting at 0
FixedWindowRollingPolicy
(Generating scrolling files with fixed algorithmic policies is not commonly used)
This strategy is not common, za not bb, property and other rolling strategy is the same, usually the file naming convention is this: tests. % i.l og, when arrive condition triggered rolling test1 generated file. The log, test2. Log, test3. The log…
SizeBasedTriggeringPolicy
(Policies that trigger scrolling based on size)
The Settings in this TAB that trigger the scroll time, such as when the file size reaches a specified value, trigger the scroll
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Copy the code
fileNamePatten
(examples, scroll by year, month, day, day, hour, minute, second)
example | describe |
---|---|
/wombat/foo.%d |
Scroll by day, format year – month – day, all generated in a folder |
/wombat/%d{yyyy/MM}/foo.txt |
Scroll by month to generate the same file each month in a different month folder, for example, first: /wombat/2018/09/foo.txt, next: /wombat/2018/10/foo.txt |
/wombat/foo.%d{yyyy-ww}.log |
It is generated once a week and starts to be generated on the first day of each week |
/wombat/foo%d{yyyy-MM-dd_HH}.log |
It’s generated every hour |
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log |
Every minute |
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log |
Generated every minute for the specified time zone |
/foo/%d{yyyy-MM,aux}/%d.log |
It is generated every day, divided by year and month, for example, /foo/2018-09/ contains a log of one month, and the log name is the date of each day |
pattern
Configuration (Log output formatting)
example
The following describes some common configuration rules.
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
Copy the code
%-4relative
: Left-align the log output time with the width of 4.%thread
: Specifies the number of the thread that will output logs%-5level
: Displays five log levels and aligns them left.%logger{35}
: Outputs logslogger
The name is usually the class name and is 35 in length.%msg%n
: Prints the information provided by the application and wraps it.
Note: all keywords must be marked with %, as above, – to mark them
pattern
form
The keyword | describe | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
c{length} lo{length} |
Output the name of the class to which logger belongs, usually the full name of the class. The parameter is reserved for the logger name. The full name is not filled in by default.
|
||||||||||
C{length} class{length} |
Similar to the above usage, output the full name of the caller, poor performance, not recommended. | ||||||||||
contextName cn| |
Output context name | ||||||||||
d{pattern} date{pattern} |
The printing time of the output log is similar to the date formatting in Java
|
||||||||||
caller{depth} | Output log caller’s call stack depth information. The larger the value is, the more stack information is output
|
||||||||||
L line |
Output the location of the log event, including the category name, the thread in which it occurred, and the number of lines in the code. If performance is not considered, it can be used | ||||||||||
m msg message |
Information provided by the application | ||||||||||
M method |
The method name that outputs execution logs has poor performance and can be used if performance concerns are not considered | ||||||||||
n | Output a carriage return newline, “/r/n” on Windows, “/n” on Unix | ||||||||||
p le level |
The output log levels are DEBUG, INFO, WARN, ERROR, and FATAL | ||||||||||
t thread |
The name of the thread that prints logs | ||||||||||
replace(msg){r,t} | MSG is the log content, and r is the regular expression. Replace the content matching R in MSG with T. For example: % the replace (MSG) % {\ ‘s’, “”} |
||||||||||
r relative |
Output The number of milliseconds elapsed between the start of the application and the output of the log information |
Configuration:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<! -- Date [thread] [class]-[log level] log content carriage return symbol -->
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
</appender>
<! -- Output INFO and above logs -->
<root level="INFO">
<! Make custom appender work -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Copy the code
Console output:
2018-10-09 14:27:55 [main] [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping]-[INFO] Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2018-10-09 14:27:55 [main] [org.springframework.jmx.export.annotation.AnnotationMBeanExporter]-[INFO] Registering beans for JMX exposure on startup 2018-10-09 14:27:55 [main] [org.apache.coyote.http11.Http11NioProtocol]-[INFO] Starting ProtocolHandler ["http-nio-6677"] 2018-10-09 14:27:55 [main] [org.apache.tomcat.util.net.NioSelectorPool]-[INFO] Using a shared selector for servlet write/read 2018-10-09 14:27:55 [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer]-[INFO] Tomcat started on port(s): 6677 (http) with context path '' 2018-10-09 14:27:55 [main] [com.xj.plugins.Springboot2AnalyzeApplication]-[INFO] Started Springboot2AnalyzeApplication in 2.014 seconds (JVM running for 3.949)Copy the code
Log configuration color for console output
format | describe |
---|---|
%black | black |
%red | red |
%green | green |
%yellow | yellow |
%blue | blue |
%magenta | magenta |
%cyan | cyan |
%white | white |
%gray | gray |
%highlight | High light |
%bold | More vivid color color, enhance all the above colors, such as %boldRed,%boldBlack |
Example:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<! -- Date [thread] [class]-[log level] log content carriage return symbol -->
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<! -- Output INFO and above logs -->
<root level="INFO">
<! Make custom appender work -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Copy the code
Console output after configuration
Log Oriented Output
In logback.xml, how do you need to output a particular log to a file using a filter, like this example
XML configures filters, for example, to output error logs to error.log
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<! -- rollover daily -->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<! -- Maximum file size: 30MB, 60 days, 20GB -->
<maxFileSize>30MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<! -- filter, only write error level log -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
Copy the code
You can override the Filter method if you need a special log that needs to be directed to output
public class MyLogFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if(event.getMessage() ! =null
&& (event.getMessage().startsWith("test")
|| event.getMessage().startsWith("demo"))) {
return FilterReply.ACCEPT;
} else {
returnFilterReply.DENY; }}}Copy the code
Then add the filter to your appender
<! -- filter, write logs starting with test and demo -->
<filter class="xx.xxx.xxxx.MyLogFilter" />
Copy the code
Turns off a level of log output from a class
Add the following configuration to logback.xml
OFF: disables all functions. You can set a specific level, such as INFO, DEBUG…
<logger name="xx.xx.class" level="OFF" />
Copy the code
logback.xml
Reading environment variables
Logback.xml can be read in two ways, from the system environment and from the Spring configuration file
The system environment variables are obtained by ${envName}
<! Read log output directory from system environment variable -->
<property name="LOG_HOME" value="${log.dir}"/>
Copy the code
How to read the Spring configuration file
<! ${} -->
<springProperty scope="context" name="LOG_HOME" source="logback.dir"/>
Copy the code
Default Settings
If the value of LOG_HOME is not taken in the environment variable, logs is used as the default, similar to the default set in Shell syntax
<file>${LOG_HOME:-logs}/test/test-info.log</file>
Copy the code
–
Full available configuration files
Three log files are generated in the following configuration: A new log file is generated every day. When the size of a log file reaches the specified size, a new log file is automatically compressed and generated for recording.
main.log
(only recordsinfo
Log output of levels and above)warn.log
(only recordswarn
Level of log output)error.log
(only recordserror
Level of log output)
<configuration debug="false">
<! -- Get the configuration from Spring, if not use the default value -->
<springProperty scope="context" name="LOG_HOME" source="logging.path"/>
<springProperty scope="context" name="LOG_LEVEL" source="logging.output.level"/>
<springProperty scope="context" name="LOG_MAX_SIZE" source="logging.file.max-size"/>
<springProperty scope="context" name="LOG_TOTAL_SIZE_CAP" source="logging.file.total-size-cap"/>
<springProperty scope="context" name="LOG_MAX_HISTORY" source="logging.file.max-history"/>
<! -- Output style -->
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%logger{10}]-[%p] %m%n"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%cyan(%t)] [%yellow(%logger{10})]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<appender name="Main-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/main.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/main-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<appender name="Error-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/error-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="Warn-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/warn-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<! -- log filter -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<! -- Disable output at a certain level in a class. OFF Disable all output, INFO,DEBUG... <logger name="x.x.Constants"> <level value="OFF"/> </logger> -->
<! -- log output level -->
<root level="${LOG_LEVEL:-INFO}">
<appender-ref ref="STDOUT"/>
<appender-ref ref="Main-Log"/>
<appender-ref ref="Warn-Log"/>
<appender-ref ref="Error-Log"/>
</root>
</configuration>
Copy the code