1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty;
16
17 import java.io.IOException;
18 import java.io.OutputStream;
19 import java.io.OutputStreamWriter;
20 import java.io.Writer;
21 import java.util.Locale;
22 import java.util.TimeZone;
23
24 import javax.servlet.http.Cookie;
25
26 import org.mortbay.component.AbstractLifeCycle;
27 import org.mortbay.jetty.servlet.PathMap;
28 import org.mortbay.log.Log;
29 import org.mortbay.util.DateCache;
30 import org.mortbay.util.RolloverFileOutputStream;
31 import org.mortbay.util.StringUtil;
32 import org.mortbay.util.TypeUtil;
33
34
35
36
37
38
39
40
41
42
43
44
45 public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
46 {
47 private String _filename;
48 private boolean _extended;
49 private boolean _append;
50 private int _retainDays;
51 private boolean _closeOut;
52 private boolean _preferProxiedForAddress;
53 private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss Z";
54 private String _filenameDateFormat = null;
55 private Locale _logLocale = Locale.getDefault();
56 private String _logTimeZone = "GMT";
57 private String[] _ignorePaths;
58 private boolean _logLatency = false;
59 private boolean _logCookies = false;
60 private boolean _logServer = false;
61
62 private transient OutputStream _out;
63 private transient OutputStream _fileOut;
64 private transient DateCache _logDateCache;
65 private transient PathMap _ignorePathMap;
66 private transient Writer _writer;
67
68
69 public NCSARequestLog()
70 {
71 _extended = true;
72 _append = true;
73 _retainDays = 31;
74 }
75
76
77
78
79
80 public NCSARequestLog(String filename)
81 {
82 _extended = true;
83 _append = true;
84 _retainDays = 31;
85 setFilename(filename);
86 }
87
88
89
90
91
92 public void setFilename(String filename)
93 {
94 if (filename != null)
95 {
96 filename = filename.trim();
97 if (filename.length() == 0)
98 filename = null;
99 }
100 _filename = filename;
101 }
102
103 public String getFilename()
104 {
105 return _filename;
106 }
107
108 public String getDatedFilename()
109 {
110 if (_fileOut instanceof RolloverFileOutputStream)
111 return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
112 return null;
113 }
114
115
116
117
118
119
120 public void setLogDateFormat(String format)
121 {
122 _logDateFormat = format;
123 }
124
125 public String getLogDateFormat()
126 {
127 return _logDateFormat;
128 }
129
130
131 public void setLogTimeZone(String tz)
132 {
133 _logTimeZone = tz;
134 }
135
136 public String getLogTimeZone()
137 {
138 return _logTimeZone;
139 }
140
141 public void setRetainDays(int retainDays)
142 {
143 _retainDays = retainDays;
144 }
145
146 public int getRetainDays()
147 {
148 return _retainDays;
149 }
150
151 public void setExtended(boolean extended)
152 {
153 _extended = extended;
154 }
155
156 public boolean isExtended()
157 {
158 return _extended;
159 }
160
161 public void setAppend(boolean append)
162 {
163 _append = append;
164 }
165
166 public boolean isAppend()
167 {
168 return _append;
169 }
170
171 public void setIgnorePaths(String[] ignorePaths)
172 {
173 _ignorePaths = ignorePaths;
174 }
175
176 public String[] getIgnorePaths()
177 {
178 return _ignorePaths;
179 }
180
181 public void setLogCookies(boolean logCookies)
182 {
183 _logCookies = logCookies;
184 }
185
186 public boolean getLogCookies()
187 {
188 return _logCookies;
189 }
190
191 public boolean getLogServer()
192 {
193 return _logServer;
194 }
195
196 public void setLogServer(boolean logServer)
197 {
198 _logServer=logServer;
199 }
200
201 public void setLogLatency(boolean logLatency)
202 {
203 _logLatency = logLatency;
204 }
205
206 public boolean getLogLatency()
207 {
208 return _logLatency;
209 }
210
211 public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
212 {
213 _preferProxiedForAddress = preferProxiedForAddress;
214 }
215
216 public void log(Request request, Response response)
217 {
218 if (!isStarted())
219 return;
220
221 try
222 {
223 if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
224 return;
225
226 if (_fileOut == null)
227 return;
228
229 StringBuffer buf = new StringBuffer(160);
230 String log =null;
231 synchronized(buf)
232 {
233 if (_logServer)
234 {
235 buf.append(request.getServerName());
236 buf.append(' ');
237 }
238
239 String addr = null;
240 if (_preferProxiedForAddress)
241 {
242 addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
243 }
244
245 if (addr == null)
246 addr = request.getRemoteAddr();
247
248 buf.append(addr);
249 buf.append(" - ");
250 String user = request.getRemoteUser();
251 buf.append((user == null)? " - " : user);
252 buf.append(" [");
253 if (_logDateCache!=null)
254 buf.append(_logDateCache.format(request.getTimeStamp()));
255 else
256 buf.append(request.getTimeStampBuffer().toString());
257
258 buf.append("] \"");
259 buf.append(request.getMethod());
260 buf.append(' ');
261 buf.append(request.getUri());
262 buf.append(' ');
263 buf.append(request.getProtocol());
264 buf.append("\" ");
265 int status = response.getStatus();
266 if (status<=0)
267 status=404;
268 buf.append((char)('0'+((status/100)%10)));
269 buf.append((char)('0'+((status/10)%10)));
270 buf.append((char)('0'+(status%10)));
271
272
273 long responseLength=response.getContentCount();
274 if (responseLength >=0)
275 {
276 buf.append(' ');
277 if (responseLength > 99999)
278 buf.append(Long.toString(responseLength));
279 else
280 {
281 if (responseLength > 9999)
282 buf.append((char)('0' + ((responseLength / 10000)%10)));
283 if (responseLength > 999)
284 buf.append((char)('0' + ((responseLength /1000)%10)));
285 if (responseLength > 99)
286 buf.append((char)('0' + ((responseLength / 100)%10)));
287 if (responseLength > 9)
288 buf.append((char)('0' + ((responseLength / 10)%10)));
289 buf.append((char)('0' + (responseLength)%10));
290 }
291 buf.append(' ');
292 }
293 else
294 buf.append(" - ");
295
296 log = buf.toString();
297 }
298
299 synchronized(_writer)
300 {
301 _writer.write(log);
302 if (_extended)
303 logExtended(request, response, _writer);
304
305 if (_logCookies)
306 {
307 Cookie[] cookies = request.getCookies();
308 if (cookies == null || cookies.length == 0)
309 _writer.write(" -");
310 else
311 {
312 _writer.write(" \"");
313 for (int i = 0; i < cookies.length; i++)
314 {
315 if (i != 0)
316 _writer.write(';');
317 _writer.write(cookies[i].getName());
318 _writer.write('=');
319 _writer.write(cookies[i].getValue());
320 }
321 _writer.write("\"");
322 }
323 }
324
325 if (_logLatency)
326 {
327 _writer.write(" ");
328 _writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp()));
329 }
330
331 _writer.write(StringUtil.__LINE_SEPARATOR);
332 _writer.flush();
333
334 }
335 }
336 catch (IOException e)
337 {
338 Log.warn(e);
339 }
340
341 }
342
343 protected void logExtended(Request request,
344 Response response,
345 Writer writer) throws IOException
346 {
347 String referer = request.getHeader(HttpHeaders.REFERER);
348 if (referer == null)
349 writer.write("\"-\" ");
350 else
351 {
352 writer.write('"');
353 writer.write(referer);
354 writer.write("\" ");
355 }
356
357 String agent = request.getHeader(HttpHeaders.USER_AGENT);
358 if (agent == null)
359 writer.write("\"-\" ");
360 else
361 {
362 writer.write('"');
363 writer.write(agent);
364 writer.write('"');
365 }
366 }
367
368 protected void doStart() throws Exception
369 {
370 if (_logDateFormat!=null)
371 {
372 _logDateCache = new DateCache(_logDateFormat, _logLocale);
373 _logDateCache.setTimeZoneID(_logTimeZone);
374 }
375
376 if (_filename != null)
377 {
378 _fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
379 _closeOut = true;
380 Log.info("Opened "+getDatedFilename());
381 }
382 else
383 _fileOut = System.err;
384
385 _out = _fileOut;
386
387 if (_ignorePaths != null && _ignorePaths.length > 0)
388 {
389 _ignorePathMap = new PathMap();
390 for (int i = 0; i < _ignorePaths.length; i++)
391 _ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
392 }
393 else
394 _ignorePathMap = null;
395
396 _writer = new OutputStreamWriter(_out);
397 super.doStart();
398 }
399
400 protected void doStop() throws Exception
401 {
402 super.doStop();
403 try {if (_writer != null) _writer.flush();} catch (IOException e) {Log.ignore(e);}
404 if (_out != null && _closeOut)
405 try {_out.close();} catch (IOException e) {Log.ignore(e);}
406
407 _out = null;
408 _fileOut = null;
409 _closeOut = false;
410 _logDateCache = null;
411 _writer = null;
412 }
413
414
415
416
417
418 public String getFilenameDateFormat()
419 {
420 return _filenameDateFormat;
421 }
422
423
424
425
426
427
428 public void setFilenameDateFormat(String logFileDateFormat)
429 {
430 _filenameDateFormat=logFileDateFormat;
431 }
432
433 }