Implementing MDC with ServerSocketReceiver

Hi, I'm trying to implement a TCP server which logs to different appenders depending on the message content. I'm using ServerSocketReceiver and SiftingAppender strategy based on MDC value. Here's my snippet: siftingAppender.setAppenderFactory((Context context1, String discriminatingValue) -> { Appender appender; if (DISCRIMINATOR_DEFAULT_VALUE.equals(discriminatingValue)) { ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>(); consoleAppender.setContext(context); consoleAppender.setEncoder(consoleOnlyEncoder(context)); consoleAppender.setName("MY_CONSOLE_APPENDER"); consoleAppender.start(); appender = consoleAppender; } else { RollingFileAppender rollingFileAppender = rollingFileAppender("MY_ROLLING_APPENDER", "myPrefix." + discriminatingValue + ".%d{yyyy-MM-dd_HH-mm}.log", context); AsyncAppender asyncAppender = asyncAppender(rollingFileAppender, context); appender = asyncAppender; } return appender; }); Let's say that my MDC discriminator key is "filename". My first challenge with this approach is that the MDC value is not serialized and sent to server. So, I changed the message format to "filename={},msg{}" and I created a Turbo Filter, which would check if the rawMessage is equal to this expression and, if so, It would log using the MDC discriminator. Here's the snippet: private static void addMDCInterceptorTurboFilter(LoggerContext context) { String regex = DISCRIMINATOR_KEY.concat("={},").concat(MESSAGE_KEY).concat("={}"); // "filename={},msg={}" TurboFilter mdcInterceptorFilter = new TurboFilter() { @Override public FilterReply decide(Marker marker, ch.qos.logback.classic.Logger logger, Level level, String rawMessage, Object[] params, Throwable t) { if (params != null && regex.equals(rawMessage)) { MDC.put(DISCRIMINATOR_KEY, (String) params[0]); logger.log(marker, this.getClass().getName(), Level.toLocationAwareLoggerInteger(level), (String) params[1], null, null); MDC.remove(DISCRIMINATOR_KEY); return FilterReply.DENY; } return FilterReply.NEUTRAL; } }; context.addTurboFilter(mdcInterceptorFilter); mdcInterceptorFilter.setName("MY_MDC_INTERCEPTOR_FILTER"); mdcInterceptorFilter.start(); } My challenge in the above approach is that neither the *rawMessage* nor *params* are populated at this time. So I can't set the MDC properly. Another approach that I tried was to set the filter to the SiftingAppender and set the MDC there, but it didn't work either. Here's the snippet: private Filter<ILoggingEvent> addMDCInterceptorFilter(String keyDiscriminator, String messageKey) { String regex = keyDiscriminator.concat("={},").concat(messageKey).concat("={}"); Filter<ILoggingEvent> filter = new Filter<ILoggingEvent>() { @Override public FilterReply decide(ILoggingEvent event) { if (regex.equals(event.getMessage())) { MDC.put(keyDiscriminator, (String)event.getArgumentArray()[0]); } else { MDC.remove(keyDiscriminator); } return FilterReply.NEUTRAL; } }; filter.start(); return filter; } Could you guys guide me how to accomplish this scenario ? Please find the full source for sake of completeness. Thanks, import ch.qos.logback.classic.AsyncAppender; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.net.server.ServerSocketReceiver; import ch.qos.logback.classic.sift.MDCBasedDiscriminator; import ch.qos.logback.classic.sift.SiftingAppender; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.turbo.TurboFilter; import ch.qos.logback.core.Appender; import ch.qos.logback.core.ConsoleAppender; import ch.qos.logback.core.Context; import ch.qos.logback.core.encoder.Encoder; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.RollingPolicy; import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; import ch.qos.logback.core.spi.FilterReply; import ch.qos.logback.core.util.StatusPrinter; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import org.slf4j.Marker; import java.nio.charset.Charset; public class MySocketServer { private static final String DISCRIMINATOR_KEY = "filename"; private static final String DISCRIMINATOR_DEFAULT_VALUE = "unknown"; private static final String MESSAGE_KEY = "msg"; public static void main(String[] args) throws InterruptedException { LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); StatusPrinter.print(context); addMDCInterceptorTurboFilter(context); newServerSocketReceiver(context); addAppenders(context); Thread.sleep(Long.MAX_VALUE); } private static void newServerSocketReceiver(LoggerContext context) { ServerSocketReceiver serverSocketReceiver = new ServerSocketReceiver(); serverSocketReceiver.setContext(context); serverSocketReceiver.setPort(6000); serverSocketReceiver.setAddress("localhost"); serverSocketReceiver.start(); } private static void addAppenders(LoggerContext context) { SiftingAppender siftingAppender = siftingAppender(context); ch.qos.logback.classic.Logger logger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); logger.detachAndStopAllAppenders(); logger.addAppender(siftingAppender); } private static SiftingAppender siftingAppender(LoggerContext context) { SiftingAppender siftingAppender = new SiftingAppender(); siftingAppender.setContext(context); siftingAppender.setName("MY_SIFT_APPENDER"); siftingAppender.setDiscriminator(getMdcBasedDiscriminator(context)); siftingAppender.setAppenderFactory((Context context1, String discriminatingValue) -> { Appender appender; if (DISCRIMINATOR_DEFAULT_VALUE.equals(discriminatingValue)) { ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>(); consoleAppender.setContext(context); consoleAppender.setEncoder(consoleOnlyEncoder(context)); consoleAppender.setName("MY_CONSOLE_APPENDER"); consoleAppender.start(); appender = consoleAppender; } else { RollingFileAppender rollingFileAppender = rollingFileAppender("MY_ROLLING_APPENDER", "myPrefix." + discriminatingValue + ".%d{yyyy-MM-dd_HH-mm}.log", context); AsyncAppender asyncAppender = asyncAppender(rollingFileAppender, context); appender = asyncAppender; } return appender; }); siftingAppender.start(); return siftingAppender; } private static AsyncAppender asyncAppender(Appender appender, LoggerContext context) { AsyncAppender asyncAppender = new AsyncAppender(); asyncAppender.setContext(context); asyncAppender.setName("MY_ASYNC_BACKUP_APPENDER"); asyncAppender.setQueueSize(512); asyncAppender.addAppender(appender); asyncAppender.start(); return asyncAppender; } private static MDCBasedDiscriminator getMdcBasedDiscriminator(LoggerContext context) { MDCBasedDiscriminator discriminator = new MDCBasedDiscriminator(); discriminator.setContext(context); discriminator.setKey(DISCRIMINATOR_KEY); discriminator.setDefaultValue(DISCRIMINATOR_DEFAULT_VALUE); discriminator.start(); return discriminator; } private static RollingFileAppender rollingFileAppender(String name, String fileNamePattern, LoggerContext context) { RollingFileAppender rollingFileAppender = new RollingFileAppender(); rollingFileAppender.setContext(context); rollingFileAppender.setRollingPolicy(timeBasedRollingPolicy(rollingFileAppender, fileNamePattern, context)); rollingFileAppender.setEncoder(messageOnlyEncoder(context)); rollingFileAppender.setName(name); rollingFileAppender.start(); return rollingFileAppender; } private static RollingPolicy timeBasedRollingPolicy(RollingFileAppender rollingFileAppender, String fileNamePattern, LoggerContext context) { final TimeBasedRollingPolicy timeBasedRollingPolicy = new TimeBasedRollingPolicy(); timeBasedRollingPolicy.setContext(context); timeBasedRollingPolicy.setFileNamePattern(fileNamePattern); timeBasedRollingPolicy.setParent(rollingFileAppender); timeBasedRollingPolicy.start(); return timeBasedRollingPolicy; } private static Encoder messageOnlyEncoder(LoggerContext context) { final PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder(); patternLayoutEncoder.setPattern("%mdc %msg%n"); patternLayoutEncoder.setCharset(Charset.forName("utf-8")); patternLayoutEncoder.setContext(context); patternLayoutEncoder.start(); return patternLayoutEncoder; } private static Encoder consoleOnlyEncoder(LoggerContext context) { final PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder(); patternLayoutEncoder.setPattern("%-4relative [%thread] %-5level %logger{35} - %msg %n"); patternLayoutEncoder.setCharset(Charset.forName("utf-8")); patternLayoutEncoder.setContext(context); patternLayoutEncoder.start(); return patternLayoutEncoder; } private static void addMDCInterceptorTurboFilter(LoggerContext context) { String regex = DISCRIMINATOR_KEY.concat("={},").concat(MESSAGE_KEY).concat("={}"); // "filename={},msg={}" TurboFilter mdcInterceptorFilter = new TurboFilter() { @Override public FilterReply decide(Marker marker, ch.qos.logback.classic.Logger logger, Level level, String rawMessage, Object[] params, Throwable t) { if (params != null && regex.equals(rawMessage)) { MDC.put(DISCRIMINATOR_KEY, (String) params[0]); logger.log(marker, this.getClass().getName(), Level.toLocationAwareLoggerInteger(level), (String) params[1], null, null); MDC.remove(DISCRIMINATOR_KEY); return FilterReply.DENY; } return FilterReply.NEUTRAL; } }; context.addTurboFilter(mdcInterceptorFilter); mdcInterceptorFilter.setName("MY_MDC_INTERCEPTOR_FILTER"); mdcInterceptorFilter.start(); } }
participants (1)
-
Joaquim Jose