resteasyserver-sent-eventswildfly-15

Disable logging for server-sent-events errors in RESTEasy


I'm currently working with server-sent-events using RESTEasy in Wildfly. So far everything is working, except that sometimes the SSE implementation doesn't somehow recognize that the client(s) listening to events is/are already closed (also the close() method of the SseEventSourceon the client-side was called). In aspect of the program logic this isn't a problem at all.

But unfortunately org.jboss.resteasy.plugins.providers.sse.SseEventOutputImpl class which is used to send the events, does - in addition to reporting the exception back to org.jboss.resteasy.plugins.providers.sse.SseBroadcasterImpl - not only report the exception, but also logs it using the failedToWriteSseEvent(String, Throwable) method of the org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages (later class is based on the JBoss logging). So I get every now and then an unnecessary log messages on level ERROR telling me that the connection was closed by the client. And it get that entry in the log in addition to the onClose event I get from the SseBroadcaster.

Configuring the JBoss logging seems impossible as the log name is org.jboss.resteasy.resteasy_jaxrs.i18n which is also used for logging other errors (Means just configuring the logger in the log4j.xml of the deployment won't work / also turn off other errors).

2021-06-22 12:59:27 [ERROR] [org.jboss.resteasy.resteasy_jaxrs.i18n:272] - RESTEASY002030: Failed to write event org.jboss.resteasy.plugins.providers.sse.OutboundSseEventImpl@fd79b33
java.io.IOException: An existing connection was forcibly closed by the remote host
    at sun.nio.ch.SocketDispatcher.writev0(Native Method)
    at sun.nio.ch.SocketDispatcher.writev(Unknown Source)
    at sun.nio.ch.IOUtil.write(Unknown Source)
    at sun.nio.ch.SocketChannelImpl.write(Unknown Source)
    at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:162)
    at io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:647)
    at io.undertow.conduits.ChunkedStreamSinkConduit.doWrite(ChunkedStreamSinkConduit.java:166)
    at io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:128)
    at org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:150)
    at io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:240)
    at io.undertow.server.HttpServerExchange$WriteDispatchChannel.write(HttpServerExchange.java:2103)
    at io.undertow.servlet.spec.ServletOutputStreamImpl.writeBufferBlocking(ServletOutputStreamImpl.java:574)
    at io.undertow.servlet.spec.ServletOutputStreamImpl.flushInternal(ServletOutputStreamImpl.java:489)
    at io.undertow.servlet.spec.ServletOutputStreamImpl.flush(ServletOutputStreamImpl.java:476)
    at io.undertow.servlet.spec.HttpServletResponseImpl.flushBuffer(HttpServletResponseImpl.java:468)
    at javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:221)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletResponseWrapper.flushBuffer(HttpServletResponseWrapper.java:124)
    at org.jboss.resteasy.plugins.providers.sse.SseEventOutputImpl.writeEvent(SseEventOutputImpl.java:264)
    at org.jboss.resteasy.plugins.providers.sse.SseEventOutputImpl.send(SseEventOutputImpl.java:199)
    at org.jboss.resteasy.plugins.providers.sse.SseBroadcasterImpl.lambda$null$4(SseBroadcasterImpl.java:150)
    at java.lang.Iterable.forEach(Unknown Source)
    at org.jboss.resteasy.plugins.providers.sse.SseBroadcasterImpl.lambda$broadcast$5(SseBroadcasterImpl.java:146)
    at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source)
    at java.util.concurrent.CompletableFuture$AsyncRun.exec(Unknown Source)
    at java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source)
    at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)

Is there a way to control that logging within RESTEasy and disabling the logging of failedToWriteSseEvent(String, Throwable)? Like introducing / inject an own implementation of LogMessages (but as far as I understand it the interface is used as a proxy, so...)?


Solution

  • You might be hitting RESTEASY-1986. You can filter these out with a log filter though. In CLI something like:

    /subsystem=logging/logger=org.jboss.resteasy.resteasy_jaxrs.i18n:add(filter-spec=not(match(".*RESTEASY002030.*")), level=INFO)