I am tying to create a PatternLayout object in Java code that will have its values substituted from the ThreadContext, using the %X
(and %d) placeholder.
private PatternLayout patternLayout = PatternLayout.newBuilder()
.withPattern("op1=%X{op1}|op2=%X{op2}|timestamp=%d{HH:mm:ss.SSS}")
.build();
I have also implemented the Log4J Message
interface:
private final PatternLayout pattern;
MyLoggingMessage(final PatternLayout pattern) {
this.pattern = pattern;
}
@Override
public String getFormattedMessage() {
// I have also tried return pattern.getContentFormat();
return pattern.toString();
}
However, when this is recorded in Graylog, the values have not been substituted out, and remains op1=%X{op1}|op2=%X{op2}|timestamp=%d{HH:mm:ss.SSS}
. However, if I use an XML implementation of the same pattern in my appender,...
<PatternLayout pattern="op1=%X{op1}|op2=%X{op2}|timestamp=%d{HH:mm:ss.SSS}" />
it all gets substituted out. How can I get log4j to evaluate the pattern in Java? From what I can see, both methods just set the pattern
field.
So this worked for me:
private final StringMap params;
MyLoggingMessage(final PatternLayout pattern) {
this.pattern = pattern;
this.params = (StringMap) ThreadContext.getContext();
}
@Override
public String getFormattedMessage() {
LogEvent logEvent = Log4jLogEvent.newBuilder()
.setContextData(params)
.build();
return pattern.toSerializable(logEvent);
}