processor.netty.http.server.AccessLog, производящий LoggingEvent, а не AccessEvent

Я пытался настроить spring-boot 2.1 с webflux для хранения журналов доступа в формате JSON. Более того, мне нужно иметь такую ​​информацию, как протокол, код состояния в виде отдельных полей JSON (а не части сообщения). Посмотрев в интернете я нашел https://github.com/logstash/logstash-logback-encoder. Который, кажется, имеет все, что мне нужно. Но во время выполнения я получаю следующую ошибку:

ERROR in ch.qos.logback.core.FileAppender[accessLog] - Appender [accessLog] failed to append. java.lang.ClassCastException: ch.qos.logback.classic.spi.LoggingEvent cannot be cast to ch.qos.logback.access.spi.IAccessEvent
at java.lang.ClassCastException: ch.qos.logback.classic.spi.LoggingEvent cannot be cast to ch.qos.logback.access.spi.IAccessEvent
at  at net.logstash.logback.composite.accessevent.AccessEventFormattedTimestampJsonProvider.getTimestampAsMillis(AccessEventFormattedTimestampJsonProvider.java:20)
at  at net.logstash.logback.composite.FormattedTimestampJsonProvider.writeTo(FormattedTimestampJsonProvider.java:149)
at  at net.logstash.logback.composite.JsonProviders.writeTo(JsonProviders.java:77)
at  at net.logstash.logback.composite.CompositeJsonFormatter.writeEventToGenerator(CompositeJsonFormatter.java:189)
at  at net.logstash.logback.composite.CompositeJsonFormatter.writeEventToOutputStream(CompositeJsonFormatter.java:166)
at  at net.logstash.logback.encoder.CompositeJsonEncoder.encode(CompositeJsonEncoder.java:122)
at  at net.logstash.logback.encoder.CompositeJsonEncoder.encode(CompositeJsonEncoder.java:34)
at  at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:230)
at  at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
at  at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at  at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at  at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at  at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at  at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at  at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
at  at ch.qos.logback.classic.Logger.info(Logger.java:591)
at  at reactor.util.Loggers$Slf4JLogger.info(Loggers.java:255)
at  at reactor.netty.http.server.AccessLog.log(AccessLog.java:104)
at  at reactor.netty.http.server.AccessLogHandler.lambda$write$0(AccessLogHandler.java:77)
at  at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
at  at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:504)
at  at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:483)
at  at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
at  at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:103)
at  at io.netty.util.internal.PromiseNotificationUtil.trySuccess(PromiseNotificationUtil.java:48)
at  at io.netty.channel.ChannelOutboundBuffer.safeSuccess(ChannelOutboundBuffer.java:696)
at  at io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:258)
at  at io.netty.channel.nio.AbstractNioByteChannel.doWriteInternal(AbstractNioByteChannel.java:216)
at  at io.netty.channel.nio.AbstractNioByteChannel.doWrite0(AbstractNioByteChannel.java:209)
at  at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:397)
at  at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:934)
at  at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:360)
at  at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:901)
at  at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1396)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:768)
at  at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:749)
at  at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.flush(CombinedChannelDuplexHandler.java:533)
at  at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:115)
at  at io.netty.channel.CombinedChannelDuplexHandler.flush(CombinedChannelDuplexHandler.java:358)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:768)
at  at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:749)
at  at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:768)
at  at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:749)
at  at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at  at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:768)

Моя конфигурация довольно проста:

<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
    <file>${LOGS}/access_log.log</file>
    <encoder class="net.logstash.logback.encoder.LogstashAccessEncoder"/>
</appender>

<logger name="reactor.netty.http.server.AccessLog" level="DEBUG" additivity="false">
    <appender-ref ref="accessLog"/>
</logger>

В этот момент я застрял. Я искал в интернете и искал код возврата, но все еще не представляю, что нужно сделать, чтобы AccessEvent содержал гораздо больше информации вместо LoggingEvent

0 ответов

LogstashAccessEncoder От logstash-logback-encoder требуется logback-доступ, который обеспечивает AccessEvents. logback-доступ доступен только для причала и кота. Это не доступно для реактора-нетто.

Реактор-Netty По reactor.netty.http.server.AccessLog просто использует стандартное событие журнала (не AccessEvent). Итак, если вы хотите использовать logstash-logback-encoder, вы должны использовать LogstashEncoder вместо LogstashAccessEncoder, как это:

<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
    <file>${LOGS}/access_log.log</file>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

<logger name="reactor.netty.http.server.AccessLog" level="DEBUG" additivity="false">
    <appender-ref ref="accessLog"/>
</logger>

Недостатком является то, что LogstashEncoder ничего не знает о HTTP-запросе. Он просто знает о событиях журнала, зарегистрированных через Logger, Поэтому вы не можете настроить, какие подробности HTTP регистрируются при использовании LogstashEncoder как вы можете при использовании LogstashAccessEncoder, Вместо этого ваше событие журнала будет просто отображать детали, предоставленные reactor.netty.http.server.AccessLog как часть сообщения журнала. Детали не будут доступны как отдельные поля в выводе JSON. Хотя, поскольку logstash-logback-encoder чрезвычайно настраиваемый, вы можете написать собственныйJsonProvider который проанализировал сообщение журнала от reactor.netty.http.server.AccessLog и разделить его на отдельные поля JSON.

Другие вопросы по тегам