Question
US
Last activity: 21 Feb 2017 2:57 EST
How to read MDC fields using custom appender
All,
We are trying to implement a custom appender to send our log messages to a log-aggregation tool (ie, Splunk). In order to do this, we had to extend the pega log4j classes and load our custom logging classes into pega.
This part works perfectly, and we are able to send our log messages and associated stack traces to our log aggregator. Our hangup right now is being able to read the values in the MDC hash map that store useful info thats not part of the raw log message (pegathread,userid, requestorid, etc..)
We are trying to read these values by calling the MDC.get() method, however it always returns null values. Is there a different method/function we should be calling to read these MDC values?
Thanks!
-Jon
***Updated by Moderator: Marissa to add SR Details***
-
Like (0)
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Accepted Solution
Pegasystems Inc.
US
SR Response below,
As it’s a AsyncAppender, the Appender append() is called on a separate dispatcher thread. Hence, MDC.get() returns null. What AsyncAppender does is stores a copy of the MDC in the LoggingEvent when AsyncAppender.doAppend() is called on the original thread itself
So, you can fetch value of any MDC key via event.getMDC(key)
Object val = event.getMDC("pegathread");
Pegasystems Inc.
US
Jon,
How did you put pegathread, etc to MDC map? Have you tried to put in a hard-coded value and call MDC.get("name") to see if the original hard-coded value can be read?
US
If we put our own value using mdc.get() we can successfully read the custom value from that particular MDC field.
Pegasystems Inc.
US
In PEGA we use com.pega.pegarules.priv.LogContext to wrap MDC.
That allows you to put things in the context:
LogContext.put(gREQUESTOR_ID, mRequestorId);
Which translates to
In PEGA we use com.pega.pegarules.priv.LogContext to wrap MDC.
That allows you to put things in the context:
LogContext.put(gREQUESTOR_ID, mRequestorId);
Which translates to
MDC.put(gREQUESTOR_ID, mRequestorId);
And then reference them in the appender:
%X{RequestorId}
The issue you may be having in your custom appender is that we use a repackaged log4j.
com.pega.apache.log4j.MDC
I wonder if you use:
import com.pega.apache.log4j
In your imports if you could just reference %X{RequestorId} in the pattern.
US
Thanks. I've forwarded this on to a collegue who is working with me on this. They will post an update shortly.
-Jon
Accenture Federal Services
US
We have imported com.pega.apache.log4j and com.pega.pegarules.priv.LogContext into our custom appender.
We have tried retrieving the MDC fields with both MDC.get and LogContext.get but both didn’t seem to work. What I have noticed is that pega picks up the new value if we change the value for the mdc field but we can’t see the new value if it’s changed in pega.
So for example if I do LogContext.put("pegathread", "TestingAppender"), I can see the value being changed in the logs to TestingAppender but I can’t get the new value when the value of pegathread is changed to STANDARD.
-Abdul
US
Has there been any update on this?
Thanks,
Jon
Pegasystems Inc.
US
Hi Jonathan,
Apologies for any delay on this. I see that your SR is actively being worked on. If the Community has any other input towards this to help Jonathan, please do so by leaving a new reply!
Thanks,
Marissa | Community Moderator | Pegasystems Inc.
Accepted Solution
Pegasystems Inc.
US
SR Response below,
As it’s a AsyncAppender, the Appender append() is called on a separate dispatcher thread. Hence, MDC.get() returns null. What AsyncAppender does is stores a copy of the MDC in the LoggingEvent when AsyncAppender.doAppend() is called on the original thread itself
So, you can fetch value of any MDC key via event.getMDC(key)
Object val = event.getMDC("pegathread");
Pegasystems Inc.
IN
Hello!
On reviewing the corresponding SR, we see that it has been resolved. SA-33123 was created as a result of the investigation. Please reference that if you have the same question.
Thank you