View Javadoc

1   // ========================================================================
2   // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses.
12  // ========================================================================
13  
14  package org.eclipse.jetty.util.log;
15  
16  import java.lang.reflect.Method;
17  import java.security.AccessController;
18  import java.security.PrivilegedAction;
19  
20  import org.eclipse.jetty.util.Loader;
21  
22  /**
23   * Logging.
24   * This class provides a static logging interface.  If an instance of the
25   * org.slf4j.Logger class is found on the classpath, the static log methods
26   * are directed to a slf4j logger for "org.eclipse.log".   Otherwise the logs
27   * are directed to stderr.
28   * <p>
29   * The "org.eclipse.jetty.util.log.class" system property can be used
30   * to select a specific logging implementation.
31   * <p>
32   * If the system property org.eclipse.jetty.util.log.IGNORED is set,
33   * then ignored exceptions are logged in detail.
34   *
35   * @see StdErrLog
36   * @see Slf4jLog
37   */
38  public class Log
39  {
40      public final static String EXCEPTION= "EXCEPTION ";
41      public final static String IGNORED= "IGNORED";
42  
43      public static String __logClass;
44      public static boolean __ignored;
45  
46      static
47      {
48          AccessController.doPrivileged(new PrivilegedAction<Object>()
49          {
50              public Object run()
51              {
52                  __logClass = System.getProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.Slf4jLog");
53                  __ignored = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.IGNORED", "false"));
54                  return null;
55              }
56          });
57      }
58  
59      private static Logger __log;
60      private static boolean __initialized;
61  
62      public static boolean initialized()
63      {
64          if (__log != null)
65              return true;
66  
67          synchronized (Log.class)
68          {
69              if (__initialized)
70                  return __log != null;
71              __initialized = true;
72          }
73  
74          try
75          {
76              Class log_class = Loader.loadClass(Log.class, __logClass);
77              if (__log == null || !__log.getClass().equals(log_class))
78              {
79                  __log = (Logger)log_class.newInstance();
80                  __log.info("Logging to {} via {}", __log, log_class.getName());
81              }
82          }
83          catch(NoClassDefFoundError e)
84          {
85              initStandardLogging(e);
86          }
87          catch(Exception e)
88          {
89              initStandardLogging(e);
90          }
91  
92          return __log != null;
93      }
94  
95      private static void initStandardLogging(Throwable e)
96      {
97          Class log_class;
98          if(e != null && __ignored)
99              e.printStackTrace();
100         if (__log == null)
101         {
102             log_class = StdErrLog.class;
103             __log = new StdErrLog();
104             __log.info("Logging to {} via {}", __log, log_class.getName());
105         }
106     }
107 
108     public static void setLog(Logger log)
109     {
110         Log.__log = log;
111     }
112 
113     public static Logger getLog()
114     {
115         initialized();
116         return __log;
117     }
118 
119 
120     /**
121      * Set Log to parent Logger.
122      * <p>
123      * If there is a different Log class available from a parent classloader,
124      * call {@link #getLogger(String)} on it and construct a {@link LoggerLog} instance
125      * as this Log's Logger, so that logging is delegated to the parent Log.
126      * <p>
127      * This should be used if a webapp is using Log, but wishes the logging to be
128      * directed to the containers log.
129      * <p>
130      * If there is not parent Log, then this call is equivalent to<pre>
131      *   Log.setLog(Log.getLogger(name));
132      * </pre>
133      * @param name Logger name
134      */
135     public static void setLogToParent(String name)
136     {
137         ClassLoader loader = Log.class.getClassLoader();
138         if (loader.getParent()!=null)
139         {
140             try
141             {
142                 Class<?> uberlog = loader.getParent().loadClass("org.eclipse.jetty.util.log.Log");
143                 Method getLogger = uberlog.getMethod("getLogger", new Class[]{String.class});
144                 Object logger = getLogger.invoke(null,name);
145                 setLog(new LoggerLog(logger));
146             }
147             catch (Exception e)
148             {
149                 e.printStackTrace();
150             }
151         }
152         else
153         {
154             setLog(getLogger(name));
155         }
156     }
157 
158     public static void debug(Throwable th)
159     {
160         if (!isDebugEnabled())
161             return;
162         __log.debug(EXCEPTION, th);
163     }
164 
165     public static void debug(String msg)
166     {
167         if (!initialized())
168             return;
169         __log.debug(msg);
170     }
171 
172     public static void debug(String msg, Object arg)
173     {
174         if (!initialized())
175             return;
176         __log.debug(msg, arg);
177     }
178 
179     public static void debug(String msg, Object arg0, Object arg1)
180     {
181         if (!initialized())
182             return;
183         __log.debug(msg, arg0, arg1);
184     }
185 
186     /**
187      * Ignore an exception unless trace is enabled.
188      * This works around the problem that log4j does not support the trace level.
189      * @param thrown the Throwable to ignore
190      */
191     public static void ignore(Throwable thrown)
192     {
193         if (!initialized())
194             return;
195         if (__ignored)
196         {
197             __log.warn(IGNORED, thrown);
198         }
199     }
200 
201     public static void info(String msg)
202     {
203         if (!initialized())
204             return;
205         __log.info(msg);
206     }
207 
208     public static void info(String msg, Object arg)
209     {
210         if (!initialized())
211             return;
212         __log.info(msg, arg);
213     }
214 
215     public static void info(String msg, Object arg0, Object arg1)
216     {
217         if (!initialized())
218             return;
219         __log.info(msg, arg0, arg1);
220     }
221 
222     public static boolean isDebugEnabled()
223     {
224         if (!initialized())
225             return false;
226         return __log.isDebugEnabled();
227     }
228 
229     public static void warn(String msg)
230     {
231         if (!initialized())
232             return;
233         __log.warn(msg);
234     }
235 
236     public static void warn(String msg, Object arg)
237     {
238         if (!initialized())
239             return;
240         __log.warn(msg, arg);
241     }
242 
243     public static void warn(String msg, Object arg0, Object arg1)
244     {
245         if (!initialized())
246             return;
247         __log.warn(msg, arg0, arg1);
248     }
249 
250     public static void warn(String msg, Throwable th)
251     {
252         if (!initialized())
253             return;
254         __log.warn(msg, th);
255     }
256 
257     public static void warn(Throwable th)
258     {
259         if (!initialized())
260             return;
261         __log.warn(EXCEPTION, th);
262     }
263 
264     /**
265      * Obtain a named Logger or the default Logger if null is passed.
266      * @param name the Logger name
267      * @return the Logger with the given name
268      */
269     public static Logger getLogger(String name)
270     {
271         if (!initialized())
272             return null;
273 
274         return name == null ? __log : __log.getLogger(name);
275     }
276 }