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