Java from 0 to architect Directory: [Java from 0 to architect] learning record
Gitee Code: https://gitee.com/szluyu99/mj_java_frame/tree/master/04_SpringBoot
SLF4J supports various frameworks:
SLF4J + Log4j 1.x
Import dependency:
<!-- rely on slf4j-api,log4j 1.x --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.30</version> </dependency>
Use example:
- In SLF4J, there is no FATAL level (or it can be understood that FATAL is equivalent to ERROR)
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestSLF4J_Log4j { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(TestSLF4J_Log4j.class); log.error("error_ERROR"); log.warn("warning_WARN"); log.info("information_INFO"); log.debug("debugging_DEBUG"); log.trace("mark_TRACE"); } }
Use Lombok to automatically generate the Logger definition of SLF4J:
@Slf4j public class TestSLF4J_Log4j { // Using @slf4j equivalent, the following code is generated // private static final Logger logger = // LoggerFactory.getLogger(TestSLF4J_Log4j.class); public static void main(String[] args) { log.error("error_ERROR"); log.warn("warning_WARN"); log.info("information_INFO"); log.debug("debugging_DEBUG"); log.trace("mark_TRACE"); } }
SLF4J + Logback
Logback syntax is relatively free, and there is no constraint in its xml. Log4j 1 X has a dtd constraint
Import dependency:
<!-- rely on slf4j-api,logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
Use example:
- Logback has a set of default configurations, which can be used without providing configuration files
log4j 1.x must provide a configuration file
@Slf4j public class TestSLF4J_Logback { // Using @slf4j equivalent, the following code is generated // private static final Logger logger = // LoggerFactory.getLogger(TestSLF4J_Logback.class); public static void main(String[] args) { for (int i = 0; i < 500; i++) { log.error("error_ERROR"); log.warn("warning_WARN"); log.info("information_INFO"); log.debug("debugging_DEBUG"); log.trace("mark_TRACE"); } } }
Logback - Profile
Configuration file location: classpath: logback xml
Logback and log4j 1 The configuration content of X is very similar, which is easy to learn
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- Extract public content --> <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%t]: %m%n"/> <property name="CHARSET" value="UTF-8"/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${PATTERN}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="console"/> </root> <logger name="com.mj" level="TRACE" additivity="false"> <appender-ref ref="console"/> </logger> </configuration>
Logback - console color printing
reference resources: Console color print document
<property name="PATTERN" value="%d{HH:mm:ss.SSS} [%highlight(%-5p)] %cyan(%c{5}): %m%n"/> <property name="CHARSET" value="UTF-8"/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${PATTERN}</pattern> </encoder> </appender>
Logback - configuration
Common properties of the configuration tag:
- debug="true": you can print logs inside Logback
- scan="true" + scanPeriod="30 seconds"
Scan the profile every 30 seconds and apply the latest changes to the profile
The units of scanPeriod can be: milliseconds, seconds, minutes and hours
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true" scan="true" scanPeriod="5 seconds"> </configuration>
Logback - Appender controls the location of log output
Similar to Log4j, there are several Appender s in Logback:
- ConsoleAppender - output logs to the console
- FileAppender - output logs to a file (single)
- RollingFileAppender - output log to file (scroll)
FileAppender uses:
<appender name="file" class="ch.qos.logback.core.FileAppender"> <file>${BASE_PATH}/${BASE_NAME}.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${FILE_PATTERN}</pattern> </encoder> </appender> <appender name="htmlFile" class="ch.qos.logback.core.FileAppender"> <file>${BASE_PATH}/${BASE_NAME}.html</file> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <charset>${CHARSET}</charset> <layout class="ch.qos.logback.classic.html.HTMLLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}%p%t%m</pattern> </layout> </encoder> </appender>
RollingFileAppender uses:
- Timebasedlollingpolicy: time based rollingpolicy
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${BASE_PATH}/${BASE_NAME}.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${PATTERN}</pattern> </encoder> <!-- Time based rolling strategy --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- Support compression --> <fileNamePattern>${BASE_PATH}/logback_rolling_%d{yyy-MM-dd-HH-mm-ss}.log.gz</fileNamePattern> <!-- Delete log files 20 seconds ago(The time unit depends on fileNamePattern) --> <maxHistory>20</maxHistory> <!-- Total log size limit(More than,Delete the oldest log) --> <totalSizeCap>10KB</totalSizeCap> </rollingPolicy> </appender>
- Sizeandtimebasedlollingpolicy: scrolling based on file size and time
<!--Scrolling strategy based on file size and time --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- Support compression --> <fileNamePattern>${BASE_PATH}/logback_rolling_%d{HH-mm}_%i.log.gz</fileNamePattern> <!-- Delete log files 20 seconds ago(The time unit depends on fileNamePattern) --> <maxHistory>20</maxHistory> <!-- When the log file size exceeds 1 MB,A new log file is generated --> <maxFileSize>1MB</maxFileSize> </rollingPolicy>
Logback - Filter filters log output information based on the Logger
Set Filter to print only WARN level information:
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${CONSOLE_PATTERN}</pattern> </encoder> <!-- Print only WARN Level information --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <!-- When matching: receive(Turn on Printing) --> <onMatch>ACCEPT</onMatch> <!-- When does not match: negative(Turn off printing) --> <onMismatch>DENY</onMismatch> </filter> </appender>
You can also configure to turn off WARN and print only other levels:
<!-- close WARN,Open other --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter>
Logback - AsyncAppender makes logging asynchronous
In Logback, you can use AsyncAppender to improve efficiency
- The log writing operation will not affect the normal execution of the program (generally used for time-consuming operations such as writing logs to files)
<appender name="file" class="ch.qos.logback.core.FileAppender"> <file>${BASE_PATH}/${BASE_NAME}.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <charset>${CHARSET}</charset> <pattern>${PATTERN}</pattern> </encoder> </appender> <appender name="async" class="ch.qos.logback.classic.AsyncAppender"> <!-- Capacity of blocking queue --> <param name="queueSize" value="512"/> <!-- When blocking the remaining 20 of the queue%Capacity time,It will be discarded by default TRACE,DEBUG,INFO Level log --> <!-- discardingThreshold Set to 0,It won't be discarded --> <param name="discardingThreshold" value="0"/> <!-- take file this appender Set to asynchronous --> <appender-ref ref="file"/> </appender>
Principle of AsyncAppender:
Log4j 2.x
Example code: log4j 2.x
Import dependency:
<!-- rely on log4j-api --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.3</version> </dependency>
Basic usage: log4j 2 X the default log level is ERROR (without configuration file)
public class TestLog4j2 { public static void main(String[] args) { Logger logger = LogManager.getLogger(TestLog4j2.class); logger.fatal("deadly_FATAL"); logger.error("error_ERROR"); logger.warn("warning_WARN"); logger.info("information_INFO"); logger.debug("debugging_DEBUG"); logger.trace("mark_TRACE"); } }
Log4j 2.x - Profile
Configuration file: classpath: log4j2 xml
The configurations of various configuration files are similar. It's easy to understand with the previous foundation
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Properties> <Property name="PATTERN">%d{HH:mm:ss.SSS} [%-5p] %c{1.}: %m %n</Property> <Property name="CHARSET">UTF-8</Property> </Properties> <Appenders> <Console name="Console"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> </Console> </Appenders> <Loggers> <Root level="TRACE"> <AppenderRef ref="Console"/> </Root> <Logger name="com.mj" level="TRACE" additivity="false"> <AppenderRef ref="Console"/> </Logger> </Loggers> </Configuration>
Common properties in the Configuration tab:
- Status: controls the printing level of Log4j internal logs, such as status="WARN"
- monitorInterval: how many seconds to scan the configuration file and apply the latest modification of the configuration file
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="5"> </Configuration>
Log4j 2.x - console color printing
reference resources: http://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns
<Properties> <Property name="PATTERN" value="%style{%d{HH:mm:ss.SSS}}{black}\ [%highlight{%t}] %highlight{%-5p}\ %style{%c{1.}}{magenta}: %m%n"/> <Property name="CHARSET">UTF-8</Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <!-- disableAnsi="false" Turn on color printing --> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}" disableAnsi="false"/> </Console> </Appenders>
Log4j 2.x - Filter
Log4j 2. The commonly used filters in X are:
- ThresholdFilter - takes a certain level as the threshold to control whether to output logs
- LevelRangeFilter - controls the output of the log in a range
- LevelMatchFilter - matches a log level
- DenyAllFilter - disable all log levels
- StringMatchFilter - matches according to the string in the log information
ThresholdFilter uses:
<Console name="Console"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> <!-- achieve WARN -> DENY -> close --> <!-- Not reached WARN -> ACCEPT -> open --> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/> </Console>
- ACCEPT: on; All subsequent filters will be ignored
- DENY: closed; All subsequent filters will be ignored
- NEUTRAL: NEUTRAL. Will be passed to
<!-- Open only[DEBUG,WARN]Level log --> <Filters> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"> </Filters>
LevelRangeFilter uses:
- Note that in log4j 2 In the LevelRangeFilter of X,
minLevel is the maximum level and maxlLevel is the minimum level
<!-- Open only[DEBUG, WARN]Level log --> <Filters> <LevelRangeFilter minLevel="WARN" maxLevel="DEDBUG" onMatch="ACCEPT" onMismatch="DENY"/> </Filters>
Log4j 2.x - Appender
The structure of the log framework is similar, log4j 2 In X, you can specify the Appender directly through the label:
Log4j 1.x and Logback, specify the Appender through the < Appender > tag and class attribute
- < console >: output logs to the console
- < File >: output logs to a file (single)
- < rollingfile >: output log to file (scroll)
<Console>:
- target: the value can be SYSTEM_OUT (default), SYSTEM_ERR, controls the color of the output to the console
<Appenders> <Console name="Console" target="SYSTEM_ERR"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> </Console> </Appenders>
<File>:
<Properties> <Property name="PATTERN">%d{HH:mm:ss.SSS} [%-5p] %c{1.}: %m %n</Property> <Property name="CHARSET">UTF-8</Property> <Property name="BASE_PATH">F:/logs</Property> <Property name="BASE_NAME">log4j2</Property> </Properties>
<File name="File" fileName="${BASE_PATH}/${BASE_NAME}_file.log"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> </File>
<RollingFile name="RollingFile" fileName="${BASE_PATH}/${BASE_NAME}.log" filePattern="${BASE_PATH}/%d{yyyy}/%d{MM}/%d{dd}/HH_mm_%i.log.gz"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> <Policies> <!-- Time based scrolling strategy: scroll when the time span reaches 2 minutes --> <!-- The time unit depends on filePattern Minimum time unit --> <TimeBasedTriggeringPolicy interval="2"/> <!-- File size based scrolling strategy: when the file size reaches 10 KB Scroll when --> <SizeBasedTriggeringPolicy size="10KB"/> </Policies> <!-- The default value is 7,set up%i Maximum value of --> </DefaultRolloverStrategy max="10"> </RollingFile>
Scroll policy - Delete
For output to a scrolling file, you can set a scrolling policy:
Reference documents: Delete
<!-- set up%i The default value is 7 --> <DefaultRolloverStrategy max="100"> <!-- maxDepth: The maximum number of levels to access the directory, Default 1, Delegate access only basePath Files in directory --> <Delete basePath="${BASE_PATH}" maxDepth="10"> <!-- IfFileName && IfLastModified --> <!-- Fill in relative basePath Relative path of --> <IfFileName glob="*.log.gz"/> <!-- The file is older than 5 minutes s --> <IfLastModified age="5s"> <!-- IfAccumulatedFileSize || IfAccumulatedFileCount --> <IfAny> <IfAccumulatedFileSize exceeds="20KB"/> <IfAccumulatedFileCount exceeds="10"/> </IfAny> </IfLastModified> </Delete> </DefaultRolloverStrategy>
Log4j 2.x - Loggers
<Loggers> <Root level="WARN"> <AppenderRef ref="Console"/> </Root> <Logger name="com.mj" level="TRACE" additivity="false"> <AppenderRef ref="RollingFile"/> </Logger> </Loggers>
Log4j 2.x - Async
<Console name="Console"> <PatternLayout pattern="${PATTERN}" charset="${CHARSET}"/> </Console> <Async name="Async"> <Appender-ref redf="Console"/> </Async>
SLF4J + Log4j 2.x
Example code: SLF4J + Log4j 2.x
Import dependency:
<!-- rely on slf4j-api,log4j-api,log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.13.3</version> </dependency>
Code example:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestSLF4J_Log4j2 { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(TestSLF4J_Log4j2.class); log.error("error_ERROR"); log.warn("warning_WARN"); log.info("information_INFO"); log.debug("debugging_DEBUG"); log.trace("mark_TRACE"); } }
Use @slf4j annotation:
import lombok.extern.slf4j.Slf4j; @Slf4j public class TestSLF4J_Log4j2 { public static void main(String[] args) { log.error("error_ERROR"); log.warn("warning_WARN"); log.info("information_INFO"); log.debug("debugging_DEBUG"); log.trace("mark_TRACE"); } }