Refactored prefix, added logging of configuration.

This commit is contained in:
Stephan Schnabel 2021-12-13 11:02:05 +01:00
parent 0adbe47739
commit 0edd98d7a4
Signed by: stephan.schnabel
GPG key ID: F74FE2422AA07290
4 changed files with 39 additions and 38 deletions

View file

@ -18,10 +18,12 @@ import io.micronaut.http.filter.ServerFilterChain;
*/ */
public abstract class AbstractMdcFilter implements HttpServerFilter { public abstract class AbstractMdcFilter implements HttpServerFilter {
private final int order; protected final int order;
protected final String prefix;
public AbstractMdcFilter(Integer order) { protected AbstractMdcFilter(Integer order, String prefix) {
this.order = order; this.order = order;
this.prefix = prefix;
} }
@Override @Override
@ -38,10 +40,14 @@ public abstract class AbstractMdcFilter implements HttpServerFilter {
return chain.proceed(request); return chain.proceed(request);
} }
mdc.forEach(MDC::put); mdc.forEach((key, value) -> MDC.put(addPrefix(key), value));
return Publishers.map(chain.proceed(request), response -> { return Publishers.map(chain.proceed(request), response -> {
mdc.keySet().forEach(MDC::remove); mdc.keySet().forEach(key -> MDC.remove(addPrefix(key)));
return response; return response;
}); });
} }
private String addPrefix(String key) {
return prefix == null ? key : prefix + key;
}
} }

View file

@ -1,19 +1,18 @@
package io.kokuwa.micronaut.logging.http.level; package io.kokuwa.micronaut.logging.http.level;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.slf4j.MDC;
import ch.qos.logback.classic.turbo.TurboFilter; import ch.qos.logback.classic.turbo.TurboFilter;
import io.kokuwa.micronaut.logging.LogbackUtil; import io.kokuwa.micronaut.logging.LogbackUtil;
import io.kokuwa.micronaut.logging.http.AbstractMdcFilter; import io.kokuwa.micronaut.logging.http.AbstractMdcFilter;
import io.micronaut.context.annotation.Requires; import io.micronaut.context.annotation.Requires;
import io.micronaut.context.annotation.Value; import io.micronaut.context.annotation.Value;
import io.micronaut.core.async.publisher.Publishers;
import io.micronaut.core.util.StringUtils; import io.micronaut.core.util.StringUtils;
import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpResponse; import io.micronaut.http.MutableHttpResponse;
@ -45,7 +44,7 @@ public class LogLevelServerFilter extends AbstractMdcFilter {
LogbackUtil logback, LogbackUtil logback,
@Value("${" + PREFIX + ".header}") Optional<String> header, @Value("${" + PREFIX + ".header}") Optional<String> header,
@Value("${" + PREFIX + ".order}") Optional<Integer> order) { @Value("${" + PREFIX + ".order}") Optional<Integer> order) {
super(order.orElse(DEFAULT_ORDER)); super(order.orElse(DEFAULT_ORDER), null);
this.logback = logback; this.logback = logback;
this.header = header.orElse(DEFAULT_HEADER); this.header = header.orElse(DEFAULT_HEADER);
} }
@ -62,15 +61,8 @@ public class LogLevelServerFilter extends AbstractMdcFilter {
@Override @Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) { public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
var level = request.getHeaders().getFirst(header); return request.getHeaders().getFirst(header)
if (level.isPresent()) { .map(level -> doFilter(request, chain, Map.of(MDC_KEY, level)))
MDC.put(MDC_KEY, level.get()); .orElseGet(() -> chain.proceed(request));
return Publishers.map(chain.proceed(request), response -> {
MDC.remove(MDC_KEY);
return response;
});
} else {
return chain.proceed(request);
}
} }
} }

View file

