我正在Spring Boot应用程序中使用log4j2进行异步日志记录。 这是我的配置log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%5p}--[%T-%-15.15t] [%-20X{serviceMessageId}]%-40.40c{1.} :%m%n%ex</Property>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT"
follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
<!-- Rolling File Appender -->
<RollingFile name="FileAppender" fileName="logs/app.log"
filePattern="logs/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="100MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
<Kafka name="KafkaAppender" topic="ServiceCentrallog">
<Property name="bootstrap.servers">10.2.16.2:9092,10.2.16.3:9092,10.2.16.4:9092</Property>
<JSONLayout compact="true" properties="true">
<KeyValuePair key="application"
value="${bundle:application-dev:spring.application.name}" />
</JSONLayout>
</Kafka>
</Appenders>
<Loggers>
<AsyncRoot level="info">
<AppenderRef ref="ConsoleAppender" />
<AppenderRef ref="FileAppender" />
<AppenderRef ref="KafkaAppender" />
</AsyncRoot>
</Loggers>
我在Project中的BaseClass
public abstract class BaseObject {
protected final org.apache.logging.log4j.Logger logger = LogManager.getLogger(getClass());
@Override
public String toString() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
String jsonString = "";
try {
jsonString = mapper.writeValueAsString(this);
} catch (JsonProcessingException e) {
logger.error("BaseObject: ", e);
jsonString = "Can't build json from object";
}
return jsonString;
}
}
这是我写日志的方法:
logger.info("Input: " + input.toString());
....
logger.info("output: " + Utils.toJson(restRes));
在正常情况下可以正常工作。 但是,如果我使用Jmetter发送大量请求(总计:7996,AVG:98消息/秒) 我发现日志记录速度太慢,在停止发送请求大约1.5分钟后,日志记录仍然继续并且日志文件的容量仍在增加。
我进行了很多搜索,但是仍然不知道如何加快日志记录速度,或者发现配置不合理的地方。
答案 0 :(得分:2)
但是,如果我使用Jmetter发送大量请求(总计:7996,AVG: 98条消息)停止发送后,我发现日志记录太慢 请求大约1.5分钟,日志记录仍然继续并记录 文件的容量仍在增加。
您正在使用Log4J2的异步日志记录。其目的是在记录操作期间不阻塞正在执行的线程。因此,如果您的应用程序在几分钟之内记录了很多事情(7996 * 98条消息),那么这种行为是完全可以理解的:消息越来越多地排在队列中,直到最后一条消息都要花一些时间。
我进行了很多搜索,但仍然不知道如何加快记录速度, 或找出我的配置不合理的地方。
1)使用同步日志记录将使用阻塞方法来加快您的日志记录速度:只有在将消息有效地记录在附加程序中时,日志记录调用才会返回,但也会影响处理速度。
2)在这种情况下(即记录请求/响应),请勿使用 3个附加器:
<AsyncRoot level="info">
<AppenderRef ref="ConsoleAppender" />
<AppenderRef ref="FileAppender" />
<AppenderRef ref="KafkaAppender" />
</AsyncRoot>
它执行三次日志。好多
如果您确实需要记录这些信息,请将它们记录在一个附加程序中。您可以使用过滤器功能轻松实现这一目标(MarkerFilter
应该没问题)。
例如,在您登录时添加标记JSON_REQUEST_RESPONSE
,并指定只有一个附加程序(如果存在)记录它,而其他任何情况下都不记录:
<RollingFile name="FileAppender" fileName="logs/app.log"
filePattern="logs/app-%d{yyyy-MM-dd}-%i.log">
<!-- ACCEPT Marker-->
<MarkerFilter marker="JSON_REQUEST_RESPONSE" onMatch="ACCEPT" />
<...>
</RollingFile>
<Console name="ConsoleAppender" target="SYSTEM_OUT"
follow="true">
<!-- DENY Marker-->
<MarkerFilter marker="JSON_REQUEST_RESPONSE" onMatch="DENY" />
<...>
</Console>
3)不要在info()
中记录太多:
logger.info("Input: " + input.toString());
....
logger.info("output: " + Utils.toJson(restRes));
请注意,请勿使用串联进行记录,因为如果记录器级别不匹配且未记录任何内容,那么这样做代价不菲。
在这种情况下,采用Supplier
的{{3}}更好:
logger.info("Input: {}", () -> input.toString());
....
logger.info("output: {}", () -> Utils.toJson(restRes));