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.debug("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.debug("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     static boolean isIgnored()
120     {
121         return __ignored;
122     }
123 
124     /**
125      * Set Log to parent Logger.
126      * <p>
127      * If there is a different Log class available from a parent classloader,
128      * call {@link #getLogger(String)} on it and construct a {@link LoggerLog} instance
129      * as this Log's Logger, so that logging is delegated to the parent Log.
130      * <p>
131      * This should be used if a webapp is using Log, but wishes the logging to be
132      * directed to the containers log.
133      * <p>
134      * If there is not parent Log, then this call is equivalent to<pre>
135      *   Log.setLog(Log.getLogger(name));
136      * </pre>
137      * @param name Logger name
138      */
139     public static void setLogToParent(String name)
140     {
141         ClassLoader loader = Log.class.getClassLoader();
142         if (loader.getParent()!=null)
143         {
144             try
145             {
146                 Class<?> uberlog = loader.getParent().loadClass("org.eclipse.jetty.util.log.Log");
147                 Method getLogger = uberlog.getMethod("getLogger", new Class[]{String.class});
148                 Object logger = getLogger.invoke(null,name);
149                 setLog(new LoggerLog(logger));
150             }
151             catch (Exception e)
152             {
153                 e.printStackTrace();
154             }
155         }
156         else
157         {
158             setLog(getLogger(name));
159         }
160     }
161 
162     public static void debug(Throwable th)
163     {
164         if (!isDebugEnabled())
165             return;
166         __log.debug(EXCEPTION, th);
167     }
168 
169     public static void debug(String msg)
170     {
171         if (!initialized())
172             return;
173         __log.debug(msg);
174     }
175 
176     public static void debug(String msg, Object arg)
177     {
178         if (!initialized())
179             return;
180         __log.debug(msg, arg);
181     }
182 
183     public static void debug(String msg, Object arg0, Object arg1)
184     {
185         if (!initialized())
186             return;
187         __log.debug(msg, arg0, arg1);
188     }
189 
190     /**
191      * Ignore an exception unless trace is enabled.
192      * This works around the problem that log4j does not support the trace level.
193      * @param thrown the Throwable to ignore
194      */
195     public static void ignore(Throwable thrown)
196     {
197         if (!initialized())
198             return;
199         if (__ignored)
200         {
201             __log.warn(IGNORED, thrown);
202         }
203     }
204 
205     public static void info(String msg)
206     {
207         if (!initialized())
208             return;
209         __log.info(msg);
210     }
211 
212     public static void info(String msg, Object arg)
213     {
214         if (!initialized())
215             return;
216         __log.info(msg, arg);
217     }
218 
219     public static void info(String msg, Object arg0, Object arg1)
220     {
221         if (!initialized())
222             return;
223         __log.info(msg, arg0, arg1);
224     }
225 
226     public static boolean isDebugEnabled()
227     {
228         if (!initialized())
229             return false;
230         return __log.isDebugEnabled();
231     }
232 
233     public static void warn(String msg)
234     {
235         if (!initialized())
236             return;
237         __log.warn(msg);
238     }
239 
240     public static void warn(String msg, Object arg)
241     {
242         if (!initialized())
243             return;
244         __log.warn(msg, arg);
245     }
246 
247     public static void warn(String msg, Object arg0, Object arg1)
248     {
249         if (!initialized())
250             return;
251         __log.warn(msg, arg0, arg1);
252     }
253 
254     public static void warn(String msg, Throwable th)
255     {
256         if (!initialized())
257             return;
258         __log.warn(msg, th);
259     }
260 
261     public static void warn(Throwable th)
262     {
263         if (!initialized())
264             return;
265         __log.warn(EXCEPTION, th);
266     }
267 
268     /**
269      * Obtain a named Logger or the default Logger if null is passed.
270      * @param name the Logger name
271      * @return the Logger with the given name
272      */
273     public static Logger getLogger(String name)
274     {
275         if (!initialized())
276             return null;
277 
278         return name == null ? __log : __log.getLogger(name);
279     }
280 }