Skip to main content
Entwickler Themen
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

2.4. Quarkus

Hier finden sich nur ein paar Dinge, die ich für mich gebaut hatte und die ich hilfreich gefunden habe.

Logging aller ausgehender Requests

Alle ausgehenden Web-Requests lassen sich über einen RequestFilter loggen.

package de.neitzel.quarkus.util;

import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.ext.Provider;
import org.jboss.logging.Logger;

@Provider
public class LoggingRequestFilter implements ClientRequestFilter {

  private static final Logger LOG = Logger.getLogger(LoggingRequestFilter.class);

  @Override
  public void filter(ClientRequestContext requestContext) {
    LOG.infof("➡️  Calling %s %s", requestContext.getMethod(), requestContext.getUri());
    requestContext.getHeaders().forEach((k, v) -> LOG.infof("Header %s: %s", k, v));
  }
}

Logging aller eingehenden Requests

Body werden nicht gelesen, da diese den Stream “verbrauchen” können.

Logging von Quarkus konfigurieren

quarkus:
  http:
    access-log:
      enabled: true
      # pattern: common | combined | eigener Pattern-String
      pattern: combined
      # optional: ins File statt nur im Log
      # log-to-file: true
      # base-file-name: access
      # log-directory: log

Deckt jede Anfrage ab (auch 404/405/Static/Extensions).

„combined“ enthält Methode, Pfad, Status, Größe, Referer, User-Agent.

Für Feinschliff kannst du einen Custom-Pattern setzen.

JAX-RS-Filter (REST Layer)

ContainerRequestFilter mit @PreMatching

package de.neitzel.quarkus.util;

import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.ext.Provider;
import org.jboss.logging.Logger;

@Provider
@PreMatching                       // läuft vor dem Routing/Matching
@Priority(Priorities.USER)
public class IncomingRequestFilter implements ContainerRequestFilter {
  private static final Logger LOG = Logger.getLogger(IncomingRequestFilter.class);

  @Override
  public void filter(ContainerRequestContext ctx) {
    LOG.infof("⬅️  %s %s", ctx.getMethod(), ctx.getUriInfo().getRequestUri());
    ctx.getHeaders().forEach((k, v) -> LOG.infof("Header %s: %s", k, v));
  }
}

RESTeasy reactive “spezial”

package de.neitzel.quarkus.util;

import org.jboss.resteasy.reactive.server.ServerRequestFilter;
import org.jboss.resteasy.reactive.server.ServerResponseFilter;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import org.jboss.logging.Logger;

public class RequestAndResponseLoggingFilters {
  private static final Logger LOG = Logger.getLogger(RrLoggingFilters.class);

  @ServerRequestFilter
  public void logReq(HttpServerRequest req) {
    LOG.infof("⬅️  %s %s", req.method(), req.uri());
  }

  @ServerResponseFilter
  public void logRes(HttpServerResponse res) {
    LOG.infof("➡️  Status %d", res.getStatusCode());
  }
}

Vert.x Ebene (läuft vor allen Routen)

package de.neitzel.quarkus.util;

import io.quarkus.vertx.web.RouteFilter;
import io.vertx.ext.web.RoutingContext;
import org.jboss.logging.Logger;

public class GlobalRouteLogging {
  private static final Logger LOG = Logger.getLogger(GlobalRouteLogging.class);

  // kleinere Zahl = höhere Priorität
  @RouteFilter(100)
  void logAll(RoutingContext rc) {
    LOG.infof("⬅️  %s %s", rc.request().method(), rc.request().uri());
    rc.request().headers().forEach(h -> LOG.infof("Header %s: %s", h.getKey(), h.getValue()));
    rc.next(); // wichtig: weiterreichen
  }
}