1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server;
15
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.io.OutputStreamWriter;
19 import java.io.Writer;
20 import java.util.Locale;
21 import java.util.TimeZone;
22
23 import javax.servlet.http.Cookie;
24
25 import org.eclipse.jetty.http.HttpHeaders;
26 import org.eclipse.jetty.http.PathMap;
27 import org.eclipse.jetty.util.DateCache;
28 import org.eclipse.jetty.util.RolloverFileOutputStream;
29 import org.eclipse.jetty.util.StringUtil;
30 import org.eclipse.jetty.util.component.AbstractLifeCycle;
31 import org.eclipse.jetty.util.log.Log;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
48 {
49 private String _filename;
50 private boolean _extended;
51 private boolean _append;
52 private int _retainDays;
53 private boolean _closeOut;
54 private boolean _preferProxiedForAddress;
55 private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z";
56 private String _filenameDateFormat = null;
57 private Locale _logLocale = Locale.getDefault();
58 private String _logTimeZone = "GMT";
59 private String[] _ignorePaths;
60 private boolean _logLatency = false;
61 private boolean _logCookies = false;
62 private boolean _logServer = false;
63 private boolean _logDispatch = false;
64
65 private transient OutputStream _out;
66 private transient OutputStream _fileOut;
67 private transient DateCache _logDateCache;
68 private transient PathMap _ignorePathMap;
69 private transient Writer _writer;
70
71
72
73
74
75 public NCSARequestLog()
76 {
77 _extended = true;
78 _append = true;
79 _retainDays = 31;
80 }
81
82
83
84
85
86
87
88
89
90 public NCSARequestLog(String filename)
91 {
92 _extended = true;
93 _append = true;
94 _retainDays = 31;
95 setFilename(filename);
96 }
97
98
99
100
101
102
103
104
105
106
107 public void setFilename(String filename)
108 {
109 if (filename != null)
110 {
111 filename = filename.trim();
112 if (filename.length() == 0)
113 filename = null;
114 }
115 _filename = filename;
116 }
117
118
119
120
121
122
123
124 public String getFilename()
125 {
126 return _filename;
127 }
128
129
130
131
132
133
134
135
136
137 public String getDatedFilename()
138 {
139 if (_fileOut instanceof RolloverFileOutputStream)
140 return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
141 return null;
142 }
143
144
145
146
147
148
149
150
151 public void setLogDateFormat(String format)
152 {
153 _logDateFormat = format;
154 }
155
156
157
158
159
160
161
162 public String getLogDateFormat()
163 {
164 return _logDateFormat;
165 }
166
167
168
169
170
171
172
173 public void setLogLocale(Locale logLocale)
174 {
175 _logLocale = logLocale;
176 }
177
178
179
180
181
182
183
184 public Locale getLogLocale()
185 {
186 return _logLocale;
187 }
188
189
190
191
192
193
194
195 public void setLogTimeZone(String tz)
196 {
197 _logTimeZone = tz;
198 }
199
200
201
202
203
204
205
206 public String getLogTimeZone()
207 {
208 return _logTimeZone;
209 }
210
211
212
213
214
215
216
217 public void setRetainDays(int retainDays)
218 {
219 _retainDays = retainDays;
220 }
221
222
223
224
225
226
227
228 public int getRetainDays()
229 {
230 return _retainDays;
231 }
232
233
234
235
236
237
238
239
240 public void setExtended(boolean extended)
241 {
242 _extended = extended;
243 }
244
245
246
247
248
249
250
251 public boolean isExtended()
252 {
253 return _extended;
254 }
255
256
257
258
259
260
261
262
263 public void setAppend(boolean append)
264 {
265 _append = append;
266 }
267
268
269
270
271
272
273
274 public boolean isAppend()
275 {
276 return _append;
277 }
278
279
280
281
282
283
284
285 public void setIgnorePaths(String[] ignorePaths)
286 {
287 _ignorePaths = ignorePaths;
288 }
289
290
291
292
293
294
295
296 public String[] getIgnorePaths()
297 {
298 return _ignorePaths;
299 }
300
301
302
303
304
305
306
307
308 public void setLogCookies(boolean logCookies)
309 {
310 _logCookies = logCookies;
311 }
312
313
314
315
316
317
318
319 public boolean getLogCookies()
320 {
321 return _logCookies;
322 }
323
324
325
326
327
328
329
330
331 public void setLogServer(boolean logServer)
332 {
333 _logServer = logServer;
334 }
335
336
337
338
339
340
341
342 public boolean getLogServer()
343 {
344 return _logServer;
345 }
346
347
348
349
350
351
352
353
354 public void setLogLatency(boolean logLatency)
355 {
356 _logLatency = logLatency;
357 }
358
359
360
361
362
363
364
365 public boolean getLogLatency()
366 {
367 return _logLatency;
368 }
369
370
371
372
373
374
375
376
377
378 public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
379 {
380 _preferProxiedForAddress = preferProxiedForAddress;
381 }
382
383
384
385
386
387
388
389 public boolean getPreferProxiedForAddress()
390 {
391 return _preferProxiedForAddress;
392 }
393
394
395
396
397
398
399
400
401 public void setFilenameDateFormat(String logFileDateFormat)
402 {
403 _filenameDateFormat = logFileDateFormat;
404 }
405
406
407
408
409
410
411
412 public String getFilenameDateFormat()
413 {
414 return _filenameDateFormat;
415 }
416
417
418
419
420
421
422
423
424 public void setLogDispatch(boolean value)
425 {
426 _logDispatch = value;
427 }
428
429
430
431
432
433
434
435 public boolean isLogDispatch()
436 {
437 return _logDispatch;
438 }
439
440
441
442
443
444
445
446 public void log(Request request, Response response)
447 {
448 try
449 {
450 if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
451 return;
452
453 if (_fileOut == null)
454 return;
455
456 StringBuilder buf= new StringBuilder(256);
457
458 if (_logServer)
459 {
460 buf.append(request.getServerName());
461 buf.append(' ');
462 }
463
464 String addr = null;
465 if (_preferProxiedForAddress)
466 {
467 addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
468 }
469
470 if (addr == null)
471 addr = request.getRemoteAddr();
472
473 buf.append(addr);
474 buf.append(" - ");
475 Authentication authentication=request.getAuthentication();
476 if (authentication instanceof Authentication.User)
477 buf.append(((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName());
478 else
479 buf.append(" - ");
480
481 buf.append(" [");
482 if (_logDateCache != null)
483 buf.append(_logDateCache.format(request.getTimeStamp()));
484 else
485 buf.append(request.getTimeStampBuffer().toString());
486
487 buf.append("] \"");
488 buf.append(request.getMethod());
489 buf.append(' ');
490 buf.append(request.getUri().toString());
491 buf.append(' ');
492 buf.append(request.getProtocol());
493 buf.append("\" ");
494 if (request.getAsyncContinuation().isInitial())
495 {
496 int status = response.getStatus();
497 if (status <= 0)
498 status = 404;
499 buf.append((char)('0' + ((status / 100) % 10)));
500 buf.append((char)('0' + ((status / 10) % 10)));
501 buf.append((char)('0' + (status % 10)));
502 }
503 else
504 buf.append("Async");
505
506 long responseLength = response.getContentCount();
507 if (responseLength >= 0)
508 {
509 buf.append(' ');
510 if (responseLength > 99999)
511 buf.append(responseLength);
512 else
513 {
514 if (responseLength > 9999)
515 buf.append((char)('0' + ((responseLength / 10000) % 10)));
516 if (responseLength > 999)
517 buf.append((char)('0' + ((responseLength / 1000) % 10)));
518 if (responseLength > 99)
519 buf.append((char)('0' + ((responseLength / 100) % 10)));
520 if (responseLength > 9)
521 buf.append((char)('0' + ((responseLength / 10) % 10)));
522 buf.append((char)('0' + (responseLength) % 10));
523 }
524 buf.append(' ');
525 }
526 else
527 buf.append(" - ");
528
529
530 if (_extended)
531 logExtended(request, response, buf);
532
533 if (_logCookies)
534 {
535 Cookie[] cookies = request.getCookies();
536 if (cookies == null || cookies.length == 0)
537 buf.append(" -");
538 else
539 {
540 buf.append(" \"");
541 for (int i = 0; i < cookies.length; i++)
542 {
543 if (i != 0)
544 buf.append(';');
545 buf.append(cookies[i].getName());
546 buf.append('=');
547 buf.append(cookies[i].getValue());
548 }
549 buf.append('\"');
550 }
551 }
552
553 if (_logDispatch || _logLatency)
554 {
555 long now = System.currentTimeMillis();
556
557 if (_logDispatch)
558 {
559 long d = request.getDispatchTime();
560 buf.append(' ');
561 buf.append(now - (d==0 ? request.getTimeStamp():d));
562 }
563
564 if (_logLatency)
565 {
566 buf.append(' ');
567 buf.append(now - request.getTimeStamp());
568 }
569 }
570
571 buf.append(StringUtil.__LINE_SEPARATOR);
572 String log = buf.toString();
573 synchronized(this)
574 {
575 if (_writer==null)
576 return;
577 _writer.write(log);
578 _writer.flush();
579 }
580 }
581 catch (IOException e)
582 {
583 Log.warn(e);
584 }
585
586 }
587
588
589
590
591
592
593
594
595
596
597 protected void logExtended(Request request,
598 Response response,
599 StringBuilder b) throws IOException
600 {
601 String referer = request.getHeader(HttpHeaders.REFERER);
602 if (referer == null)
603 b.append("\"-\" ");
604 else
605 {
606 b.append('"');
607 b.append(referer);
608 b.append("\" ");
609 }
610
611 String agent = request.getHeader(HttpHeaders.USER_AGENT);
612 if (agent == null)
613 b.append("\"-\" ");
614 else
615 {
616 b.append('"');
617 b.append(agent);
618 b.append('"');
619 }
620 }
621
622
623
624
625
626
627
628 @Override
629 protected void doStart() throws Exception
630 {
631 if (_logDateFormat != null)
632 {
633 _logDateCache = new DateCache(_logDateFormat,_logLocale);
634 _logDateCache.setTimeZoneID(_logTimeZone);
635 }
636
637 if (_filename != null)
638 {
639 _fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
640 _closeOut = true;
641 Log.info("Opened " + getDatedFilename());
642 }
643 else
644 _fileOut = System.err;
645
646 _out = _fileOut;
647
648 if (_ignorePaths != null && _ignorePaths.length > 0)
649 {
650 _ignorePathMap = new PathMap();
651 for (int i = 0; i < _ignorePaths.length; i++)
652 _ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
653 }
654 else
655 _ignorePathMap = null;
656
657 _writer = new OutputStreamWriter(_out);
658 super.doStart();
659 }
660
661
662
663
664
665
666
667 @Override
668 protected void doStop() throws Exception
669 {
670 synchronized (this)
671 {
672 super.doStop();
673 try
674 {
675 if (_writer != null)
676 _writer.flush();
677 }
678 catch (IOException e)
679 {
680 Log.ignore(e);
681 }
682 if (_out != null && _closeOut)
683 try
684 {
685 _out.close();
686 }
687 catch (IOException e)
688 {
689 Log.ignore(e);
690 }
691
692 _out = null;
693 _fileOut = null;
694 _closeOut = false;
695 _logDateCache = null;
696 _writer = null;
697 }
698 }
699 }