View Javadoc

1   package org.apache.velocity.runtime.log;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.apache.log.Hierarchy;
29  import org.apache.log.LogTarget;
30  import org.apache.log.Logger;
31  import org.apache.log.Priority;
32  import org.apache.log.output.io.FileTarget;
33  import org.apache.velocity.runtime.RuntimeConstants;
34  import org.apache.velocity.runtime.RuntimeServices;
35  
36  /**
37   * Implementation of a Avalon logger.
38   *
39   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
40   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
41   * @author <a href="mailto:nbubna@apache.org">Nathan Bubna</a>
42   * @version $Id: AvalonLogChute.java 522566 2007-03-26 16:42:00Z nbubna $
43   */
44  public class AvalonLogChute implements LogChute
45  {
46      public static final String AVALON_LOGGER = "runtime.log.logsystem.avalon.logger";
47   
48      public static final String AVALON_LOGGER_FORMAT = "runtime.log.logsystem.avalon.format";
49      
50      public static final String AVALON_LOGGER_LEVEL = "runtime.log.logsystem.avalon.level";
51  
52      private Logger logger = null;
53      private RuntimeServices rsvc = null;
54      
55      private static final Map logLevels = new HashMap();
56      
57      static
58      {
59          logLevels.put("trace", Priority.DEBUG);
60          logLevels.put("debug", Priority.DEBUG);
61          logLevels.put("info", Priority.INFO);
62          logLevels.put("warn", Priority.WARN);
63          logLevels.put("error", Priority.ERROR);
64      }
65  
66      /**
67       * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices)
68       */
69      public void init(RuntimeServices rs) throws Exception
70      {
71          this.rsvc = rs;
72  
73          // if a logger is specified, we will use this instead of the default
74          String name = (String)rsvc.getProperty(AVALON_LOGGER);
75          if (name != null)
76          {
77              this.logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
78          }
79          else
80          {
81              // use the toString() of RuntimeServices to make a unique logger
82              logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString());
83  
84              // if we have a file property, use it to create a FileTarget
85              String file = (String)rsvc.getProperty(RuntimeConstants.RUNTIME_LOG);
86              if (StringUtils.isNotEmpty(file))
87              {
88                  initTarget(file, rsvc);
89              }
90          }
91      }
92  
93      // creates a file target using the specified file name
94      private void initTarget(final String file, final RuntimeServices rsvc) throws Exception
95      {
96          try
97          {
98              String format = null;
99              Priority level = null;
100             if (rsvc != null)
101             {
102                 format = rsvc.getString(AVALON_LOGGER_FORMAT, "%{time} %{message}\\n%{throwable}");
103                 level = (Priority) logLevels.get(rsvc.getString(AVALON_LOGGER_LEVEL, "warn"));
104             }
105 
106             VelocityFormatter vf = new VelocityFormatter(format);
107 
108             // make the target and keep the default behavior of not appending
109             FileTarget target = new FileTarget(new File(file), false, vf);
110 
111             logger.setPriority(level);
112             logger.setLogTargets(new LogTarget[] { target });
113             log(DEBUG_ID, "AvalonLogChute initialized using file '"+file+'\'');
114         }
115         catch (IOException ioe)
116         {
117             rsvc.getLog().warn("Unable to create log file for AvalonLogChute", ioe);
118             throw new Exception("Error configuring AvalonLogChute : " + ioe);
119         }
120     }
121 
122     /**
123      * @param file
124      * @throws Exception
125      * @deprecated This method should not be used. It is here only to provide
126      *             backwards compatibility for the deprecated AvalonLogSystem
127      *             class, in case anyone used it and this method directly.
128      */
129     public void init(String file) throws Exception
130     {
131         logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString());
132         initTarget(file, null);
133         // nag the theoretical user
134         log(WARN_ID, "You shouldn't be using the init(String file) method!");
135     }
136 
137     /**
138      *  logs messages
139      *
140      *  @param level severity level
141      *  @param message complete error message
142      */
143     public void log(int level, String message)
144     {
145         /*
146          * based on level, call the right logger method
147          * and prefix with the appropos prefix
148          */
149         switch (level)
150         {
151             case WARN_ID:
152                 logger.warn(WARN_PREFIX + message );
153                 break;
154             case INFO_ID:
155                 logger.info(INFO_PREFIX + message);
156                 break;
157             case DEBUG_ID:
158                 logger.debug(DEBUG_PREFIX + message);
159                 break;
160             case TRACE_ID:
161                 logger.debug(TRACE_PREFIX + message);
162                 break;
163             case ERROR_ID:
164                 logger.error(ERROR_PREFIX + message);
165                 break;
166             default:
167                 logger.info(message);
168                 break;
169         }
170     }
171 
172     /**
173      *  logs messages and error
174      *
175      *  @param level severity level
176      *  @param message complete error message
177      * @param t
178      */
179     public void log(int level, String message, Throwable t)
180     {
181         switch (level)
182         {
183             case WARN_ID:
184                 logger.warn(WARN_PREFIX + message, t);
185                 break;
186             case INFO_ID:
187                 logger.info(INFO_PREFIX + message, t);
188                 break;
189             case DEBUG_ID:
190                 logger.debug(DEBUG_PREFIX + message, t);
191                 break;
192             case TRACE_ID:
193                 logger.debug(TRACE_PREFIX + message, t);
194                 break;
195             case ERROR_ID:
196                 logger.error(ERROR_PREFIX + message, t);
197                 break;
198             default:
199                 logger.info(message, t);
200                 break;
201         }
202     }
203 
204     /**
205      * Checks to see whether the specified level is enabled.
206      * @param level
207      * @return True if the specified level is enabled.
208      */
209     public boolean isLevelEnabled(int level)
210     {
211         switch (level)
212         {
213             // For Avalon, no Trace exists. Log at debug level.
214             case TRACE_ID:
215             case DEBUG_ID:
216                 return logger.isDebugEnabled();
217             case INFO_ID:
218                 return logger.isInfoEnabled();
219             case WARN_ID:
220                 return logger.isWarnEnabled();
221             case ERROR_ID:
222                 return logger.isErrorEnabled();
223             default:
224                 return true;
225         }
226     }
227 
228     /**
229      * Also do a shutdown if the object is destroy()'d.
230      * @throws Throwable
231      */
232     protected void finalize() throws Throwable
233     {
234         shutdown();
235     }
236 
237     /** Close all destinations*/
238     public void shutdown()
239     {
240         logger.unsetLogTargets();
241     }
242 
243 }