Log4J Appender to create per-request logs
[java-idp.git] / src / edu / internet2 / middleware / commons / log4j / ThreadLocalAppenderContext.java
1 /*
2  * ThreadLocalAppenderContext.java
3  * 
4  * An interface describing the services provided by the "helper class"
5  * that feeds the ThreadLocal Writer to the Log4J ThreadLocalAppender.
6  * It also exposes startRequest() and endRequest() methods to anyone
7  * managing the gate through which the threadpool request manager 
8  * (say Tomcat) dispatches requests (GET or PUT HTTP requests) to an
9  * application (a Tomcat context) where you want a separate log file
10  * or buffer for every individual request processed.
11  * 
12  * The default implementation of this interface is provided by the
13  * SimpleAppenderContextImpl class.
14  * 
15  * --------------------
16  * Copyright 2002, 2004 
17  * Yale University
18  * University Corporation for Advanced Internet Development, Inc. 
19  * All rights reserved
20  * Your permission to use this code is governed by "The Shibboleth License".
21  * A copy may be found at http://shibboleth.internet2.edu/license.html
22  */
23 package edu.internet2.middleware.commons.log4j;
24
25 import java.io.Writer;
26
27
28 /**
29  * Provide ThreadLocalAppender with a Writer into which to put the log data.
30  * 
31  * Provide the Request managment layer (Servlet, Servlet Filter, RMI, ...)
32  * methods to signal the start and end of a request. After the startRequest
33  * the implementing object should have generated a bucket to hold trace and
34  * should 
35  * 
36  * <p>The purpose of ThreadLocal logging is to log activity local to a request
37  * in an application server (say a Tomcat Web request). The problem is that
38  * such threads never belong to the code that is doing the logging, they 
39  * belong to the external container. So what you have to do is load the
40  * ThreadLocal reference on entry to the Servlet/EJB/whatever and then
41  * clear the pointer before returning to the container. You can't do that
42  * if the ThreadLocal variable belongs to the Appender, because the 
43  * Appender should, if properly abstracted, only know about log4j. So you
44  * have to feed the appender an object (or the name of a class that can
45  * create an object) that knows where the ThreadLocal pointer is for this
46  * application and can return it. That is what this interface does.</p>
47  * 
48  * <p>You must create a class, familiar with the environment, that implements
49  * the class and passes back either null or a ThreadLocal Writer.
50  * The name of this class must be the LocalContext parameter of the
51  * ThreadLocalAppender configuration. The class must be in the classpath when
52  * the Appender is configured.
53  * </p>
54  * 
55  * @author Howard Gilbert
56  */
57 public interface ThreadLocalAppenderContext {
58     
59     /**
60      * Give the Appender a Writer into which to write data.
61      * @return Writer
62      */
63     Writer getLocalWriter();
64     
65     /**
66      * Called by the request manager (say the Servlet Filter) to 
67      * signal the start of a new request. The implementor must 
68      * allocate a new Writer to accept data.
69      */
70     void startRequest();
71     
72     /**
73      * Called by the request manager to signal the end of a request.
74      * Returns an IOU that will deliver the log data on request
75      * if it is needed (typically when a Servlet wants to display
76      * log data to a remote user.)
77      * @return WrappedLog object to access log data.
78      */
79     WrappedLog endRequest();
80     
81 }