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 730039 2008-12-30 03:53:19Z byron $
43   * @since 1.5
44   */
45  public class AvalonLogChute implements LogChute
46  {
47      public static final String AVALON_LOGGER = "runtime.log.logsystem.avalon.logger";
48   
49      public static final String AVALON_LOGGER_FORMAT = "runtime.log.logsystem.avalon.format";
50      
51      public static final String AVALON_LOGGER_LEVEL = "runtime.log.logsystem.avalon.level";
52  
53      private Logger logger = null;
54      private RuntimeServices rsvc = null;
55      
56      private static final Map logLevels = new HashMap();
57      
58      static
59      {
60          logLevels.put("trace", Priority.DEBUG);
61          logLevels.put("debug", Priority.DEBUG);
62          logLevels.put("info", Priority.INFO);
63          logLevels.put("warn", Priority.WARN);
64          logLevels.put("error", Priority.ERROR);
65      }
66  
67      /**
68       * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices)
69       */
70      public void init(RuntimeServices rs) throws Exception
71      {
72          this.rsvc = rs;
73  
74          // if a logger is specified, we will use this instead of the default
75          String name = (String)rsvc.getProperty(AVALON_LOGGER);
76          if (name != null)
77          {
78              this.logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
79          }
80          else
81          {
82              // use the toString() of RuntimeServices to make a unique logger
83              logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString());
84  
85              // if we have a file property, use it to create a FileTarget
86              String file = (String)rsvc.getProperty(RuntimeConstants.RUNTIME_LOG);
87              if (StringUtils.isNotEmpty(file))
88              {
89                  initTarget(file, rsvc);
90              }
91          }
92      }
93  
94      // creates a file target using the specified file name
95      private void initTarget(final String file, final RuntimeServices rsvc) throws Exception
96      {
97          try
98          {
99              String format = null;
100             Priority level = null;
101             if (rsvc != null)
102             {
103                 format = rsvc.getString(AVALON_LOGGER_FORMAT, "%{time} %{message}\\n%{throwable}");
104                 level = (Priority) logLevels.get(rsvc.getString(AVALON_LOGGER_LEVEL, "warn"));
105             }
106 
107             VelocityFormatter vf = new VelocityFormatter(format);
108 
109             // make the target and keep the default behavior of not appending
110             FileTarget target = new FileTarget(new File(file), false, vf);
111 
112             logger.setPriority(level);
113             logger.setLogTargets(new LogTarget[] { target });
114             log(DEBUG_ID, "AvalonLogChute initialized using file '"+file+'\'');
115         }
116         catch (IOException ioe)
117         {
118             rsvc.getLog().error("Unable to create log file for AvalonLogChute", ioe);
119             throw new Exception("Error configuring AvalonLogChute : " + ioe);
120         }
121     }
122 
123     /**
124      * @param file
125      * @throws Exception
126      * @deprecated This method should not be used. It is here only to provide
127      *             backwards compatibility for the deprecated AvalonLogSystem
128      *             class, in case anyone used it and this method directly.
129      */
130     public void init(String file) throws Exception
131     {
132         logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString());
133         initTarget(file, null);
134         // nag the theoretical user
135         log(DEBUG_ID, "You shouldn't be using the init(String file) method!");
136     }
137 
138     /**
139      *  logs messages
140      *
141      *  @param level severity level
142      *  @param message complete error message
143      */
144     public void log(int level, String message)
145     {
146         /*
147          * based on level, call the right logger method
148          * and prefix with the appropos prefix
149          */
150         switch (level)
151         {
152             case WARN_ID:
153                 logger.warn(WARN_PREFIX + message );
154                 break;
155             case INFO_ID:
156                 logger.info(INFO_PREFIX + message);
157                 break;
158             case DEBUG_ID:
159                 logger.debug(DEBUG_PREFIX + message);
160                 break;
161             case TRACE_ID:
162                 logger.debug(TRACE_PREFIX + message);
163                 break;
164             case ERROR_ID:
165                 logger.error(ERROR_PREFIX + message);
166                 break;
167             default:
168                 logger.info(message);
169                 break;
170         }
171     }
172 
173     /**
174      *  logs messages and error
175      *
176      *  @param level severity level
177      *  @param message complete error message
178      * @param t
179      */
180     public void log(int level, String message, Throwable t)
181     {
182         switch (level)
183         {
184             case WARN_ID:
185                 logger.warn(WARN_PREFIX + message, t);
186                 break;
187             case INFO_ID:
188                 logger.info(INFO_PREFIX + message, t);
189                 break;
190             case DEBUG_ID:
191                 logger.debug(DEBUG_PREFIX + message, t);
192                 break;
193             case TRACE_ID:
194                 logger.debug(TRACE_PREFIX + message, t);
195                 break;
196             case ERROR_ID:
197                 logger.error(ERROR_PREFIX + message, t);
198                 break;
199             default:
200                 logger.info(message, t);
201                 break;
202         }
203     }
204 
205     /**
206      * Checks to see whether the specified level is enabled.
207      * @param level
208      * @return True if the specified level is enabled.
209      */
210     public boolean isLevelEnabled(int level)
211     {
212         switch (level)
213         {
214             // For Avalon, no Trace exists. Log at debug level.
215             case TRACE_ID:
216             case DEBUG_ID:
217                 return logger.isDebugEnabled();
218             case INFO_ID:
219                 return logger.isInfoEnabled();
220             case WARN_ID:
221                 return logger.isWarnEnabled();
222             case ERROR_ID:
223                 return logger.isErrorEnabled();
224             default:
225                 return true;
226         }
227     }
228 
229     /**
230      * Also do a shutdown if the object is destroy()'d.
231      * @throws Throwable
232      */
233     protected void finalize() throws Throwable
234     {
235         shutdown();
236     }
237 
238     /** Close all destinations*/
239     public void shutdown()
240     {
241         logger.unsetLogTargets();
242     }
243 
244 }