Skip to content

Instantly share code, notes, and snippets.

@abhi2495
Last active March 7, 2024 06:26
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save abhi2495/2f025384dde46cf6fa212e1597efde30 to your computer and use it in GitHub Desktop.
Save abhi2495/2f025384dde46cf6fa212e1597efde30 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