1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd. 4 // ------------------------------------------------------------------------ 5 // All rights reserved. This program and the accompanying materials 6 // are made available under the terms of the Eclipse Public License v1.0 7 // and Apache License v2.0 which accompanies this distribution. 8 // 9 // The Eclipse Public License is available at 10 // http://www.eclipse.org/legal/epl-v10.html 11 // 12 // The Apache License v2.0 is available at 13 // http://www.opensource.org/licenses/apache2.0.php 14 // 15 // You may elect to redistribute this code under either of these licenses. 16 // ======================================================================== 17 // 18 19 package org.eclipse.jetty.server; 20 21 import java.io.IOException; 22 import java.io.OutputStream; 23 import java.io.OutputStreamWriter; 24 import java.io.Writer; 25 import java.util.TimeZone; 26 27 import org.eclipse.jetty.util.RolloverFileOutputStream; 28 import org.eclipse.jetty.util.StringUtil; 29 import org.eclipse.jetty.util.annotation.ManagedAttribute; 30 import org.eclipse.jetty.util.annotation.ManagedObject; 31 32 /** 33 * This {@link RequestLog} implementation outputs logs in the pseudo-standard 34 * NCSA common log format. Configuration options allow a choice between the 35 * standard Common Log Format (as used in the 3 log format) and the Combined Log 36 * Format (single log format). This log format can be output by most web 37 * servers, and almost all web log analysis software can understand these 38 * formats. 39 */ 40 @ManagedObject("NCSA standard format request log") 41 public class NCSARequestLog extends AbstractNCSARequestLog implements RequestLog 42 { 43 private String _filename; 44 private boolean _append; 45 private int _retainDays; 46 private boolean _closeOut; 47 private String _filenameDateFormat = null; 48 private transient OutputStream _out; 49 private transient OutputStream _fileOut; 50 private transient Writer _writer; 51 52 /* ------------------------------------------------------------ */ 53 /** 54 * Create request log object with default settings. 55 */ 56 public NCSARequestLog() 57 { 58 setExtended(true); 59 _append = true; 60 _retainDays = 31; 61 } 62 63 /* ------------------------------------------------------------ */ 64 /** 65 * Create request log object with specified output file name. 66 * 67 * @param filename the file name for the request log. 68 * This may be in the format expected 69 * by {@link RolloverFileOutputStream} 70 */ 71 public NCSARequestLog(String filename) 72 { 73 setExtended(true); 74 _append = true; 75 _retainDays = 31; 76 setFilename(filename); 77 } 78 79 /* ------------------------------------------------------------ */ 80 /** 81 * Set the output file name of the request log. 82 * The file name may be in the format expected by 83 * {@link RolloverFileOutputStream}. 84 * 85 * @param filename file name of the request log 86 * 87 */ 88 public void setFilename(String filename) 89 { 90 if (filename != null) 91 { 92 filename = filename.trim(); 93 if (filename.length() == 0) 94 filename = null; 95 } 96 _filename = filename; 97 } 98 99 /* ------------------------------------------------------------ */ 100 /** 101 * Retrieve the output file name of the request log. 102 * 103 * @return file name of the request log 104 */ 105 @ManagedAttribute("file of log") 106 public String getFilename() 107 { 108 return _filename; 109 } 110 111 /* ------------------------------------------------------------ */ 112 /** 113 * Retrieve the file name of the request log with the expanded 114 * date wildcard if the output is written to the disk using 115 * {@link RolloverFileOutputStream}. 116 * 117 * @return file name of the request log, or null if not applicable 118 */ 119 public String getDatedFilename() 120 { 121 if (_fileOut instanceof RolloverFileOutputStream) 122 return ((RolloverFileOutputStream)_fileOut).getDatedFilename(); 123 return null; 124 } 125 126 /* ------------------------------------------------------------ */ 127 @Override 128 protected boolean isEnabled() 129 { 130 return (_fileOut != null); 131 } 132 133 /* ------------------------------------------------------------ */ 134 /** 135 * Set the number of days before rotated log files are deleted. 136 * 137 * @param retainDays number of days to keep a log file 138 */ 139 public void setRetainDays(int retainDays) 140 { 141 _retainDays = retainDays; 142 } 143 144 /* ------------------------------------------------------------ */ 145 /** 146 * Retrieve the number of days before rotated log files are deleted. 147 * 148 * @return number of days to keep a log file 149 */ 150 @ManagedAttribute("number of days that log files are kept") 151 public int getRetainDays() 152 { 153 return _retainDays; 154 } 155 156 /* ------------------------------------------------------------ */ 157 /** 158 * Set append to log flag. 159 * 160 * @param append true - request log file will be appended after restart, 161 * false - request log file will be overwritten after restart 162 */ 163 public void setAppend(boolean append) 164 { 165 _append = append; 166 } 167 168 /* ------------------------------------------------------------ */ 169 /** 170 * Retrieve append to log flag. 171 * 172 * @return value of the flag 173 */ 174 @ManagedAttribute("existing log files are appends to the new one") 175 public boolean isAppend() 176 { 177 return _append; 178 } 179 180 /* ------------------------------------------------------------ */ 181 /** 182 * Set the log file name date format. 183 * @see RolloverFileOutputStream#RolloverFileOutputStream(String, boolean, int, TimeZone, String, String) 184 * 185 * @param logFileDateFormat format string that is passed to {@link RolloverFileOutputStream} 186 */ 187 public void setFilenameDateFormat(String logFileDateFormat) 188 { 189 _filenameDateFormat = logFileDateFormat; 190 } 191 192 /* ------------------------------------------------------------ */ 193 /** 194 * Retrieve the file name date format string. 195 * 196 * @return the log File Date Format 197 */ 198 public String getFilenameDateFormat() 199 { 200 return _filenameDateFormat; 201 } 202 203 /* ------------------------------------------------------------ */ 204 @Override 205 public void write(String requestEntry) throws IOException 206 { 207 synchronized(this) 208 { 209 if (_writer==null) 210 return; 211 _writer.write(requestEntry); 212 _writer.write(StringUtil.__LINE_SEPARATOR); 213 _writer.flush(); 214 } 215 } 216 217 /* ------------------------------------------------------------ */ 218 /** 219 * Set up request logging and open log file. 220 * 221 * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() 222 */ 223 @Override 224 protected synchronized void doStart() throws Exception 225 { 226 if (_filename != null) 227 { 228 _fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(getLogTimeZone()),_filenameDateFormat,null); 229 _closeOut = true; 230 LOG.info("Opened " + getDatedFilename()); 231 } 232 else 233 _fileOut = System.err; 234 235 _out = _fileOut; 236 237 synchronized(this) 238 { 239 _writer = new OutputStreamWriter(_out); 240 } 241 super.doStart(); 242 } 243 244 /* ------------------------------------------------------------ */ 245 /** 246 * Close the log file and perform cleanup. 247 * 248 * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() 249 */ 250 @Override 251 protected void doStop() throws Exception 252 { 253 synchronized (this) 254 { 255 super.doStop(); 256 try 257 { 258 if (_writer != null) 259 _writer.flush(); 260 } 261 catch (IOException e) 262 { 263 LOG.ignore(e); 264 } 265 if (_out != null && _closeOut) 266 try 267 { 268 _out.close(); 269 } 270 catch (IOException e) 271 { 272 LOG.ignore(e); 273 } 274 275 _out = null; 276 _fileOut = null; 277 _closeOut = false; 278 _writer = null; 279 } 280 } 281 }