[logback-user] Implementing MDC with ServerSocketReceiver
Joaquim Jose
joaquimjosedasilva at gmail.com
Tue Jul 30 17:47:16 CEST 2019
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();
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.qos.ch/pipermail/logback-user/attachments/20190730/dd5d8376/attachment-0001.html>
More information about the logback-user
mailing list