Add request filter.
This commit is contained in:
parent
c4b1d1d2f6
commit
c3d38e2d11
12 changed files with 500 additions and 0 deletions
|
@ -0,0 +1,75 @@
|
|||
package io.kokuwa.micronaut.logging.request;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import ch.qos.logback.classic.turbo.TurboFilter;
|
||||
import io.kokuwa.micronaut.logging.LogbackUtil;
|
||||
import io.micronaut.context.annotation.Requires;
|
||||
import io.micronaut.context.annotation.Value;
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.http.MutableHttpResponse;
|
||||
import io.micronaut.http.annotation.Filter;
|
||||
import io.micronaut.http.filter.HttpServerFilter;
|
||||
import io.micronaut.http.filter.ServerFilterChain;
|
||||
import io.micronaut.http.filter.ServerFilterPhase;
|
||||
import io.micronaut.runtime.server.EmbeddedServer;
|
||||
|
||||
/**
|
||||
* Http request logging filter.
|
||||
*
|
||||
* @author Stephan Schnabel
|
||||
*/
|
||||
@Requires(beans = EmbeddedServer.class)
|
||||
@Requires(property = HeaderLoggingHttpFilter.ENABLED, notEquals = "false")
|
||||
@Filter("${" + HeaderLoggingHttpFilter.PREFIX + ".pattern:" + HeaderLoggingHttpFilter.DEFAULT_PATTERN + ":/**}")
|
||||
public class HeaderLoggingHttpFilter implements HttpServerFilter {
|
||||
|
||||
public static final String PREFIX = "logger.request.header";
|
||||
public static final String ENABLED = PREFIX + ".enabled";
|
||||
public static final String MDC_FILTER = PREFIX + ".filter";
|
||||
public static final String MDC_KEY = "level";
|
||||
|
||||
public static final String DEFAULT_HEADER = "x-log-level";
|
||||
public static final String DEFAULT_PATTERN = "/**";
|
||||
public static final int DEFAULT_ORDER = ServerFilterPhase.FIRST.before();
|
||||
|
||||
private final LogbackUtil logback;
|
||||
private final String header;
|
||||
private final int order;
|
||||
|
||||
public HeaderLoggingHttpFilter(
|
||||
LogbackUtil logback,
|
||||
@Value("${" + PREFIX + ".header:" + DEFAULT_HEADER + "}") String header,
|
||||
@Value("${" + PREFIX + ".order}") Optional<Integer> order) {
|
||||
this.logback = logback;
|
||||
this.header = header;
|
||||
this.order = order.orElse(DEFAULT_ORDER);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
void startTurbofilter() {
|
||||
logback.getTurboFilter(HeaderLoggingTurboFilter.class, MDC_FILTER, HeaderLoggingTurboFilter::new).start();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void stopTurbofilter() {
|
||||
logback.getTurboFilter(HeaderLoggingTurboFilter.class, MDC_FILTER).ifPresent(TurboFilter::stop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
|
||||
request.getHeaders().getFirst(header).ifPresent(level -> MDC.put(MDC_KEY, level));
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package io.kokuwa.micronaut.logging.request;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.slf4j.Marker;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.turbo.TurboFilter;
|
||||
import ch.qos.logback.core.spi.FilterReply;
|
||||
|
||||
/**
|
||||
* Filter for log levels based on MDC.
|
||||
*
|
||||
* @author Stephan Schnabel
|
||||
*/
|
||||
public class HeaderLoggingTurboFilter extends TurboFilter {
|
||||
|
||||
@Override
|
||||
public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
|
||||
|
||||
if (!isStarted()) {
|
||||
return FilterReply.NEUTRAL;
|
||||
}
|
||||
|
||||
var value = MDC.get(HeaderLoggingHttpFilter.MDC_KEY);
|
||||
if (value == null) {
|
||||
return FilterReply.NEUTRAL;
|
||||
}
|
||||
|
||||
return level.isGreaterOrEqual(Level.valueOf(value)) ? FilterReply.ACCEPT : FilterReply.NEUTRAL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package io.kokuwa.micronaut.logging.request;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import io.micronaut.context.annotation.Requires;
|
||||
import io.micronaut.context.annotation.Value;
|
||||
import io.micronaut.http.HttpRequest;
|
||||
import io.micronaut.http.MutableHttpResponse;
|
||||
import io.micronaut.http.annotation.Filter;
|
||||
import io.micronaut.http.filter.HttpServerFilter;
|
||||
import io.micronaut.http.filter.ServerFilterChain;
|
||||
import io.micronaut.http.filter.ServerFilterPhase;
|
||||
import io.micronaut.runtime.server.EmbeddedServer;
|
||||
|
||||
/**
|
||||
* Http request principal filter.
|
||||
*
|
||||
* @author Stephan Schnabel
|
||||
*/
|
||||
@Requires(beans = EmbeddedServer.class)
|
||||
@Requires(property = PrincipalHttpFilter.ENABLED, notEquals = "false")
|
||||
@Filter("${" + PrincipalHttpFilter.PREFIX + ".pattern:" + PrincipalHttpFilter.DEFAULT_PATTERN + ":/**}")
|
||||
public class PrincipalHttpFilter implements HttpServerFilter {
|
||||
|
||||
public static final String PREFIX = "logger.request.principal";
|
||||
public static final String ENABLED = PREFIX + ".enabled";
|
||||
|
||||
public static final String DEFAULT_KEY = "principal";
|
||||
public static final String DEFAULT_PATTERN = "/**";
|
||||
public static final int DEFAULT_ORDER = ServerFilterPhase.SECURITY.after();
|
||||
|
||||
private final String key;
|
||||
private final int order;
|
||||
|
||||
public PrincipalHttpFilter(
|
||||
@Value("${" + PREFIX + ".key:" + DEFAULT_KEY + "}") String key,
|
||||
@Value("${" + PREFIX + ".order}") Optional<Integer> order) {
|
||||
this.key = key;
|
||||
this.order = order.orElse(DEFAULT_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
|
||||
request.getUserPrincipal().ifPresent(princial -> MDC.put(key, princial.getName()));
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue