1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.io.IOException;
22 import java.util.Locale;
23
24 import javax.servlet.http.Cookie;
25
26 import org.eclipse.jetty.http.HttpHeader;
27 import org.eclipse.jetty.http.PathMap;
28 import org.eclipse.jetty.server.handler.StatisticsHandler;
29 import org.eclipse.jetty.util.DateCache;
30 import org.eclipse.jetty.util.annotation.ManagedAttribute;
31 import org.eclipse.jetty.util.component.AbstractLifeCycle;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34
35
36
37
38
39
40
41 public abstract class AbstractNCSARequestLog extends AbstractLifeCycle implements RequestLog
42 {
43 protected static final Logger LOG = Log.getLogger(AbstractNCSARequestLog.class);
44
45 private static ThreadLocal<StringBuilder> _buffers = new ThreadLocal<StringBuilder>()
46 {
47 @Override
48 protected StringBuilder initialValue()
49 {
50 return new StringBuilder(256);
51 }
52 };
53
54
55 private String[] _ignorePaths;
56 private boolean _extended;
57 private transient PathMap<String> _ignorePathMap;
58 private boolean _logLatency = false;
59 private boolean _logCookies = false;
60 private boolean _logServer = false;
61 private boolean _preferProxiedForAddress;
62 private transient DateCache _logDateCache;
63 private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z";
64 private Locale _logLocale = Locale.getDefault();
65 private String _logTimeZone = "GMT";
66
67
68
69
70
71
72
73 protected abstract boolean isEnabled();
74
75
76
77
78
79
80
81
82 public abstract void write(String requestEntry) throws IOException;
83
84
85
86 private void append(StringBuilder buf,String s)
87 {
88 if (s==null || s.length()==0)
89 buf.append('-');
90 else
91 buf.append(s);
92 }
93
94
95
96
97
98
99 @Override
100 public void log(Request request, Response response)
101 {
102 try
103 {
104 int status = response.getCommittedMetaData().getStatus();
105 long written = response.getHttpChannel().getBytesWritten();
106
107 if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
108 return;
109
110 if (!isEnabled())
111 return;
112
113 StringBuilder buf = _buffers.get();
114 buf.setLength(0);
115
116 if (_logServer)
117 {
118 append(buf,request.getServerName());
119 buf.append(' ');
120 }
121
122 String addr = null;
123 if (_preferProxiedForAddress)
124 {
125 addr = request.getHeader(HttpHeader.X_FORWARDED_FOR.toString());
126 }
127
128 if (addr == null)
129 addr = request.getRemoteAddr();
130
131 buf.append(addr);
132 buf.append(" - ");
133 Authentication authentication = request.getAuthentication();
134 append(buf,(authentication instanceof Authentication.User)?((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName():null);
135
136 buf.append(" [");
137 if (_logDateCache != null)
138 buf.append(_logDateCache.format(request.getTimeStamp()));
139 else
140 buf.append(request.getTimeStamp());
141
142 buf.append("] \"");
143 append(buf,request.getMethod());
144 buf.append(' ');
145 append(buf,request.getHttpURI().toString());
146 buf.append(' ');
147 append(buf,request.getProtocol());
148 buf.append("\" ");
149
150 if (status >=0)
151 {
152 buf.append((char)('0' + ((status / 100) % 10)));
153 buf.append((char)('0' + ((status / 10) % 10)));
154 buf.append((char)('0' + (status % 10)));
155 }
156 else
157 buf.append(status);
158
159 if (written >= 0)
160 {
161 buf.append(' ');
162 if (written > 99999)
163 buf.append(written);
164 else
165 {
166 if (written > 9999)
167 buf.append((char)('0' + ((written / 10000) % 10)));
168 if (written > 999)
169 buf.append((char)('0' + ((written / 1000) % 10)));
170 if (written > 99)
171 buf.append((char)('0' + ((written / 100) % 10)));
172 if (written > 9)
173 buf.append((char)('0' + ((written / 10) % 10)));
174 buf.append((char)('0' + (written) % 10));
175 }
176 buf.append(' ');
177 }
178 else
179 buf.append(" - ");
180
181
182 if (_extended)
183 logExtended(request, buf);
184
185 if (_logCookies)
186 {
187 Cookie[] cookies = request.getCookies();
188 if (cookies == null || cookies.length == 0)
189 buf.append(" -");
190 else
191 {
192 buf.append(" \"");
193 for (int i = 0; i < cookies.length; i++)
194 {
195 if (i != 0)
196 buf.append(';');
197 buf.append(cookies[i].getName());
198 buf.append('=');
199 buf.append(cookies[i].getValue());
200 }
201 buf.append('\"');
202 }
203 }
204
205 if (_logLatency)
206 {
207 long now = System.currentTimeMillis();
208
209 if (_logLatency)
210 {
211 buf.append(' ');
212 buf.append(now - request.getTimeStamp());
213 }
214 }
215
216 String log = buf.toString();
217 write(log);
218 }
219 catch (IOException e)
220 {
221 LOG.warn(e);
222 }
223 }
224
225
226
227
228
229
230
231
232
233
234 protected void logExtended(Request request,
235 StringBuilder b) throws IOException
236 {
237 String referer = request.getHeader(HttpHeader.REFERER.toString());
238 if (referer == null)
239 b.append("\"-\" ");
240 else
241 {
242 b.append('"');
243 b.append(referer);
244 b.append("\" ");
245 }
246
247 String agent = request.getHeader(HttpHeader.USER_AGENT.toString());
248 if (agent == null)
249 b.append("\"-\" ");
250 else
251 {
252 b.append('"');
253 b.append(agent);
254 b.append('"');
255 }
256 }
257
258
259
260
261
262
263
264 public void setIgnorePaths(String[] ignorePaths)
265 {
266 _ignorePaths = ignorePaths;
267 }
268
269
270
271
272
273
274 public String[] getIgnorePaths()
275 {
276 return _ignorePaths;
277 }
278
279
280
281
282
283
284
285 public void setLogCookies(boolean logCookies)
286 {
287 _logCookies = logCookies;
288 }
289
290
291
292
293
294
295 public boolean getLogCookies()
296 {
297 return _logCookies;
298 }
299
300
301
302
303
304
305 public void setLogServer(boolean logServer)
306 {
307 _logServer = logServer;
308 }
309
310
311
312
313
314
315 public boolean getLogServer()
316 {
317 return _logServer;
318 }
319
320
321
322
323
324
325
326 public void setLogLatency(boolean logLatency)
327 {
328 _logLatency = logLatency;
329 }
330
331
332
333
334
335
336 public boolean getLogLatency()
337 {
338 return _logLatency;
339 }
340
341
342
343
344
345 @Deprecated
346 public void setLogDispatch(boolean value)
347 {
348 }
349
350
351
352
353
354 @Deprecated
355 public boolean isLogDispatch()
356 {
357 return false;
358 }
359
360
361
362
363
364
365
366
367 public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
368 {
369 _preferProxiedForAddress = preferProxiedForAddress;
370 }
371
372
373
374
375
376
377 public boolean getPreferProxiedForAddress()
378 {
379 return _preferProxiedForAddress;
380 }
381
382
383
384
385
386
387 public void setExtended(boolean extended)
388 {
389 _extended = extended;
390 }
391
392
393
394
395
396
397 @ManagedAttribute("use extended NCSA format")
398 public boolean isExtended()
399 {
400 return _extended;
401 }
402
403
404
405
406
407
408 @Override
409 protected synchronized void doStart() throws Exception
410 {
411 if (_logDateFormat != null)
412 {
413 _logDateCache = new DateCache(_logDateFormat, _logLocale ,_logTimeZone);
414 }
415
416 if (_ignorePaths != null && _ignorePaths.length > 0)
417 {
418 _ignorePathMap = new PathMap<>();
419 for (int i = 0; i < _ignorePaths.length; i++)
420 _ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
421 }
422 else
423 _ignorePathMap = null;
424
425 super.doStart();
426 }
427
428 @Override
429 protected void doStop() throws Exception
430 {
431 _logDateCache = null;
432 super.doStop();
433 }
434
435
436
437
438
439
440
441 public void setLogDateFormat(String format)
442 {
443 _logDateFormat = format;
444 }
445
446
447
448
449
450
451 public String getLogDateFormat()
452 {
453 return _logDateFormat;
454 }
455
456
457
458
459
460
461 public void setLogLocale(Locale logLocale)
462 {
463 _logLocale = logLocale;
464 }
465
466
467
468
469
470
471 public Locale getLogLocale()
472 {
473 return _logLocale;
474 }
475
476
477
478
479
480
481 public void setLogTimeZone(String tz)
482 {
483 _logTimeZone = tz;
484 }
485
486
487
488
489
490
491 @ManagedAttribute("the timezone")
492 public String getLogTimeZone()
493 {
494 return _logTimeZone;
495 }
496 }