本文介绍了 SpringBoot 日志结构 log4j2 的根本运用和装备方法,包含将日志输出到操控台、文件、Elasticsearch 和 Kafka,多个输出目的地的装备,以及异步日志记录器的运用。此外,还介绍了 log4j2.xml 装备文件的详细语法和参数意义。
Quick Start
在SpringBoot中运用log4j2日志结构,只需三步:
- 引入依靠
- 装备log文件
- 获取Logger实例并输出日志
引入依靠
dependencies {
implementation 'org.apache.logging.log4j:log4j-core:2.14.1'
implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.14.1"
implementation('org.springframework.boot:spring-boot-starter') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
为了防止日志结构之间的冲突,建议在运用Log4j2时将其他的日志结构排除掉,例如在build.gradle文件中排除Spring Boot默许的Logback日志结构
装备log文件
创立Log4j2的装备文件log4j2.xml,能够放在src/main/resources目录下或指定的目录下。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
上面的装备文件界说了一个名为Console的Appender,用于将日志输出到操控台。它运用了PatternLayout来界说日志输出格局,包含了日期、线程、日志等级、Logger称号和音讯等信息。在Loggers中,咱们将根Logger的日志等级设置为info,并将Console Appender添加到根Lodagger中。
获取Logger实例并输出日志
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyService {
private static final Logger logger = LogManager.getLogger(MyService.class);
public void doSomething() {
logger.debug("Debug message");
logger.info("Info message");
logger.warn("Warning message");
logger.error("Error message");
}
}
运用LogManager获取Logger实例,然后运用Logger的debug、info、warn和error方法来记录不同等级的日志。
这是日志输出成果,机敏的朋友可能现已发现了,这段输出里没有debug等级的日志,这是因为在默许情况下,Logback 只会输出 INFO 等级及以上的日志信息。
咱们把日志等级从info改成debug就能够输出debug日志了
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
@Slf4j注解
@Slf4j 是 Lombok 提供的一个注解,用于在编译时主动生成日志变量。
dependencies {
implementation 'org.apache.logging.log4j:log4j-core:2.14.1'
implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.14.1"
implementation('org.springframework.boot:spring-boot-starter') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
运用 @Slf4j 注解需要引入 lombok 和 SLF4J 的依靠。
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MyClass {
public void myMethod() {
log.info("这是一条日志");
}
}
@Slf4j 注解会主动生成一个名为 log 的日志变量,咱们能够直接运用 log 目标来记录日志。
log4j2.xml 详解
log4j2.xml 是 log4j 2.x 版本的装备文件格局,用于装备日志记录器的行为。它能够界说多个日志记录器、日志输出器和日志格局。
标签简介
以下是一些 log4j2.xml 中的重要标签:
-
<Configuration>
:界说整个装备文件的根元素,它有一个 status 特点,用于操控日志结构的日志输出等级。status 特点的值能够是 ALL、TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF 中的任何一个,默许值为 OFF。 -
<Appenders>
:界说日志输出器的集合,能够包含多个 Appender。每个 Appender 能够有自己的日志输出方法和格局化方法,以满意不同的需求。 -
<Logger>
:界说一个 Logger 目标,它能够有自己的日志等级、Appenders 和过滤器等特点。Logger 元素还能够经过子元素<AppenderRef>
来引证一个或多个 Appenders,将它们附加到该 Logger 上。 -
<Root>
:界说 Root Logger 目标,它是一切 Logger 的父 Logger。它的等级一般设置为最低等级,以便将一切日志音讯传递到其他 Logger 或 Appender。Root 元素也能够经过子元素<AppenderRef>
来引证一个或多个 Appenders,将它们附加到 Root Logger 上。 -
<Filter>
:界说一个或多个过滤器,用于操控哪些日志音讯被记录和输出。过滤器能够根据日志等级、音讯内容、时刻戳等条件进行过滤。 -
<PatternLayout>
:界说日志格局化器,用于将日志音讯格局化成一行一行的文本。PatternLayout 能够运用一系列占位符,表明日志音讯的不同部分,例如时刻戳、线程名、日志等级、类名、方法名、音讯内容等。 -
<RollingFile>
:界说一个 RollingFile Appender,用于将日志输出到文件,并完成翻滚文件的功能。RollingFile Appender 能够按照时刻、文件巨细等条件进行翻滚,并设置最多保存多少个日志文件。 -
<Console>
:界说一个 Console Appender,用于将日志输出到操控台。 -
<Elasticsearch>
:界说一个 Elasticsearch Appender,用于将日志输出到 Elasticsearch 中。
输出到操控台
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
该文件界说了一个名为 Console 的 Appender,用于将日志输出到操控台。
PatternLayout格局化字符串意义如下:
-
%d{yyyy-MM-dd HH:mm:ss.SSS}
:输出日志时刻的格局,其间yyyy表明四位年份,MM表明两位月份,dd表明两位日期,HH表明24小时制的小时数,mm表明分钟数,ss表明秒数,SSS表明毫秒数。 -
[%t]
:输出线程称号。 -
%-5level
:输出日志等级,其间-
表明左对齐,5
表明占位符宽度,level
表明日志等级。 -
%logger{36}
:输出logger称号,其间36表明logger称号的最大宽度。 -
%msg%n
:输出日志音讯和换行符。
该文件还界说了一个 Root logger,将日志等级设置为 info,表明只输出 INFO 等级及以上的日志信息,并将它的 AppenderRef 设置为 Console。
输出到文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<RollingFile name="RollingFile" fileName="/path/to/logs/myapp.log"
filePattern="/path/to/logs/myapp-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
这个装备文件中界说了一个名为 RollingFile 的 Appender,用于将日志输出到文件。
RollingFile Appender 运用了 TimeBasedTriggeringPolicy 和 SizeBasedTriggeringPolicy,表明按时刻和文件巨细来翻滚文件,以防止日志文件过大。DefaultRolloverStrategy 表明最多保存 10 个日志文件。
输出到多个文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<Routing name="Routing">
<Routes pattern="$${ctx:logFileName}">
<Route>
<File name="file" fileName="/path/to/logs/${ctx:logFileName}.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Routing"/>
</Root>
</Loggers>
</Configuration>
这个装备文件中界说了一个名为 Routing 的 Appender,用于按照日志文件名将日志输出到不同的文件中。Routing Appender 运用了 Routes 和 Route 元素,将日志按照日志文件名的不同路由到不同的 File Appender 中,完成了将日志输出到多个文件的功能。
输出Elasticsearch
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="org.apache.logging.log4j.core,com.fasterxml.jackson.databind.json">
<Appenders>
<Elasticsearch name="elasticsearch" type="http" index="log4j2" indexDateFormat="yyyy-MM-dd" ignoreExceptions="false">
<ServerHost>localhost</ServerHost>
<ServerPort>9200</ServerPort>
<IndexType>doc</IndexType>
<SourceHost>${env:HOSTNAME}</SourceHost>
<JacksonJsonLayout compact="true" />
</Elasticsearch>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="elasticsearch" />
</Root>
</Loggers>
</Configuration>
上述装备文件中,<Elasticsearch>
元素界说了 Elasticsearch Appender 的装备,其间包含了以下特点:
-
name
:指定 Appender 的称号,可自界说。 -
type
:指定 Elasticsearch 衔接类型,这儿运用的是 HTTP衔接方法。 -
index
:指定 Elasticsearch 中的索引称号。 -
indexDateFormat
:指定日志索引的日期格局。 -
ignoreExceptions
:指定是否疏忽反常,假如设置为false
,则在出现反常时会中断应用程序。 -
ServerHost
:指定 Elasticsearch 服务器的主机名或 IP 地址。 -
ServerPort
:指定 Elasticsearch 服务器的端口号。 -
IndexType
:指定 Elasticsearch 索引类型。 -
SourceHost
:指定日志来历的主机名或 IP 地址。 -
JacksonJsonLayout
:指定日志输出的格局,这儿运用了 JacksonJsonLayout。
装备多个Appenders
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="RollingFile" fileName="/path/to/logs/myapp.log"
filePattern="/path/to/logs/myapp-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
在这个例子中,咱们界说了一个名为 Console 的 Appender 和一个名为 RollingFile 的 Appender。Console Appender 用于将日志输出到操控台,RollingFile Appender 用于将日志输出到文件。在 Loggers 元素中,咱们将 Root logger 的 AppenderRef 分别设置为 Console 和 RollingFile,表明将日志一起输出到操控台和文件中。
每个 Appender 有必要有一个唯一的 name 特点,用于在其他当地引证该 Appender。在 Loggers 元素中,能够经过 AppenderRef 元从来引证一个或多个 Appenders,并将它们附加到特定的 Logger 上。也能够经过 Logger 元从来界说一个新的 Logger,并将其与一个或多个 Appenders 相关起来。
输出到kafka
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="org.apache.logging.log4j.core,com.fasterxml.jackson.databind.json">
<Appenders>
<Kafka name="Kafka" topic="myTopic" syncSend="false">
<Property name="bootstrap.servers">localhost:9092</Property>
<Property name="acks">1</Property>
<Property name="batch.size">32768</Property>
<Property name="compression.type">snappy</Property>
<Property name="retries">20</Property>
<Property name="reconnect.backoff.ms">20000</Property>
<Property name="retry.backoff.ms">20000</Property>
<PatternLayout pattern="${LOG_PATTERN}" charset="utf-8"/>
</Kafka>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Kafka" />
</Root>
</Loggers>
</Configuration>
Kafka
-
topic
特点:指定 Kafka 主题的称号,这儿设置为myTopic
。 -
bootstrap.servers
特点:指定 Kafka 服务器的地址和端口号,这儿设置为localhost:9092
。 -
acks
特点:指定 Kafka 生产者的承认等级。这儿设置为1
,表明只需要 Kafka 生产者收到音讯就返回承认音讯。 -
batch.size
特点:指定 Kafka 生产者批量发送音讯的巨细。这儿设置为32768
。 -
compression.type
特点:指定音讯的压缩类型,这儿设置为snappy
。 -
retries
特点:指定 Kafka 生产者在发生错误时的重试次数。这儿设置为20
。 -
reconnect.backoff.ms
特点:指定 Kafka 生产者在从头衔接到 Kafka 服务器之前的等待时刻。这儿设置为20000
毫秒。 -
retry.backoff.ms
特点:指定 Kafka 生产者在发生错误时的重试等待时刻。这儿设置为20000
毫秒。
装备异步日志记录器
在 log4j2 中,能够运用异步日志记录器来进步性能和吞吐量。
异步日志记录器能够将日志事情放入一个行列中,然后由别的的线程或线程池来处理行列中的日志事情,从而降低了日志记录对应用程序的影响。
下面是在 log4j2.xml 中装备异步日志记录器的示例:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<Async name="AsyncConsole" bufferSize="16384" queueSize="500" ringBufferSize="1024" blocking="false">
<AppenderRef ref="Console"/>
</Async>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="AsyncConsole"/>
</Root>
</Loggers>
</Configuration>
<Async>
元素是 Log4j2 中用于完成异步日志输出的 Appender。以下是<Async>
元素中各个参数的解释:
-
name
:指定异步 Appender 的称号,可自界说。 -
bufferSize
:指定异步行列的缓冲区巨细,即能够一起缓存的日志事情的数量。当行列已满时,新的日志事情会被直接丢掉。 -
queueSize
:指定异步行列的容量,即能够缓存的日志事情的最大数量。当超越此数量时,新的日志事情会被直接丢掉。 -
ringBufferSize
:指定异步行列的环形缓冲区巨细,这是一个循环行列,巨细有必要是 2 的幂次方。假如未指定bufferSize
,则运用ringBufferSize
作为缓冲区巨细。 -
blocking
:指定是否运用阻塞形式。假如设置为true
,则当行列已满时,新的日志事情将会被阻塞,直到行列中有空闲位置。假如设置为false
,则当行列已满时,新的日志事情会被直接丢掉。 -
AppenderRef
:指定异步 Appender 的输出目的地。