processor.netty.http.server.AccessLog, производящий LoggingEvent, а не AccessEvent - PullRequest
0 голосов
/ 05 февраля 2019

Я пытался настроить spring-boot 2.1 с webflux для хранения журналов доступа в формате JSON.Более того, мне нужно иметь такую ​​информацию, как протокол, код состояния в виде отдельных полей JSON (а не части сообщения).Просматривая интернет я нашел 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

.

1 Ответ

0 голосов
/ 24 марта 2019

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

Реактор-нетти 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 чрезвычайно настраиваемый, вы можете написать custom JsonProvider, который будет анализировать сообщение журнала из reactor.netty.http.server.AccessLog и разбивать его на отдельные поля JSON.

...