View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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
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 }