Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesushenriquez/51455b9e16cadd1336e3ca96f0727ae4 to your computer and use it in GitHub Desktop.
Save jesushenriquez/51455b9e16cadd1336e3ca96f0727ae4 to your computer and use it in GitHub Desktop.
##################################################################################
##################################################################################
######### IF YOU FOUND THIS GIST USEFUL, PLEASE LEAVE A STAR. THANKS. ############
##################################################################################
##################################################################################
logging:
pattern:
console: "%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} %clr(%5p) %clr(%-40.40logger{39}) :[%8X{tenant}] %m%n${LOG_EXCEPTION_CONVERSION_WORD:%rEx}"
public final class LogUtil {
private LogUtil() {
}
public static <T> Consumer<Signal<T>> logOnNext(Consumer<T> logStatement) {
return signal -> {
if (!signal.isOnNext())
return;
Optional<String> optionalTenant = signal.getContext().getOrEmpty("TENANT_CONTEXT");
optionalTenant.ifPresentOrElse(tenant -> {
try (MDC.MDCCloseable closeable = MDC.putCloseable("tenant", tenant)) {
logStatement.accept(signal.get());
}
}, () -> logStatement.accept(signal.get()));
};
}
public static <T> Consumer<Signal<T>> logOnError(Consumer<Throwable> logStatement) {
return signal -> {
if (!signal.isOnError())
return;
Optional<String> optionalTenant = signal.getContext().getOrEmpty("TENANT_CONTEXT");
optionalTenant.ifPresentOrElse(tenant -> {
try (MDC.MDCCloseable closeable = MDC.putCloseable("tenant", tenant)) {
logStatement.accept(signal.getThrowable());
}
}, () -> logStatement.accept(signal.getThrowable()));
};
}
public static <T> Consumer<Signal<T>> logOnComplete(Consumer<T> logStatement) {
return signal -> {
if (!signal.isOnComplete())
return;
Optional<String> optionalTenant = signal.getContext().getOrEmpty("TENANT_CONTEXT");
optionalTenant.ifPresentOrElse(tenant -> {
try (MDC.MDCCloseable closeable = MDC.putCloseable("tenant", tenant)) {
logStatement.accept(signal.get());
}
}, () -> logStatement.accept(signal.get()));
};
}
}
public class TenancyContextFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String tenantAlias = extractTenantAliasFromRequest(exchange.getRequest());
if (tenantAlias != null) {
return chain.filter(exchange)
.subscriberContext(context -> {
return context.put("TENANT_CONTEXT", tenantAlias);
});
} else {
LOGGER.error(...);
return Mono.error(new TenantExtractionException());
}
}
}
someMono
.doOnEach(LogUtil.logOnNext(obj -> logger.info(...)))
someMono
.doOnEach(LogUtil.logOnComplete(obj -> logger.info(...)))
someMono
.doOnEach(LogUtil.logOnError(err -> logger.error(...)))

A technique to do MDC logging in reactive JAVA web application using Spring.

An example demonstrating printing of tenant id as mdc in logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment