1 package ch.qos.logback.access.tomcat;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.servlet.ServletContext;
11 import javax.servlet.ServletException;
12
13 import org.apache.catalina.Lifecycle;
14 import org.apache.catalina.LifecycleListener;
15 import org.apache.catalina.connector.Request;
16 import org.apache.catalina.connector.Response;
17 import org.apache.catalina.valves.ValveBase;
18
19 import ch.qos.logback.access.AccessConstants;
20 import ch.qos.logback.access.joran.JoranConfigurator;
21 import ch.qos.logback.access.spi.AccessEvent;
22 import ch.qos.logback.core.Appender;
23 import ch.qos.logback.core.BasicStatusManager;
24 import ch.qos.logback.core.Context;
25 import ch.qos.logback.core.CoreConstants;
26 import ch.qos.logback.core.filter.Filter;
27 import ch.qos.logback.core.joran.spi.JoranException;
28 import ch.qos.logback.core.spi.AppenderAttachable;
29 import ch.qos.logback.core.spi.AppenderAttachableImpl;
30 import ch.qos.logback.core.spi.FilterAttachable;
31 import ch.qos.logback.core.spi.FilterAttachableImpl;
32 import ch.qos.logback.core.spi.FilterReply;
33 import ch.qos.logback.core.status.InfoStatus;
34 import ch.qos.logback.core.status.StatusManager;
35 import ch.qos.logback.core.status.WarnStatus;
36 import ch.qos.logback.core.util.OptionHelper;
37 import ch.qos.logback.core.util.StatusPrinter;
38
39
40
41
42
43
44
45
46
47
48
49
50 public class LogbackValve extends ValveBase implements Lifecycle, Context,
51 AppenderAttachable<AccessEvent>, FilterAttachable<AccessEvent> {
52
53 public final static String DEFAULT_CONFIG_FILE = "conf" + File.separatorChar
54 + "logback-access.xml";
55
56
57 private String name;
58 StatusManager sm = new BasicStatusManager();
59
60
61
62 Map<String, String> propertyMap = new HashMap<String, String>();
63 Map<String, Object> objectMap = new HashMap<String, Object>();
64 private FilterAttachableImpl<AccessEvent> fai = new FilterAttachableImpl<AccessEvent>();
65
66 AppenderAttachableImpl<AccessEvent> aai = new AppenderAttachableImpl<AccessEvent>();
67 String filename;
68 boolean quiet;
69 boolean started;
70 boolean alreadySetLogbackStatusManager = false;
71
72 public LogbackValve() {
73 putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
74 }
75
76 public void start() {
77 if (filename == null) {
78 String tomcatHomeProperty = OptionHelper
79 .getSystemProperty("catalina.home");
80
81 filename = tomcatHomeProperty + File.separatorChar + DEFAULT_CONFIG_FILE;
82 getStatusManager().add(
83 new InfoStatus("filename property not set. Assuming [" + filename
84 + "]", this));
85 }
86 File configFile = new File(filename);
87 if (configFile.exists()) {
88 try {
89 JoranConfigurator jc = new JoranConfigurator();
90 jc.setContext(this);
91 jc.doConfigure(filename);
92 } catch (JoranException e) {
93
94 e.printStackTrace();
95 }
96 } else {
97 getStatusManager().add(
98 new WarnStatus("[" + filename + "] does not exist", this));
99 }
100
101 if (!quiet) {
102 StatusPrinter.print(getStatusManager());
103 }
104
105 started = true;
106 }
107
108 public String getFilename() {
109 return filename;
110 }
111
112 public void setFilename(String filename) {
113 this.filename = filename;
114 }
115
116 public boolean isQuiet() {
117 return quiet;
118 }
119
120 public void setQuiet(boolean quiet) {
121 this.quiet = quiet;
122 }
123
124 public void invoke(Request request, Response response) throws IOException,
125 ServletException {
126
127 try {
128
129 if (!alreadySetLogbackStatusManager) {
130 alreadySetLogbackStatusManager = true;
131 org.apache.catalina.Context tomcatContext = request.getContext();
132 if (tomcatContext != null) {
133 ServletContext sc = tomcatContext.getServletContext();
134 if (sc != null) {
135 sc.setAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY,
136 getStatusManager());
137 }
138 }
139 }
140
141 getNext().invoke(request, response);
142
143 TomcatServerAdapter adapter = new TomcatServerAdapter(request, response);
144 AccessEvent accessEvent = new AccessEvent(request, response, adapter);
145
146 if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
147 return;
148 }
149
150
151 aai.appendLoopOnAppenders(accessEvent);
152 } finally {
153 request
154 .removeAttribute(AccessConstants.LOGBACK_STATUS_MANAGER_KEY);
155 }
156 }
157
158 public void stop() {
159 started = false;
160 }
161
162 public void addAppender(Appender<AccessEvent> newAppender) {
163 aai.addAppender(newAppender);
164 }
165
166 public Iterator<Appender<AccessEvent>> iteratorForAppenders() {
167 return aai.iteratorForAppenders();
168 }
169
170 public Appender<AccessEvent> getAppender(String name) {
171 return aai.getAppender(name);
172 }
173
174 public boolean isAttached(Appender appender) {
175 return aai.isAttached(appender);
176 }
177
178 public void detachAndStopAllAppenders() {
179 aai.detachAndStopAllAppenders();
180
181 }
182
183 public boolean detachAppender(Appender appender) {
184 return aai.detachAppender(appender);
185 }
186
187 public boolean detachAppender(String name) {
188 return aai.detachAppender(name);
189 }
190
191 public String getInfo() {
192 return "Logback's implementation of ValveBase";
193 }
194
195
196 public StatusManager getStatusManager() {
197 return sm;
198 }
199
200 public Map<String, String> getPropertyMap() {
201 return propertyMap;
202 }
203
204 public void putProperty(String key, String val) {
205 this.propertyMap.put(key, val);
206 }
207
208 public String getProperty(String key) {
209 return (String) this.propertyMap.get(key);
210 }
211
212 public Object getObject(String key) {
213 return objectMap.get(key);
214 }
215
216 public void putObject(String key, Object value) {
217 objectMap.put(key, value);
218 }
219
220 public void addFilter(Filter<AccessEvent> newFilter) {
221 fai.addFilter(newFilter);
222 }
223
224 public Filter getFirstFilter() {
225 return fai.getFirstFilter();
226 }
227
228 public void clearAllFilters() {
229 fai.clearAllFilters();
230 }
231
232 public List<Filter<AccessEvent>> getCopyOfAttachedFiltersList() {
233 return fai.getCopyOfAttachedFiltersList();
234 }
235
236 public FilterReply getFilterChainDecision(AccessEvent event) {
237 return fai.getFilterChainDecision(event);
238 }
239
240 public String getName() {
241 return name;
242 }
243
244 public void setName(String name) {
245 if (this.name != null) {
246 throw new IllegalStateException(
247 "LogbackValve has been already given a name");
248 }
249 this.name = name;
250 }
251
252
253
254 public void addLifecycleListener(LifecycleListener arg0) {
255
256 }
257
258 public LifecycleListener[] findLifecycleListeners() {
259 return new LifecycleListener[0];
260 }
261
262 public void removeLifecycleListener(LifecycleListener arg0) {
263
264 }
265
266 }