0

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.

MeanwhileInHell
  • 6,780
  • 17
  • 57
  • 106

1 Answers1

0

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);
}
MeanwhileInHell
  • 6,780
  • 17
  • 57
  • 106