1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.access.jetty;
15
16 import java.io.File;
17 import java.net.URL;
18 import java.util.EventListener;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import ch.qos.logback.core.status.InfoStatus;
24 import ch.qos.logback.core.util.FileUtil;
25 import ch.qos.logback.core.util.StatusPrinter;
26
27 import org.eclipse.jetty.server.Request;
28 import org.eclipse.jetty.server.RequestLog;
29 import org.eclipse.jetty.server.Response;
30
31 import ch.qos.logback.access.joran.JoranConfigurator;
32 import ch.qos.logback.access.spi.AccessEvent;
33 import ch.qos.logback.access.spi.IAccessEvent;
34 import ch.qos.logback.core.Appender;
35 import ch.qos.logback.core.ContextBase;
36 import ch.qos.logback.core.CoreConstants;
37 import ch.qos.logback.core.boolex.EventEvaluator;
38 import ch.qos.logback.core.filter.Filter;
39 import ch.qos.logback.core.joran.spi.JoranException;
40 import ch.qos.logback.core.spi.AppenderAttachable;
41 import ch.qos.logback.core.spi.AppenderAttachableImpl;
42 import ch.qos.logback.core.spi.FilterAttachable;
43 import ch.qos.logback.core.spi.FilterAttachableImpl;
44 import ch.qos.logback.core.spi.FilterReply;
45 import ch.qos.logback.core.status.ErrorStatus;
46 import ch.qos.logback.core.util.OptionHelper;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public class RequestLogImpl extends ContextBase implements org.eclipse.jetty.util.component.LifeCycle, RequestLog,
127 AppenderAttachable<IAccessEvent>, FilterAttachable<IAccessEvent> {
128
129 public final static String DEFAULT_CONFIG_FILE = "etc" + File.separatorChar + "logback-access.xml";
130
131 AppenderAttachableImpl<IAccessEvent> aai = new AppenderAttachableImpl<IAccessEvent>();
132 FilterAttachableImpl<IAccessEvent> fai = new FilterAttachableImpl<IAccessEvent>();
133 String fileName;
134 String resource;
135 boolean started = false;
136 boolean quiet = false;
137
138 public RequestLogImpl() {
139 putObject(CoreConstants.EVALUATOR_MAP, new HashMap<String, EventEvaluator<?>>());
140 }
141
142 @Override
143 public void log(Request jettyRequest, Response jettyResponse) {
144 JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest, jettyResponse);
145 IAccessEvent accessEvent = new AccessEvent(this, jettyRequest, jettyResponse, adapter);
146 if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
147 return;
148 }
149 aai.appendLoopOnAppenders(accessEvent);
150 }
151
152 private void addInfo(String msg) {
153 getStatusManager().add(new InfoStatus(msg, this));
154 }
155
156 private void addError(String msg) {
157 getStatusManager().add(new ErrorStatus(msg, this));
158 }
159
160 @Override
161 public void start() {
162 configure();
163 if (!isQuiet()) {
164 StatusPrinter.print(getStatusManager());
165 }
166 started = true;
167 }
168
169 protected void configure() {
170 URL configURL = getConfigurationFileURL();
171 if (configURL != null) {
172 runJoranOnFile(configURL);
173 } else {
174 addError("Could not find configuration file for logback-access");
175 }
176 }
177
178 protected URL getConfigurationFileURL() {
179 if (fileName != null) {
180 addInfo("Will use configuration file [" + fileName + "]");
181 File file = new File(fileName);
182 if (!file.exists())
183 return null;
184 return FileUtil.fileToURL(file);
185 }
186 if (resource != null) {
187 addInfo("Will use configuration resource [" + resource + "]");
188 return this.getClass().getResource(resource);
189 }
190
191 String jettyHomeProperty = OptionHelper.getSystemProperty("jetty.home");
192 String defaultConfigFile = DEFAULT_CONFIG_FILE;
193 if (!OptionHelper.isNullOrEmpty(jettyHomeProperty)) {
194 defaultConfigFile = jettyHomeProperty + File.separatorChar + DEFAULT_CONFIG_FILE;
195 } else {
196 addInfo("[jetty.home] system property not set.");
197 }
198 File file = new File(defaultConfigFile);
199 addInfo("Assuming default configuration file [" + defaultConfigFile + "]");
200 if (!file.exists())
201 return null;
202 return FileUtil.fileToURL(file);
203 }
204
205 private void runJoranOnFile(URL configURL) {
206 try {
207 JoranConfigurator jc = new JoranConfigurator();
208 jc.setContext(this);
209 jc.doConfigure(configURL);
210 if (getName() == null) {
211 setName("LogbackRequestLog");
212 }
213 } catch (JoranException e) {
214
215 }
216 }
217
218 @Override
219 public void stop() {
220 aai.detachAndStopAllAppenders();
221 started = false;
222 }
223
224 @Override
225 public boolean isRunning() {
226 return started;
227 }
228
229 public void setFileName(String fileName) {
230 this.fileName = fileName;
231 }
232
233 public void setResource(String resource) {
234 this.resource = resource;
235 }
236
237 @Override
238 public boolean isStarted() {
239 return started;
240 }
241
242 @Override
243 public boolean isStarting() {
244 return false;
245 }
246
247 @Override
248 public boolean isStopping() {
249 return false;
250 }
251
252 @Override
253 public boolean isStopped() {
254 return !started;
255 }
256
257 @Override
258 public boolean isFailed() {
259 return false;
260 }
261
262 public boolean isQuiet() {
263 return quiet;
264 }
265
266 public void setQuiet(boolean quiet) {
267 this.quiet = quiet;
268 }
269
270 @Override
271 public void addAppender(Appender<IAccessEvent> newAppender) {
272 aai.addAppender(newAppender);
273 }
274
275 @Override
276 public Iterator<Appender<IAccessEvent>> iteratorForAppenders() {
277 return aai.iteratorForAppenders();
278 }
279
280 @Override
281 public Appender<IAccessEvent> getAppender(String name) {
282 return aai.getAppender(name);
283 }
284
285 @Override
286 public boolean isAttached(Appender<IAccessEvent> appender) {
287 return aai.isAttached(appender);
288 }
289
290 @Override
291 public void detachAndStopAllAppenders() {
292 aai.detachAndStopAllAppenders();
293 }
294
295 @Override
296 public boolean detachAppender(Appender<IAccessEvent> appender) {
297 return aai.detachAppender(appender);
298 }
299
300 @Override
301 public boolean detachAppender(String name) {
302 return aai.detachAppender(name);
303 }
304
305 @Override
306 public void addFilter(Filter<IAccessEvent> newFilter) {
307 fai.addFilter(newFilter);
308 }
309
310 @Override
311 public void clearAllFilters() {
312 fai.clearAllFilters();
313 }
314
315 @Override
316 public List<Filter<IAccessEvent>> getCopyOfAttachedFiltersList() {
317 return fai.getCopyOfAttachedFiltersList();
318 }
319
320 @Override
321 public FilterReply getFilterChainDecision(IAccessEvent event) {
322 return fai.getFilterChainDecision(event);
323 }
324
325 @Override
326 public boolean addEventListener(EventListener listener) {
327
328 return false;
329 }
330
331 @Override
332 public boolean removeEventListener(EventListener listener) {
333
334 return false;
335 }
336
337 }