logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ceki Gülcü <c...@qos.ch>
Subject RE: MDC in J2EE environment
Date Thu, 03 Apr 2003 16:09:20 GMT
At 09:58 AM 4/3/2003 -0600, you wrote:
>Actually just another thought occurred to me.  The MDC value is now a
>ContextCounter instance instead of the actual value I put there.  The
>default rendering is simply to call the Object's toString() correct?  So it
>would seem that I would also need to add a renderer or override toString in
>ContextCounter to call its context.toString()?

You are right.

public class ContextCounter {
   int count = 0;
   Object context;

   public ContextCounter(Object c) { context = c; }

   public void setContext(Object c) { context = c; }
   public Object getContext() { return context; }

   public boolean isCountZero() { return (count == 0); }
   public void incCount() { count++; }
   public void decCount() { count--; }

   // We override toString so that Layouts print the correct information
   public String toString() { return context.toString(); }
}


>     |-----Original Message-----
>     |From: Ceki Gülcü [mailto:ceki@qos.ch]
>     |Sent: Thursday, April 03, 2003 9:30 AM
>     |To: Log4J Users List
>     |Subject: Re: MDC in J2EE environment
>     |
>     |
>     |Steven,
>     |
>     |Your question is quite intriguing.
>     |
>     |One solution would be to use some sort of counting. Thus,
>     |each time you set
>     |a key in the MDC you would increment the count of that key
>     |in the MDC by
>     |one. Each time you would "remove" the key you would
>     |decrement the count by
>     |one but not really remove (i.e. call MDC.remove). You
>     |would really remove
>     |only if the count reached zero (assuming the count started
>     |at 0). I think
>     |this provides for quite a solid solution.
>     |
>     |Let me give you an example:
>     |
>     |-- File XMDC.java ------------------------------------------
>     |import org.apache.log4j.MDC;
>     |
>     |public class XMDC {
>     |
>     |   static Object get(String key) {
>     |     return  MDC.get(key);
>     |   }
>     |
>     |   static void put(String key, Object o) {
>     |     Object value = MDC.get(key);
>     |
>     |     if(value == null) {
>     |       ContextCounter cc = new ContextCounter(value);
>     |       cc.incCount();
>     |       MDC.put(key, cc);
>     |     } else if(o instanceof ContextCounter) {
>     |       ContextCounter cc = (ContextCounter) value;
>     |       cc.incCount();
>     |       cc.setContext(o);
>     |     } else {
>     |       MDC.put(key, o);
>     |     }
>     |   }
>     |
>     |   static void remove(String key) {
>     |     Object o = MDC.get(key);
>     |
>     |     if(o == null) {
>     |       ; // nothing to do because there is nothing there
>     |     } else if(o instanceof ContextCounter) {
>     |       ContextCounter cc = (ContextCounter) o;
>     |       cc.decCount();
>     |       if(cc.isCountZero()) {
>     |         MDC.remove(key);
>     |       }
>     |     } else {
>     |       MDC.remove(key);
>     |     }
>     |   }
>     |}
>     |
>     |-- File  ContextCounter.java ---------------------------------
>     |public class ContextCounter {
>     |   int count = 0;
>     |   Object context;
>     |
>     |   public ContextCounter(Object c) { context = c; }
>     |
>     |   public void setContext(Object c) { context = c; }
>     |   public Object getContext() { return context; }
>     |
>     |   public boolean isCountZero() { return (count == 0); }
>     |   public void incCount() { count++; }
>     |   public void decCount() { count--; }
>     |}
>     |
>     |In your code you would use XMDC which would automatically
>     |track the
>     |reference count of the keys and values you entered into
>     |the MDC. Assuming
>     |each XMDC.put operation is matched by the corresponding
>     |XMDC.remove
>     |operation, you are guaranteed that "inner" put operations
>     |update the value
>     |of the key while inner remove operation are inoffensive,
>     |only the outer or
>     |topmost XMDC.remove will remove the key and its value from the MDC.
>     |
>     |Think about it and let us know if it fits your purposes.
>     |
>     |At 08:13 AM 4/3/2003 -0600, Ebersole, Steven wrote:
>     |>There is certain information which is thread contextual
>     |which I would like
>     |>to include into log4j's MDC to be available for logging.
>     |One of these, for
>     |>example, is the currently executing user.  My
>     |architecture is such that all
>     |>requests come through a layer of stateless session EJBs.
>     |Now these EJBs can
>     |>make calls into other session EJBs in order to fulfill
>     |their use-case:
>     |>
>     |>public class SessionBeanA
>     |>...
>     |>{
>     |>     ...
>     |>     public void executeUseCase()
>     |>     {
>     |>         ... // Do some work
>     |>         SessionBeanB sessionBeanB = ...; // Lookup SessionBeanB
>     |>         sessionBeanB.executeSomeRelatedUseCase();
>     |>         ... // Do some more work
>     |>     }
>     |>}
>     |>
>     |>public class SessionBeanB
>     |>...
>     |>{
>     |>     ...
>     |>     public void executeRelatedUseCase()
>     |>     {
>     |>         ... // Do something
>     |>     }
>     |>}
>     |>
>     |>The typical usage of MDC seems to be:
>     |>1) put vars into MDC
>     |>2) do your work
>     |>3) clean up MDC
>     |>
>     |>But if I apply this usage to the scenario above, when
>     |>SessionBeanB.executeRelatedUseCase() cleans up the MDC,
>     |the information
>     |>would no longer be contained in the MDC for LoggingEvents
>     |generated within
>     |>the "Do some more work" section of SessionBeanA.executeUseCase().
>     |>
>     |>I run weblogic 6.1, which unfortunately does not have
>     |support for "call
>     |>interceptors" to know when a user context has been bound
>     |to a thread.
>     |>Otherwise, I could simply setup MDC when a "session" is
>     |begun and clean up
>     |>the MDC when the session ends.  The only way around this
>     |I have been able to
>     |>think of is to just always call MDC.put( "USER",
>     |>mySessionContext.getCallerPrincipal().getName() ) at the
>     |beginning of each
>     |>and every session bean method.  But I would not ever be
>     |able to clean up the
>     |>MDC because of this nesting described above.
>     |>
>     |>Is this OK?  Or this there a better way to do this?
>     |>
>     |>
>     |>
>     |>Steve Ebersole
>     |>IT Integration Engineer
>     |>Vignette Corporation
>     |>Office: 512.741.4195
>     |>Mobile: 512.297.5438
>     |>
>     |>Visit http://www.vignette.com
>     |>
>     |>----------------------------------------------------------
>     |-----------
>     |>To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org
>     |>For additional commands, e-mail:
>     |log4j-user-help@jakarta.apache.org
>     |
>     |--
>     |Ceki
>     |
>     |
>     |-----------------------------------------------------------
>     |----------
>     |To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org
>     |For additional commands, e-mail: log4j-user-help@jakarta.apache.org
>     |
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: log4j-user-help@jakarta.apache.org

--
Ceki 


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-user-help@jakarta.apache.org


Mime
View raw message