Log4J Appender to create per-request logs
[java-idp.git] / src / edu / internet2 / middleware / commons / log4j / SimpleAppenderContextImpl.java
1 /*
2  * SimpleAppenderContext.java
3  * 
4  * A TheadLocalAppenderContext implementation class serves as the 
5  * meeting point between a particular instance of ThreadLocalAppender
6  * in a Log4J configuration and a particular thread pool request 
7  * dispatcher (such as a Tomcat application context). 
8  * 
9  * In this simple case, the ThreadLocal reference is held in a 
10  * static variable in this class, and it points to a StringWriter.
11  * 
12  * The ThreadLocalAppender is configured (or defaults since this
13  * is the default value) through the LocalContext property. Set 
14  * that property in the Log4J configuration file with the name of 
15  * a class that implements ThreadLocalAppenderContext. 
16  * 
17  * The request container is also configured with or default do the
18  * name of this class. It calls startRequest() when a new request
19  * arrives and endRequest() before returning from request processing.
20  * An example is the RequestLoggingFilter that makes these calls just
21  * before and just after chaining a Servlet GET or POST request on to
22  * the next Filter/Servlet in the processing chain.
23  * 
24  * What ties things together is the name of this class, and the 
25  * fact that the ThreadLocal variable is static in this class. So
26  * if you want two differently configured ThreadLocalAppenders to share
27  * the same JVM ClassLoader, then you have to create two different classes
28  * with two different names and configure at least one new name as the
29  * Log4J Appender property or the Filter initialization parameter.
30  * 
31  * Note: The ThreadLocalAppender creates one object of this class.
32  * The RequestLoggingFilter creates a separate object. The two
33  * objects share only the static variable. Do not make the 
34  * mistake of assuming that the Filter and log share the same
35  * object.
36  * 
37  * --------------------
38  * Copyright 2002, 2004 
39  * Yale University
40  * University Corporation for Advanced Internet Development, Inc. 
41  * All rights reserved
42  * Your permission to use this code is governed by "The Shibboleth License".
43  * A copy may be found at http://shibboleth.internet2.edu/license.html
44  */
45 package edu.internet2.middleware.commons.log4j;
46
47 import java.io.StringWriter;
48 import java.io.Writer;
49
50
51 /**
52  * @author Howard Gilbert
53  */
54 public class SimpleAppenderContextImpl 
55         implements ThreadLocalAppenderContext {
56     
57     private static ThreadLocal localWriterReference = new ThreadLocal();
58
59     /**
60      * @return Null or the Writer for the current thread.
61      */
62     public Writer getLocalWriter() {
63         return (Writer) localWriterReference.get();
64     }
65
66     /**
67      * Called to signal the start of Request processing for this thread.
68      */
69     public void startRequest() {
70         localWriterReference.set(new StringWriter());
71     }
72
73     /**
74      * Called to signal the end of Request processing. Return log data
75      * and null out the Writer to stop collecting data.
76      * 
77      * @return A wrapped String containing the log data.
78      */
79     public WrappedLog endRequest() {
80         StringWriter stringWriter =(StringWriter) localWriterReference.get();
81         if (stringWriter==null)
82             return null;
83         String logdata = stringWriter.toString();
84         localWriterReference.set(null);
85         return new WrappedStringLog(logdata);
86     }
87     
88     
89     /**
90      * The log Writer could be a file or WebDav network store. So
91      * the log data could be a String, or a file name, or a URL.
92      * This class handles the simple String case.
93      * @author Howard Gilbert
94      */
95     static class WrappedStringLog implements WrappedLog {
96         
97         String logdata;
98         
99         WrappedStringLog(String logdata) {
100             this.logdata=logdata;
101             
102         }
103         
104         public String getLogData() {
105             return logdata;
106         }
107         
108     }
109
110 }