HTTP access logging has many uses, debugging, auditing, metrics, alarms and many more. Undertow has a very extensible access logging handler where you can customize whatever format you want and plug in your own logging framework.

Basic Routes

These are copy pasted from a previous post on Undertow's RoutingHandler so they may look familliar.

// For brevity just borrow the RoutingServer routes. Copy Pasta!
private static final HttpHandler ROUTES = new RoutingHandler()
    .get("/", RoutingHandlers.constantStringHandler("GET - My Homepage"))
    .get("/myRoute", RoutingHandlers.constantStringHandler("GET - My Route"))
    .post("/myRoute", RoutingHandlers.constantStringHandler("POST - My Route"))
    .get("/myOtherRoute", RoutingHandlers.constantStringHandler("GET - My Other Route"))
    // Wildcards and RoutingHandler had some bugs before version 1.4.8.Final
    .get("/myRoutePrefix*", RoutingHandlers.constantStringHandler("GET - My Prefixed Route"))
    // Pass a handler as a method reference.
    .setFallbackHandler(RoutingHandlers::notFoundHandler)
;

Adding the AccessLogHandler

AccessLogHandler has a few constructors but here is a simple implementation. The default access log receiver is JBossLoggingAccessLogReceiver.java however we will be using Slf4jAccessLogReceiver.java

private static final HttpHandler ROOT = new AccessLogHandler(
    ROUTES,
    new Slf4jAccessLogReceiver(LoggerFactory.getLogger("com.stubbornjava.accesslog")),
    "combined",
    AccessLogServer.class.getClassLoader())
;

Server

public static void main(String[] args) {
    SimpleServer server = SimpleServer.simpleServer(ROOT);
    server.start();
}

Output

Requests

curl -X GET localhost:8080
GET - My Homepage
curl -X GET localhost:8080/myRoute
GET - My Route
curl -X POST localhost:8080/myRoute
POST - My Route
curl -X GET localhost:8080/myOtherRoute
GET - My Other Route
curl -X GET localhost:8080/myRoutePrefix
GET - My Prefixed Route
curl -X GET localhost:8080/myRoutePrefixTest
GET - My Prefixed Route
curl -X GET localhost:8080/123
Page Not Found!!

Log File / Console

08:23:51.254 [XNIO-1 I/O-1] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:23:51 -0500] "GET / HTTP/1.1" 200 18 "-" "curl/7.49.1"
08:23:59.172 [XNIO-1 I/O-3] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:23:59 -0500] "GET /myRoute HTTP/1.1" 200 15 "-" "curl/7.49.1"
08:24:05.492 [XNIO-1 I/O-1] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:24:05 -0500] "POST /myRoute HTTP/1.1" 200 16 "-" "curl/7.49.1"
08:24:15.732 [XNIO-1 I/O-3] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:24:15 -0500] "GET /myOtherRoute HTTP/1.1" 200 21 "-" "curl/7.49.1"
08:24:22.462 [XNIO-1 I/O-1] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:24:22 -0500] "GET /myRoutePrefix HTTP/1.1" 200 24 "-" "curl/7.49.1"
08:24:28.743 [XNIO-1 I/O-3] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:24:28 -0500] "GET /myRoutePrefixTest HTTP/1.1" 200 24 "-" "curl/7.49.1"
08:24:35.480 [XNIO-1 I/O-2] INFO com.stubbornjava.accesslog - 127.0.0.1 - - [11/Jan/2017:08:24:35 -0500] "GET /123 HTTP/1.1" 404 16 "-" "curl/7.49.1"

Now we have all the basics for access logging date, http method, url, status code, ip, user agent and more. Remember this is very configurable.