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