View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.common.util;
25  
26  import net.jcip.annotations.Immutable;
27  import org.slf4j.MDC;
28  
29  /**
30   * Provides a "mapped diagnostic context" (MDC) for use in capturing extra context information to be included in logs of
31   * multithreaded applications. Not all logging implementations support MDC, although a few do (including <a
32   * href="http://logging.apache.org/log4j/1.3/index.html">Log4J</a> and <a href="http://logback.qos.ch/">Logback</a>). Note that if
33   * the logging implementation does not support MDC, this information is ignored.
34   * <p>
35   * It can be difficult to understand what is going on within a multithreaded application. When multiple threads are working
36   * simultaneously, their log messages are mixed together. Thus, it's difficult to follow the log messages of a single thread. Log
37   * contexts provide a way to associate additional information with "the current context", and log messages can include that
38   * additional information in the messages.
39   * </p>
40   * <p>
41   * Log contexts are managed for you, and so using them is very straightforward. Typically, log contexts are used within
42   * well-defined activities, and additional information is recorded in the context at the beginning of the activity and cleared at
43   * the end of the activity.
44   * </p>
45   * <p>
46   * The following example shows how to set and clear this additional information:
47   * 
48   * <pre>
49   *   LogContext.set(&quot;username&quot;,&quot;jsmith&quot;);
50   *   LogContext.set(&quot;operation&quot;,&quot;process&quot;);
51   *   ...
52   *   // do work here
53   *   ...
54   *   LogContext.clear();
55   * </pre>
56   * 
57   * Note that the actually values would not be hardcoded but would be retrieved from other objects available at the time.
58   * </p>
59   * <p>
60   * If the logging system doesn't support MDC, then the additional information provided via LogContext is ignored. However, if the
61   * logging system is able to use MDC and it is set up with patterns that reference the keys, then those log messages will contain
62   * the values for those keys.
63   * </p>
64   */
65  @Immutable
66  public class LogContext {
67  
68      /**
69       * Put a context value (the <code>val</code> parameter) as identified with the <code>key</code> parameter into the current
70       * thread's context map. The <code>key</code> parameter cannot be null. The code>val</code> parameter can be null only if the
71       * underlying implementation supports it.
72       * <p>
73       * This method delegates all work to the MDC of the underlying logging system.
74       * 
75       * @param key the key
76       * @param value the value
77       * @throws IllegalArgumentException in case the "key" parameter is null
78       */
79      public static void set( String key,
80                              String value ) {
81          MDC.put(key, value);
82      }
83  
84      /**
85       * Get the context identified by the <code>key</code> parameter. The <code>key</code> parameter cannot be null.
86       * <p>
87       * This method delegates all work to the MDC of the underlying logging system.
88       * 
89       * @param key the key
90       * @return the string value identified by the <code>key</code> parameter.
91       * @throws IllegalArgumentException in case the "key" parameter is null
92       */
93      public static String get( String key ) {
94          return MDC.get(key);
95      }
96  
97      /**
98       * Remove the the context identified by the <code>key</code> parameter using the underlying system's MDC implementation. The
99       * <code>key</code> parameter cannot be null. This method does nothing if there is no previous value associated with
100      * <code>key</code>.
101      * 
102      * @param key the key
103      * @throws IllegalArgumentException in case the "key" parameter is null
104      */
105     public static void remove( String key ) {
106         MDC.remove(key);
107     }
108 
109     /**
110      * Clear all entries in the MDC of the underlying implementation.
111      */
112     public static void clear() {
113         MDC.clear();
114     }
115 
116 }