@ -1,11 +1,10 @@
package io.kokuwa.micronaut.logging.http.mdc; package io.kokuwa.micronaut.logging.http.mdc;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.slf4j.MDC;
import io.kokuwa.micronaut.logging.http.AbstractMdcFilter; import io.kokuwa.micronaut.logging.http.AbstractMdcFilter;
import io.micronaut.context.annotation.Requires; import io.micronaut.context.annotation.Requires;
@ -18,6 +17,7 @@ import io.micronaut.http.filter.ServerFilterChain;
import io.micronaut.http.filter.ServerFilterPhase; import io.micronaut.http.filter.ServerFilterPhase;
import io.micronaut.runtime.context.scope.Refreshable; import io.micronaut.runtime.context.scope.Refreshable;
import io.micronaut.security.authentication.Authentication; import io.micronaut.security.authentication.Authentication;
import lombok.extern.slf4j.Slf4j;
/** /**
* Filter to add claims from authentication to MDC. * Filter to add claims from authentication to MDC.
@ -28,6 +28,7 @@ import io.micronaut.security.authentication.Authentication;
@Requires(classes = Authentication.class) @Requires(classes = Authentication.class)
@Requires(property = AuthenticationMdcFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE) @Requires(property = AuthenticationMdcFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@Filter("${" + AuthenticationMdcFilter.PREFIX + ".path:/**}") @Filter("${" + AuthenticationMdcFilter.PREFIX + ".path:/**}")
@Slf4j
public class AuthenticationMdcFilter extends AbstractMdcFilter { public class AuthenticationMdcFilter extends AbstractMdcFilter {
public static final String PREFIX = "logger.http.authentication"; public static final String PREFIX = "logger.http.authentication";
@ -35,18 +36,19 @@ public class AuthenticationMdcFilter extends AbstractMdcFilter {
public static final int DEFAULT_ORDER = ServerFilterPhase.SECURITY.after(); public static final int DEFAULT_ORDER = ServerFilterPhase.SECURITY.after();
private final String name; private final String name;
private final List<String> attributes; private final Set<String> attributes;
private final String prefix;
public AuthenticationMdcFilter( public AuthenticationMdcFilter(
@Value("${" + PREFIX + ".name:principal}") Optional<String> name, @Value("${" + PREFIX + ".name}") Optional<String> name,
@Value("${" + PREFIX + ".attributes:[]}") List<String> attributes, @Value("${" + PREFIX + ".attributes}") Optional<Set<String>> attributes,
@Value("${" + PREFIX + ".prefix}") Optional<String> prefix, @Value("${" + PREFIX + ".prefix}") Optional<String> prefix,
@Value("${" + PREFIX + ".order}") Optional<Integer> order) { @Value("${" + PREFIX + ".order}") Optional<Integer> order) {
super(order.orElse(DEFAULT_ORDER)); super(order.orElse(DEFAULT_ORDER), prefix.orElse(null));
this.name = name.orElse(DEFAULT_NAME); this.name = name.orElse(DEFAULT_NAME);
this.prefix = prefix.orElse(null); this.attributes = attributes.orElseGet(Set::of);
this.attributes = attributes; if (name.isPresent() || !this.attributes.isEmpty()) {
log.info("Configured with name {} and attributes {}", name, attributes);
}
} }
@Override @Override
@ -54,21 +56,21 @@ public class AuthenticationMdcFilter extends AbstractMdcFilter {
// get authentication // get authentication
var optional = request.getUserPrincipal(Authentication.class); var authenticationOptional = request.getUserPrincipal(Authentication.class);
if (optional.isEmpty()) { if (authenticationOptional.isEmpty()) {
return chain.proceed(request); return chain.proceed(request);
} }
var authentication = optional.get(); var authentication = authenticationOptional.get();
var authenticationAttributes = authentication.getAttributes(); var authenticationAttributes = authentication.getAttributes();
// add mdc // add mdc
var mdc = new HashMap<String, String>(); var mdc = new HashMap<String, String>();
MDC.put(prefix == null ? name : prefix + name, authentication.getName()); mdc.put(name, authentication.getName());
for (var header : attributes) { for (var attibuteName : attributes) {
var value = authenticationAttributes.get(header); var attibuteValue = authenticationAttributes.get(attibuteName);
if (value != null) { if (attibuteValue != null) {
mdc.put(prefix == null ? header : prefix + header, String.valueOf(value)); mdc.put(attibuteName, String.valueOf(attibuteValue));
} }
} }

View file

@ -18,6 +18,7 @@ import io.micronaut.http.annotation.Filter;
import io.micronaut.http.filter.ServerFilterChain; import io.micronaut.http.filter.ServerFilterChain;
import io.micronaut.http.filter.ServerFilterPhase; import io.micronaut.http.filter.ServerFilterPhase;
import io.micronaut.runtime.context.scope.Refreshable; import io.micronaut.runtime.context.scope.Refreshable;
import lombok.extern.slf4j.Slf4j;
/** /**
* Filter to add http headers to MDC. * Filter to add http headers to MDC.
@ -28,21 +29,21 @@ import io.micronaut.runtime.context.scope.Refreshable;
@Requires(property = HttpHeadersMdcFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE) @Requires(property = HttpHeadersMdcFilter.PREFIX + ".enabled", notEquals = StringUtils.FALSE)
@Requires(property = HttpHeadersMdcFilter.PREFIX + ".names") @Requires(property = HttpHeadersMdcFilter.PREFIX + ".names")
@Filter("${" + HttpHeadersMdcFilter.PREFIX + ".path:/**}") @Filter("${" + HttpHeadersMdcFilter.PREFIX + ".path:/**}")
@Slf4j
public class HttpHeadersMdcFilter extends AbstractMdcFilter { public class HttpHeadersMdcFilter extends AbstractMdcFilter {
public static final String PREFIX = "logger.http.headers"; public static final String PREFIX = "logger.http.headers";
public static final int DEFAULT_ORDER = ServerFilterPhase.FIRST.before(); public static final int DEFAULT_ORDER = ServerFilterPhase.FIRST.before();
private final Set<String> headers; private final Set<String> headers;
private final String prefix;
public HttpHeadersMdcFilter( public HttpHeadersMdcFilter(
@Value("${" + PREFIX + ".names}") List<String> headers, @Value("${" + PREFIX + ".names}") List<String> headers,
@Value("${" + PREFIX + ".prefix}") Optional<String> prefix, @Value("${" + PREFIX + ".prefix}") Optional<String> prefix,
@Value("${" + PREFIX + ".order}") Optional<Integer> order) { @Value("${" + PREFIX + ".order}") Optional<Integer> order) {
super(order.orElse(DEFAULT_ORDER)); super(order.orElse(DEFAULT_ORDER), prefix.orElse(null));
this.prefix = prefix.orElse(null);
this.headers = headers.stream().map(String::toLowerCase).collect(Collectors.toSet()); this.headers = headers.stream().map(String::toLowerCase).collect(Collectors.toSet());
log.info("Configured with header names {}", headers);
} }
@Override @Override
@ -51,7 +52,7 @@ public class HttpHeadersMdcFilter extends AbstractMdcFilter {
for (var header : headers) { for (var header : headers) {
request.getHeaders() request.getHeaders()
.getFirst(header) .getFirst(header)
.ifPresent(value -> mdc.put(prefix == null ? header : prefix + header, String.valueOf(value))); .ifPresent(value -> mdc.put(header, String.valueOf(value)));
} }
return doFilter(request, chain, mdc); return doFilter(request, chain, mdc);
} }