6

对于我的 LogBack 记录器,我正在尝试以编程方式创建一个写入 ByteArrayOutputStream的OutputStreamAppender 。这是我到目前为止所拥有的:

// Destination stream
ByteArrayOutputStream stream = new ByteArrayOutputStream();

// Get LoggerContext from SLF4J
LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory();

// Encoder
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(context);
encoder.setPattern("%d{HH:mm:ss} %-5level %logger{36} - %msg%n");
encoder.start();

// OutputStreamAppender
OutputStreamAppender<ILoggingEvent> appender= new OutputStreamAppender<>();
appender.setName( "OutputStream Appender" );
appender.setContext(context);
appender.setOutputStream(printStream);
appender.setEncoder(encoder);

appender.start();

Logger log = context.getLogger(this.getClass());
log.addAppender(appender);

log.info( "text from logger");

// Output to stdout logback status
StatusPrinter.print(context);

根据我所阅读的所有内容,这应该是正确的。Logger 中的任何内容都不会写入流,并且 OutputStreamAppender 无法根据以下输出正确初始化StatusPrinter

15:26:30,330 |-WARN in ch.qos.logback.core.OutputStreamAppender[OutputStream Appender] - Encoder has not been set. Cannot invoke its init method.
15:26:30,335 |-ERROR in ch.qos.logback.core.OutputStreamAppender[OutputStream Appender] - Appender [OutputStream Appender] failed to append. java.lang.NullPointerException
    at java.lang.NullPointerException
    at  at ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:135)
    at  at ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:188)
    at  at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:212)
    at  at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:103)
    at  at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88)
    at  at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
    at  at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
    at  at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
    at  at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:441)
    at  at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:395)
    at  at ch.qos.logback.classic.Logger.info(Logger.java:599)

我被警告和 NPE 难住了LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder)。我在 Appender 上设置编码器。

4

1 回答 1

8

查了一下源代码,发现编码器必须在输出流之前设置:

OutputStreamAppender<ILoggingEvent> appender= new OutputStreamAppender<>();
appender.setName( "OutputStream Appender" );
appender.setContext(context);
appender.setEncoder(encoder);  // <-- must be set before outputstream
appender.setOutputStream(printStream);
于 2013-09-29T03:15:05.647 回答