Modifing MDCPropertyMap of LoggingEvents

I have a layout which is generating JSON from logging events and MDC Context. MDC is great and I want to add parameters to MDC Context conditionally. For example, I would like add request information as JSON into MDC conditionally on Error Level log entries. I am not familiar with Logback internals but gave a try with Logback Filter implementation. I have used: public FilterReply decide(ILoggingEvent event) { // simplified for demo // conditionally I am putting some attributes here Map<String, String> mdcPropertyMap = event.getMDCPropertyMap(); if (event.getLevel().isGreaterOrEqual(Level.ERROR)) { mdcPropertyMap.put("demo", "demo"); } return FilterReply.ACCEPT; } I am expecting mdcPropertyMap to be cleared for each event but it does not. LoggingEvent has a internal CACHED_NULL_MAP map and its modified per touch. private static final Map<String, String> CACHED_NULL_MAP = new HashMap<String, String>(); I could not be sure but it seems a little bid buggy to me. Can someone verify this behaviour? For those who are interested why I am not using MDC.put in a Servlet Filter implementation because I am conditionally adding some attributes. Serialising HttpRequest into JSON is not cheap task but having Http Request information is giving great insights about error. Using Filter is the only way I found to add conditionally attributes so far. What I would like to use is: public FilterReply decide(ILoggingEvent event) { if (event.getLevel().isGreaterOrEqual(Level.WARN)) { MDC.put("demo", "demo"); } return FilterReply.ACCEPT; }

MDC is a thread-wide structure. At present time, it cannot be set per logging event. Any changes you make to the mdcPropertyMap (retrieved by calling event.getMDCPropertyMap()) will be visible to all future events generated in the same thread. On 3/9/2015 21:03, Cemo wrote:
I have a layout which is generating JSON from logging events and MDC Context. MDC is great and I want to add parameters to MDC Context conditionally. For example, I would like add request information as JSON into MDC conditionally on Error Level log entries. I am not familiar with Logback internals but gave a try with Logback Filter implementation. I have used:
public FilterReply decide(ILoggingEvent event) {
// simplifiedfor demo // conditionally I am putting some attributes here Map<String,String> mdcPropertyMap = event.getMDCPropertyMap(); if (event.getLevel().isGreaterOrEqual(Level.ERROR)) { mdcPropertyMap.put("demo","demo"); } return FilterReply.ACCEPT; }
I am expecting mdcPropertyMap to be cleared for each event but it does not. LoggingEvent has a internal CACHED_NULL_MAP map and its modified per touch.
private static final Map<String,String> CACHED_NULL_MAP =new HashMap<String,String>();
I could not be sure but it seems a little bid buggy to me. Can someone verify this behaviour?
For those who are interested why I am not using MDC.put in a Servlet Filter implementation because I am conditionally adding some attributes. Serialising HttpRequest into JSON is not cheap task but having Http Request information is giving great insights about error. Using Filter is the only way I found to add conditionally attributes so far. What I would like to use is:
public FilterReply decide(ILoggingEvent event) { if (event.getLevel().isGreaterOrEqual(Level.WARN)) { MDC.put("demo","demo"); } return FilterReply.ACCEPT; }
_______________________________________________ Logback-user mailing list Logback-user@qos.ch http://mailman.qos.ch/mailman/listinfo/logback-user

On 9 March 2015 at 22:37, Ceki Gülcü <ceki@qos.ch> wrote:
MDC is a thread-wide structure. At present time, it cannot be set per logging event. Any changes you make to the mdcPropertyMap (retrieved by calling event.getMDCPropertyMap()) will be visible to all future events generated in the same thread.
Please forgive my ignorance if I say something wrong. ch.qos.logback.classic.spi.LoggingEvent#getMDCPropertyMap returns: 1. If MDCAdapter has an already property map, It returns this map 2. If MDCAdapter has not a map, it returns a static map(CACHED_NULL_MAP) which is shared among other threads as well. If I set it mistakenly, It will be used by other threads. This parts seems a little bid problematic. I just want to share same map reference between event and MDCAdapter which will let me:
public FilterReply decide(ILoggingEvent event) { if (event.getLevel().isGreaterOrEqual(Level.WARN)) { MDC.put("demo","demo"); } return FilterReply.ACCEPT; }
Also I am expecting to be cleared in case a MDC.remove call. What do you think?

Cemo, There is logic in LogbackMDCAdaptor, which is called by MDC.put() which does duplicateAndInsertNewMap(), so that when you add a new key it is not shared with all threads. David -- View this message in context: http://logback.10977.n7.nabble.com/Modifing-MDCPropertyMap-of-LoggingEvents-... Sent from the Users mailing list archive at Nabble.com.
participants (3)
-
Ceki Gülcü
-
Cemo
-
diroussel