Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mortbay/util/OutputStreamLogSink.java


1   // ========================================================================
2   // Copyright (c) 1997 MortBay Consulting, Sydney
3   // $Id: OutputStreamLogSink.java,v 1.17 2003/04/24 21:57:52 bretts Exp $
4   // ========================================================================
5   
6   package org.mortbay.util;
7   
8   import java.io.IOException;
9   import java.io.OutputStream;
10  import java.util.TimeZone;
11  
12  
13  /* ------------------------------------------------------------ */
14  /** A Log sink.
15   * This class represents both a concrete or abstract sink of
16   * Log data.  The default implementation logs to System.err, but
17   * other output stream or files may be specified.
18   *
19   * Currently this Stream only writes in ISO8859_1 encoding.  For
20   * Other encodings use the less efficient WriterLogSink.
21   *
22   * If a logFilename is specified, output is sent to that file.
23   * If the filename contains "yyyy_mm_dd", the log file date format
24   * is used to create the actual filename and the log file is rolled
25   * over at local midnight.
26   * If append is set, existing logfiles are appended to, otherwise
27   * a backup is created with a timestamp.
28   * Dated log files are deleted after retain days.
29   * 
30   * <p> If the property LOG_DATE_FORMAT is set, then it is interpreted
31   * as a format string for java.text.SimpleDateFormat and used to
32   * format the log timestamps. Default value: HH:mm:ss.SSS
33   *
34   * <p> If LOG_TIMEZONE is set, it is used to set the timezone of the log date
35   * format, otherwise GMT is used.
36   *
37   * @see org.mortbay.util.Log
38   * @version $Id: OutputStreamLogSink.java,v 1.17 2003/04/24 21:57:52 bretts Exp $
39   * @author Greg Wilkins (gregw)
40   */
41  public class OutputStreamLogSink
42      implements LogSink
43  {
44      /*-------------------------------------------------------------------*/
45      public final static char OPT_TIMESTAMP = 't';
46      public final static char OPT_LABEL = 'L';
47      public final static char OPT_TAG = 'T';
48      public final static char OPT_STACKSIZE = 's';
49      public final static char OPT_STACKTRACE = 'S';
50      public final static char OPT_ONELINE = 'O';
51      
52      /* ------------------------------------------------------------ */
53      private final static String __lineSeparator =
54          System.getProperty("line.separator");
55  
56      /*-------------------------------------------------------------------*/
57      private int _retainDays =Integer.getInteger("LOG_FILE_RETAIN_DAYS",31).intValue();
58      
59      protected DateCache _dateFormat=
60          new DateCache(System.getProperty("LOG_DATE_FORMAT","HH:mm:ss.SSS"));
61      protected String _logTimezone=
62    System.getProperty("LOG_TIME_ZONE");    
63      {
64          if (_logTimezone!=null)
65              _dateFormat.getFormat().setTimeZone(TimeZone.getTimeZone(_logTimezone));
66      }
67  
68      /* ------------------------------------------------------------ */
69      protected boolean _logTimeStamps=true;
70      protected boolean _logLabels=true;
71      protected boolean _logTags=true;
72      protected boolean _logStackSize=true;
73      protected boolean _logStackTrace=false;
74      protected boolean _logOneLine=false;
75      
76      /*-------------------------------------------------------------------*/
77      private String _filename;
78      private boolean _append=true;
79      protected boolean _flushOn=true;
80      protected int _bufferSize=2048;
81      protected boolean _reopen=false;
82  
83      protected transient boolean _started;
84      protected transient OutputStream _out;
85      protected transient ByteArrayISO8859Writer _buffer;
86  
87      /* ------------------------------------------------------------ */
88      /** Constructor. 
89       */
90      public OutputStreamLogSink()
91          throws IOException
92      {
93          _filename=System.getProperty("LOG_FILE");
94          if (_filename==null)
95              _out=System.err;
96      }
97          
98      /* ------------------------------------------------------------ */
99      public OutputStreamLogSink(String filename)
100     {
101         _filename=filename;
102     }
103     
104     /* ------------------------------------------------------------ */
105     public void setOptions(String logOptions)
106     {  
107         setOptions((logOptions.indexOf(OPT_TIMESTAMP) >= 0),
108                    (logOptions.indexOf(OPT_LABEL) >= 0),
109                    (logOptions.indexOf(OPT_TAG) >= 0),
110                    (logOptions.indexOf(OPT_STACKSIZE) >= 0),
111                    (logOptions.indexOf(OPT_STACKTRACE) >= 0),
112                    (logOptions.indexOf(OPT_ONELINE) >= 0));
113     }
114     
115     /* ------------------------------------------------------------ */
116     public String getOptions()
117     {
118         return
119             (_logTimeStamps?"t":"")+
120             (_logLabels?"L":"")+
121             (_logTags?"T":"")+
122             (_logStackSize?"s":"")+
123             (_logStackTrace?"S":"")+
124             (_logOneLine?"O":"");
125     }
126     
127     
128     /*-------------------------------------------------------------------*/
129     /** Set the log options.
130      */
131     public void setOptions(boolean logTimeStamps,
132                            boolean logLabels,
133                            boolean logTags,
134                            boolean logStackSize,
135                            boolean logStackTrace,
136                            boolean logOneLine)
137     {
138         _logTimeStamps      = logTimeStamps;
139         _logLabels          = logLabels;
140         _logTags            = logTags;
141         _logStackSize       = logStackSize;
142         _logStackTrace      = logStackTrace;
143         _logOneLine         = logOneLine;
144     }
145     
146     /* ------------------------------------------------------------ */
147     public String getLogDateFormat()
148     {
149         return _dateFormat.getFormatString();
150     }
151     
152     /* ------------------------------------------------------------ */
153     public void setLogDateFormat(String logDateFormat)
154     {
155         _dateFormat = new DateCache(logDateFormat);
156         if (_logTimezone!=null)
157             _dateFormat.getFormat().setTimeZone(TimeZone.getTimeZone(_logTimezone));
158     }
159 
160     
161     /* ------------------------------------------------------------ */
162     /** 
163      * @deprecated Use getLogTimeZone() 
164      */
165     public String getLogTimezone()
166     {
167         return _logTimezone;
168     }
169     
170     /* ------------------------------------------------------------ */
171     /** 
172      * @deprecated Use setLogTimeZone(String) 
173      */
174     public void setLogTimezone(String logTimezone)
175     {
176         _logTimezone=logTimezone;
177         if (_dateFormat!=null && _logTimezone!=null)
178             _dateFormat.getFormat().setTimeZone(TimeZone.getTimeZone(_logTimezone));
179     }
180     
181     /* ------------------------------------------------------------ */
182     public String getLogTimeZone()
183     {
184         return _logTimezone;
185     }
186     
187     /* ------------------------------------------------------------ */
188     public void setLogTimeZone(String logTimezone)
189     {
190         _logTimezone=logTimezone;
191         if (_dateFormat!=null && _logTimezone!=null)
192             _dateFormat.getFormat().setTimeZone(TimeZone.getTimeZone(_logTimezone));
193     }
194     
195     /* ------------------------------------------------------------ */
196     public boolean isLogTimeStamps()
197     {
198         return _logTimeStamps;
199     }
200     /* ------------------------------------------------------------ */
201     public void setLogTimeStamps(boolean logTimeStamps)
202     {
203         _logTimeStamps = logTimeStamps;
204     }
205     /* ------------------------------------------------------------ */
206     public boolean isLogLabels()
207     {
208         return _logLabels;
209     }
210     /* ------------------------------------------------------------ */
211     public void setLogLabels(boolean logLabels)
212     {
213         _logLabels = logLabels;
214     }
215     /* ------------------------------------------------------------ */
216     public boolean isLogTags()
217     {
218         return _logTags;
219     }
220     /* ------------------------------------------------------------ */
221     public void setLogTags(boolean logTags)
222     {
223         _logTags = logTags;
224     }
225     /* ------------------------------------------------------------ */
226     public boolean isLogStackSize()
227     {
228         return _logStackSize;
229     }
230     /* ------------------------------------------------------------ */
231     public void setLogStackSize(boolean logStackSize)
232     {
233         _logStackSize = logStackSize;
234     }
235     /* ------------------------------------------------------------ */
236     public boolean isLogStackTrace()
237     {
238         return _logStackTrace;
239     }
240     /* ------------------------------------------------------------ */
241     public void setLogStackTrace(boolean logStackTrace)
242     {
243         _logStackTrace = logStackTrace;
244     }
245     /* ------------------------------------------------------------ */
246     public boolean isLogOneLine()
247     {
248         return _logOneLine;
249     }
250     /* ------------------------------------------------------------ */
251     public void setLogOneLine(boolean logOneLine)
252     {
253         _logOneLine = logOneLine;
254     }
255 
256     /* ------------------------------------------------------------ */
257     public boolean isAppend()
258     {
259         return _append;
260     }
261 
262     /* ------------------------------------------------------------ */
263     public void setAppend(boolean a)
264     {
265         _append=a;
266     }
267     
268     /* ------------------------------------------------------------ */
269     public synchronized void setOutputStream(OutputStream out)
270     {
271         _reopen=isStarted() && out!=out;
272         _filename=null;
273         if (_buffer!=null)
274             _buffer.resetWriter();
275         _out=out;
276     }
277 
278     /* ------------------------------------------------------------ */
279     public OutputStream getOutputStream()
280     {
281         return _out;
282     }
283 
284     /* ------------------------------------------------------------ */
285     public  synchronized void setFilename(String filename)
286     {
287         if (filename!=null)
288         {
289             filename=filename.trim();
290             if (filename.length()==0)
291                 filename=null;
292         }
293         _reopen=isStarted() &&
294             ((_filename==null && filename!=null)||
295              (_filename!=null && !_filename.equals(filename)));
296         _filename=filename;
297 
298         if (!isStarted() && _filename!=null)
299             _out=null;
300     }
301 
302     /* ------------------------------------------------------------ */
303     public String getFilename()
304     {
305         return _filename;
306     }
307     
308     /* ------------------------------------------------------------ */
309     public String getDatedFilename()
310     {
311         if (_filename==null)
312             return null;
313 
314         if (_out==null || ! (_out instanceof RolloverFileOutputStream))
315             return null;
316 
317         return ((RolloverFileOutputStream)_out).getDatedFilename();
318     }
319     
320     /* ------------------------------------------------------------ */
321     public int getRetainDays()
322     {
323         return _retainDays;
324     }
325 
326     /* ------------------------------------------------------------ */
327     public void setRetainDays(int retainDays)
328     {
329         _reopen=isStarted() && _retainDays!=retainDays;
330         _retainDays = retainDays;
331     }
332     
333     /* ------------------------------------------------------------ */
334     /** 
335      * @param on If true, log is flushed on every log. 
336      */
337     public void setFlushOn(boolean on)
338     {
339         _flushOn=on;
340         if (on && _out!=null)
341         {
342             try{_out.flush();}
343             catch(IOException e){e.printStackTrace();}
344         }
345         
346     }
347     
348     /* ------------------------------------------------------------ */
349     /** 
350      * @return true, log is flushed on every log. 
351      */
352     public boolean getFlushOn()
353     {
354         return _flushOn;
355     }
356     
357     /* ------------------------------------------------------------ */
358     /** Log a message.
359      * This method formats the log information as a string and calls
360      * log(String).  It should only be specialized by a derived
361      * implementation if the format of the logged messages is to be changed.
362      *
363      * @param tag Tag for type of log
364      * @param msg The message
365      * @param frame The frame that generated the message.
366      * @param time The time stamp of the message.
367      */
368     public  synchronized void log(String tag,
369                                   Object msg,
370                                   Frame frame,
371                                   long time)
372     {
373         StringBuffer buf = new StringBuffer(160);
374         
375         // Log the time stamp
376         if (_logTimeStamps)
377         {
378             buf.append(_dateFormat.format(time));
379             buf.append(' ');
380         }
381             
382             
383         // Log the tag
384         if (_logTags)
385             buf.append(tag);
386         
387         // Log the label
388         if (_logLabels && frame != null)
389         {
390             buf.append(frame.toString());
391         }
392         
393         // Log the stack depth.
394         if (_logStackSize && frame != null)
395         {
396             if (frame.getDepth()<10)    
397                 buf.append('0');
398             buf.append(Integer.toString(frame.getDepth()));  
399             buf.append("> ");
400         }
401         
402         // Determine the indent string for the message and append it
403         // to the buffer. Only put a newline in the buffer if the first
404         // line is not blank
405         String nl=__lineSeparator;
406         
407         if (_logLabels && !_logOneLine && _buffer.size() > 0)
408             buf.append(nl);
409         
410         // Log indented message
411         String smsg=(msg==null)
412             ?"???"
413             :((msg instanceof String)?((String)msg):msg.toString());
414         
415         if (_logOneLine)
416         {
417             smsg=StringUtil.replace(smsg,"\015\012","<|");
418             smsg=StringUtil.replace(smsg,"\015","<");
419             smsg=StringUtil.replace(smsg,"\012","|");
420         }
421         else
422         {
423             smsg=StringUtil.replace(smsg,"\015\012","<|");
424             smsg=StringUtil.replace(smsg,"\015","<|");
425             smsg=StringUtil.replace(smsg,"\012","<|");
426             smsg=StringUtil.replace(smsg,"<|",nl);
427         }
428         buf.append(smsg);
429         
430         // Add stack frame to message
431         if (_logStackTrace && frame != null)
432         {
433             buf.append(nl);
434             buf.append(frame.getStack());
435         }
436         
437         log(buf.toString());
438     }
439     
440     /* ------------------------------------------------------------ */
441     /** Log a message.
442      * The formatted log string is written to the log sink. The default
443      * implementation writes the message to an outputstream.
444      * @param formattedLog 
445      */
446     public synchronized void log(String formattedLog)
447     {
448         if (_reopen)
449         {
450             stop();
451             start();
452         }
453         try
454         {
455             _buffer.write(formattedLog);
456             _buffer.write(StringUtil.__LINE_SEPARATOR);
457             if (_flushOn || _buffer.size()>_bufferSize)
458             {
459                 _buffer.writeTo(_out);
460                 _buffer.resetWriter();
461                 _out.flush();
462             }
463         }
464         catch(IOException e){e.printStackTrace();}
465     }
466 
467     
468     /* ------------------------------------------------------------ */
469     /** Start a log sink.
470      * The default implementation does nothing 
471      */
472     public synchronized void start()
473     {
474         _buffer=new ByteArrayISO8859Writer(_bufferSize);
475         _reopen=false;
476         if (_started)
477             return;
478         
479         if (_out==null && _filename!=null)
480         {
481             try
482             {
483                 RolloverFileOutputStream rfos=
484                     new RolloverFileOutputStream(_filename,_append,_retainDays);
485                 _out=rfos;
486             }
487             catch(IOException e){e.printStackTrace();}   
488         }
489 
490         if (_out==null)
491             _out=System.err;
492         
493         _started=true;
494     }
495     
496     
497     /* ------------------------------------------------------------ */
498     /** Stop a log sink.
499      * An opportunity for subclasses to clean up. The default
500      * implementation does nothing 
501      */
502     public synchronized void stop()
503     {
504         _started=false;
505 
506         if (_out!=null)
507         {
508             try
509             {
510                 if (_buffer.size()>0)
511                 {
512                     _buffer.writeTo(_out);
513                 }
514                 _out.flush();
515                 _buffer=null;
516             }
517             catch(Exception e){if (Code.debug())e.printStackTrace();}
518             Thread.yield();
519         }
520         
521         if (_out!=null && _out!=System.err)
522         {
523             try{_out.close();}
524             catch(Exception e){if (Code.debug())e.printStackTrace();}
525         }
526 
527         if (_filename!=null)
528             _out=null;
529     }
530 
531     /* ------------------------------------------------------------ */
532     public boolean isStarted()
533     {
534         return _started;
535     }    
536 };