LogWrapper.java

1    import java.io.BufferedOutputStream; 
2    import java.io.FileOutputStream; 
3    import java.io.IOException; 
4    import java.io.OutputStream; 
5    import java.io.PrintStream; 
6    import java.text.DateFormat; 
7    import java.text.SimpleDateFormat; 
8    import java.util.Date; 
9     
10   /** 
11    * <p> 
12    * LogWrapper can be used for situations where log4j might not be available on 
13    * the classpath.  It presents the most basic and critical components of the 
14    * log4j API, and passes all log calls through to log4j if possible.  If log4j 
15    * is not available, logging is sent to standard-out by default. 
16    * <p> 
17    * This default logging to standard-out (which only occurs if log4j is NOT 
18    * available) can be disabled or changed via the static setBackupStream() and 
19    * setBackupLogFile() methods. 
20    * 
21    * @author Credit Union Central of British Columbia 
22    * @author <a href="http://www.cucbc.com/">www.cucbc.com</a> 
23    * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a> 
24    * @since 3-Aug-2006 
25    */ 
26   public class LogWrapper { 
27    
28     final static String[] LEVELS = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}; 
29     final static String TIMESTAMP_PATTERN = "zzz:yyyy-MM-dd/HH:mm:ss.SSS"; 
30     final static int TIMESTAMP_LENGTH = TIMESTAMP_PATTERN.length(); 
31     final static String LINE_SEPARATOR = System.getProperty( "line.separator" ); 
32     final static DateFormat DF = new SimpleDateFormat(TIMESTAMP_PATTERN); 
33    
34     private final static LogWrapper NOOP = new LogWrapper(); 
35    
36     /** 
37      * true if log4j is available 
38      */ 
39     public final static boolean log4j; 
40    
41     /** 
42      * OutputStream to log to if log4j is not available.  Set it to null to 
43      * disable. 
44      */ 
45     private static volatile OutputStream backup = System.out; 
46    
47     /** 
48      * The wrappingPrintStream is lazy-initted if we have to log a stacktrace. 
49      */ 
50     private static volatile PrintStream wrappingPrintStream = null; 
51    
52     private final LogHelper h; 
53    
54     static { 
55       boolean avail = false; 
56       try { 
57         // LogHelper's constructor will blow up if log4j.jar isn't on the 
58         // classpath. 
59         LogHelper lh = new LogHelper( LogWrapper.class ); 
60         lh.hashCode(); 
61         avail = true; 
62       } 
63       catch (Throwable t) {} 
64       finally { 
65         log4j = avail; 
66       } 
67     } 
68    
69     public static boolean isLog4jAvailable() { return log4j; } 
70    
71     public static LogWrapper getLogger( Class c ) { 
72       return log4j ? new LogWrapper( c ) : NOOP; 
73     } 
74    
75     public static LogWrapper getLogger( String s ) { 
76       return log4j ? new LogWrapper( s ) : NOOP; 
77     } 
78    
79     private LogWrapper()                     { this.h = null;                   } 
80     private LogWrapper( Class c )            { this.h = new LogHelper( c );     } 
81     private LogWrapper( String s )           { this.h = new LogHelper( s );     } 
82     public void debug(Object o)              { if (t(0,o,null)) h.debug(o);     } 
83     public void debug(Object o, Throwable t) { if (t(0,o,t))    h.debug(o,t);   } 
84     public void info (Object o)              { if (t(1,o,null)) h.info(o);      } 
85     public void info (Object o, Throwable t) { if (t(1,o,t))    h.info(o,t);    } 
86     public void warn (Object o)              { if (t(2,o,null)) h.warn(o);      } 
87     public void warn (Object o, Throwable t) { if (t(2,o,t))    h.warn(o,t);    } 
88     public void error(Object o)              { if (t(3,o,null)) h.error(o);     } 
89     public void error(Object o, Throwable t) { if (t(3,o,t))    h.error(o,t);   } 
90     public void fatal(Object o)              { if (t(4,o,null)) h.fatal(o);     } 
91     public void fatal(Object o, Throwable t) { if (t(4,o,t))    h.fatal(o,t);   } 
92     public boolean isDebugEnabled() { return log4j ? h.isDebugEnabled() : false;} 
93     public boolean isInfoEnabled()  { return log4j ? h.isInfoEnabled()  : true; } 
94     public Object getLog4jLogger()  { return log4j ? h.getLog4jLogger() : null; } 
95    
96    
97     /** 
98      * Tests if log4j is available.  If not, logs to backup OutputStream (if 
99      * backup != null). 
100     */ 
101    private final boolean t(int level, Object o, Throwable t) { 
102      if ( log4j ) { 
103        return true; 
104      } else { 
105        if ( backup != null ) { 
106          String s = "";  // log4j allows null 
107          if ( o != null ) { 
108            try { 
109              s = (String) o; 
110            } catch ( ClassCastException cce ) { 
111              s = o.toString(); 
112            } 
113          } 
114          int len = s.length() + TIMESTAMP_LENGTH + 9; 
115          String timestamp = DF.format( new Date() ); 
116          StringBuffer buf = new StringBuffer( len ); 
117          buf.append( timestamp ); 
118          buf.append( ' ' ); 
119          buf.append( LEVELS[ level ] ); 
120          buf.append( ' ' ); 
121          buf.append( s ); 
122          buf.append( LINE_SEPARATOR ); 
123          s = buf.toString(); 
124          byte[] logBytes = s.getBytes(); 
125          try { 
126            if ( t == null ) { 
127              backup.write( logBytes ); 
128            } else { 
129              synchronized( backup ) { 
130                backup.write( logBytes ); 
131                if ( t != null ) { 
132                  if ( wrappingPrintStream == null ) { 
133                    wrappingPrintStream = new PrintStream( backup, false ); 
134                  } 
135                  t.printStackTrace( wrappingPrintStream ); 
136                  wrappingPrintStream.flush(); 
137                } 
138              } 
139            } 
140            backup.flush();   // J2RE 1.5.0 IBM J9 2.3 Linux x86-32 needs this. 
141          } catch ( IOException ioe ) { 
142            throw new RuntimeException( ioe.toString() ); 
143          } 
144        } 
145        return false; 
146      } 
147    } 
148   
149    /** 
150     * Set file to log to if log4j is not available. 
151     * @param f 
152     * @throws IOException 
153     */ 
154    public static void setBackupLogFile( String f ) 
155          throws IOException { 
156      if ( !log4j ) { 
157        OutputStream out = new FileOutputStream( f, true ); 
158        out = new BufferedOutputStream( out ); 
159        setBackupStream( out ); 
160      } 
161    } 
162   
163    /** 
164     * Set PrintStream to log to if log4j is not available.  Set to null to 
165     * disable.  Default value is System.out. 
166     * 
167     * @param os 
168     */ 
169    public static void setBackupStream( OutputStream os ) { 
170      // synchronize on the old backup - don't want to pull the rug out from 
171      // under him if he's working on a big stacktrace or something like that. 
172      if ( backup != null ) { 
173        synchronized( backup ) { 
174          wrappingPrintStream = null; 
175          backup = os; 
176        } 
177      } 
178    } 
179   
180    /** 
181     * Get the PrintStream we're logging to if log4j is not available. 
182     */ 
183    public static OutputStream getBackupStream() { return backup; } 
184   
185  } 
186