Fix mdc cleanup, propagate level header, code clean up.

This commit is contained in:
Stephan Schnabel 2020-09-12 17:10:11 +02:00
parent 5a5fa8a408
commit 0a7a34cb34
Signed by: stephan.schnabel
GPG key ID: F74FE2422AA07290
10 changed files with 119 additions and 36 deletions

View file

@ -10,6 +10,7 @@ import io.micronaut.context.annotation.Requires;
import io.micronaut.context.env.Environment;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
/**
@ -19,7 +20,7 @@ import lombok.extern.slf4j.Slf4j;
*/
@Requires(beans = LogbackUtil.class)
@Requires(property = MDCTurboFilterConfigurer.PREFIX)
@Requires(property = MDCTurboFilterConfigurer.ENABLED, notEquals = "false")
@Requires(property = MDCTurboFilterConfigurer.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@BootstrapContextCompatible
@Context
@Internal
@ -27,7 +28,6 @@ import lombok.extern.slf4j.Slf4j;
public class MDCTurboFilterConfigurer {
public static final String PREFIX = "logger.mdc";
public static final String ENABLED = PREFIX + ".enabled";
private final LogbackUtil logback;
private final Environment environment;

View file

@ -0,0 +1,56 @@
package io.kokuwa.micronaut.logging.request;
import java.util.Optional;
import org.reactivestreams.Publisher;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MutableHttpRequest;
import io.micronaut.http.annotation.Filter;
import io.micronaut.http.context.ServerRequestContext;
import io.micronaut.http.filter.ClientFilterChain;
import io.micronaut.http.filter.HttpClientFilter;
import io.micronaut.http.filter.ServerFilterPhase;
/**
* Http request logging filter.
*
* @author Stephan Schnabel
*/
@Requires(beans = HeaderLoggingServerHttpFilter.class)
@Requires(property = HeaderLoggingClientHttpFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@Filter("${" + HeaderLoggingClientHttpFilter.PREFIX + ".path:/**}")
public class HeaderLoggingClientHttpFilter implements HttpClientFilter {
public static final String PREFIX = "logger.request.propagation";
public static final int DEFAULT_ORDER = ServerFilterPhase.TRACING.order();
private final String serverHeader;
private final String propagationHeader;
private final int order;
public HeaderLoggingClientHttpFilter(
@Value("${" + HeaderLoggingServerHttpFilter.PREFIX + ".header}") Optional<String> serverHeader,
@Value("${" + PREFIX + ".header}") Optional<String> propagationHeader,
@Value("${" + PREFIX + ".order}") Optional<Integer> order) {
this.serverHeader = serverHeader.orElse(HeaderLoggingServerHttpFilter.DEFAULT_HEADER);
this.propagationHeader = propagationHeader.orElse(this.serverHeader);
this.order = order.orElse(DEFAULT_ORDER);
}
@Override
public int getOrder() {
return order;
}
@Override
public Publisher<? extends HttpResponse<?>> doFilter(MutableHttpRequest<?> targetRequest, ClientFilterChain chain) {
ServerRequestContext.currentRequest()
.flatMap(currentRequest -> currentRequest.getHeaders().getFirst(serverHeader))
.ifPresent(level -> targetRequest.getHeaders().add(propagationHeader, level));
return chain.proceed(targetRequest);
}
}

View file

@ -12,6 +12,8 @@ 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.core.async.publisher.Publishers;
import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Filter;
@ -26,29 +28,27 @@ import io.micronaut.runtime.server.EmbeddedServer;
* @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 {
@Requires(property = HeaderLoggingServerHttpFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@Filter("${" + HeaderLoggingServerHttpFilter.PREFIX + ".path:/**}")
public class HeaderLoggingServerHttpFilter 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 PREFIX = "logger.request.filter";
public static final String MDC_FILTER = PREFIX;
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(
public HeaderLoggingServerHttpFilter(
LogbackUtil logback,
@Value("${" + PREFIX + ".header:" + DEFAULT_HEADER + "}") String header,
@Value("${" + PREFIX + ".header}") Optional<String> header,
@Value("${" + PREFIX + ".order}") Optional<Integer> order) {
this.logback = logback;
this.header = header;
this.header = header.orElse(DEFAULT_HEADER);
this.order = order.orElse(DEFAULT_ORDER);
}
@ -69,7 +69,15 @@ public class HeaderLoggingHttpFilter implements HttpServerFilter {
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
request.getHeaders().getFirst(header).ifPresent(level -> MDC.put(MDC_KEY, level));
return chain.proceed(request);
var level = request.getHeaders().getFirst(header);
if (level.isPresent()) {
MDC.put(MDC_KEY, level.get());
return Publishers.map(chain.proceed(request), response -> {
MDC.remove(MDC_KEY);
return response;
});
} else {
return chain.proceed(request);
}
}
}

View file

@ -22,7 +22,7 @@ public class HeaderLoggingTurboFilter extends TurboFilter {
return FilterReply.NEUTRAL;
}
var value = MDC.get(HeaderLoggingHttpFilter.MDC_KEY);
var value = MDC.get(HeaderLoggingServerHttpFilter.MDC_KEY);
if (value == null) {
return FilterReply.NEUTRAL;
}

View file

@ -7,6 +7,8 @@ import org.slf4j.MDC;
import io.micronaut.context.annotation.Requires;
import io.micronaut.context.annotation.Value;
import io.micronaut.core.async.publisher.Publishers;
import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Filter;
@ -21,15 +23,13 @@ import io.micronaut.runtime.server.EmbeddedServer;
* @author Stephan Schnabel
*/
@Requires(beans = EmbeddedServer.class)
@Requires(property = PrincipalHttpFilter.ENABLED, notEquals = "false")
@Filter("${" + PrincipalHttpFilter.PREFIX + ".pattern:" + PrincipalHttpFilter.DEFAULT_PATTERN + ":/**}")
@Requires(property = PrincipalHttpFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@Filter("${" + PrincipalHttpFilter.PREFIX + ".path:/**}")
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;
@ -49,7 +49,15 @@ public class PrincipalHttpFilter implements HttpServerFilter {
@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
request.getUserPrincipal().ifPresent(princial -> MDC.put(key, princial.getName()));
return chain.proceed(request);
var princial = request.getUserPrincipal();
if (princial.isPresent()) {
MDC.put(key, princial.get().getName());
return Publishers.map(chain.proceed(request), response -> {
MDC.remove(key);
return response;
});
} else {
return chain.proceed(request);
}
}
}

View file

@ -9,7 +9,7 @@ import ch.qos.logback.classic.Level;
import io.kokuwa.micronaut.logging.AbstractTest;
/**
* Test for {@link HeaderLoggingHttpFilter}.
* Test for {@link HeaderLoggingServerHttpFilter}.
*
* @author Stephan Schnabel
*/

View file

@ -19,7 +19,7 @@ import io.micronaut.http.client.annotation.Client;
import io.micronaut.security.token.jwt.signature.SignatureGeneratorConfiguration;
/**
* Contoller for testing {@link HeaderLoggingHttpFilter} and {@link PrincipalHttpFilter}.
* Contoller for testing {@link HeaderLoggingServerHttpFilter} and {@link PrincipalHttpFilter}.
*
* @author Stephan Schnabel
*/
@ -48,7 +48,7 @@ public class TestClient {
request.bearerAuth(token);
}
if (header != null) {
request.getHeaders().add(HeaderLoggingHttpFilter.DEFAULT_HEADER, header);
request.getHeaders().add(HeaderLoggingServerHttpFilter.DEFAULT_HEADER, header);
}
var response = client.toBlocking().exchange(request, TestResponse.class);

View file

@ -13,7 +13,7 @@ import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* Controller for testing {@link HeaderLoggingHttpFilter} and {@link PrincipalHttpFilter}.
* Controller for testing {@link HeaderLoggingServerHttpFilter} and {@link PrincipalHttpFilter}.
*
* @author Stephan Schnabel
*/