Search code examples
javaundertow

unable to see Undertow logs via SLF4J


I asked this question on the Undertow dev group, but received no response.

I wrote a sample test application using Java 17. I've used embedded Tomcat in the past, but I read high reviews for Undertow so I wanted to try it out. I don't need Java/Jakarta EE servlets; I just need to respond to requests using path templates.

I successfully started up an Undertow server and so far it's working as expected. But no logging. I see in Undertow.start() that I should see "starting server: …", but I don't.

    public synchronized void start() {
        UndertowLogger.ROOT_LOGGER.infof("starting server: %s", Version.getFullVersionString());

I'm using io.undertow:undertow-core:2.3.10.Final. For logging I'm using SLF4J 2.0.9 and Logback 1.4.11. I have my Logback file configured to use INFO level logging:

<configuration>
  <root level="info">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

I even tried (after a bit of research) forcing JBoss Logging to use SLF4J before starting the server:

System.setProperty("org.jboss.logging.provider", "slf4j");

Still no logs from Undertow

I stepped through the code. Undertow's Slf4jLocationAwareLogger is calling LOG_METHOD.invoke(logger, null, className, Integer.valueOf(level), text, EMPTY, thrown) where level has a value of 20. Using reflection this invokes Logback's Logger.filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params, final Throwable t) method the if (effectiveLevelInt > level.levelInt) check fails because effectiveLevelInt is 10000 and level.levelInt is 20000, so the method returns without logging (i.e. without calling buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t)).

First of all, why am I not getting any logs?

Secondly, why is Undertow invoking Logback directly? The whole point of SLF4J is to provide a general abstraction layer across loggers. How can I make Undertow invoke SLF4J directly? (In fact, the latest SLF4J allows system properties to specify an actual logging implementation; see SLF4J-450. If Undertow is bypassing SLF4J and requires Logback, or tries to guess the logging implementation and access it directly, that defeats the whole purpose of SLF4J and will break.)

Undertow looks really promising, and it worked well enough for me to give a demo at a recent Java user group meeting. But I hope I can get Undertow logging working via SLF4J, as that is critical for any embedded server.


Solution

  • For what it's worth, Undertow does not use SLF4J, it uses jboss-logging which is a facade similar SLF4J.

    The issue is your logback.xml file. You need to define the STDOUT appender. Something like:

    <configuration>
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n</pattern>
            </encoder>
        </appender>
        <root level="info">
            <appender-ref ref="STDOUT"/>
        </root>
    </configuration>
    

    Without defining the STDOUT appender there is not appender for the reference so nothing is logged.