Logback:使用Logstash的微服务的StatusManager的用途和范围

时间:2018-12-28 15:41:14

标签: java logstash logback

根据manual

  

Logback在StatusManager对象中收集其内部状态数据,   可通过LoggerContext访问。

     

给定StatusManager,您可以访问所有关联的状态数据   带有登录上下文。为了将内存使用率保持在合理水平,   默认的StatusManager实现将状态消息存储在两个   分开的部分:标题部分和尾部。标头部分存储   前H个状态消息,而尾部则存储最后T个消息。目前,H = T = 150,尽管这些值在将来的版本中可能会更改。

目的似乎是允许侦听传入的日志消息,也可以通过servlet对其进行查看。

在本例中,我们使用logstash-logback-encoder并将Logback消息发送到控制台,以便fluentd / Filebeat等可以传送到远程Logstash-因此我们的微服务不需要检查或聆听它们。

所以问题是:我们是否可以/应该重写默认的BasicStatusManager(使用NOOP实现)以禁止这些消息的内部存储,或者有人知道Logstash编码器是依赖还是依赖于此地位机制本身?

我们的logback.xml很简单:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="lsAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
    </appender>

    <logger name="a.b.c" level="debug"/>

    <root level="debug">
        <appender-ref ref="lsAppender"/>
    </root>
</configuration>

第二发问的原因是,我们最近发现自己从具有120 MB堆的微服务中获取了OOME。当然,这些单独的日志消息太大了,但这仅是由Logback自身保留而不是被发送并遗忘的问题。这将是一个较少的可扩展性问题。

YourKit输出的屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:0)

我最近又注意到了这一点。问题实际上与日志大小或日志吞吐量无关,并且无需以任何方式控制 StatusManager 的大小。

实际原因是 Logstash Logback Encoder(6.4 版)由于 Marker 无法编码而“无声地”失败:

import net.logstash.logback.marker.Markers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import java.util.HashMap;

@ControllerAdvice
public class MyExceptionHandler {

    private static final Logger LOG = LoggerFactory.getLogger(MyExceptionHandler.class);

    public void logException(Throwable e, WebRequest request) {
        var fields = new HashMap<>();
        fields.put("Request", request);

        LOG.error(Markers.appendEntries(fields), "Error occurred", e);
    }
}

WebRequestorg.springframework.web.context.request.ServletWebRequest 的一个实例,当编码器使用 jackson-databind 将其序列化为 JSON 时,会抛出一个 StackOverflowError,该Coffee 会被所述编码器捕获并忽略.原始日志请求不会从内部 Logback 缓存中刷新。

考虑到足够多的此类错误,我们最终耗尽了内存。