001: package org.apache.velocity.runtime.log;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.util.HashMap;
025: import java.util.Map;
026:
027: import org.apache.commons.lang.StringUtils;
028: import org.apache.log.Hierarchy;
029: import org.apache.log.LogTarget;
030: import org.apache.log.Logger;
031: import org.apache.log.Priority;
032: import org.apache.log.output.io.FileTarget;
033: import org.apache.velocity.runtime.RuntimeConstants;
034: import org.apache.velocity.runtime.RuntimeServices;
035:
036: /**
037: * Implementation of a Avalon logger.
038: *
039: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
040: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
041: * @author <a href="mailto:nbubna@apache.org">Nathan Bubna</a>
042: * @version $Id: AvalonLogChute.java 463300 2006-10-12 16:15:29Z henning $
043: */
044: public class AvalonLogChute implements LogChute {
045: public static final String AVALON_LOGGER = "runtime.log.logsystem.avalon.logger";
046:
047: public static final String AVALON_LOGGER_FORMAT = "runtime.log.logsystem.avalon.format";
048:
049: public static final String AVALON_LOGGER_LEVEL = "runtime.log.logsystem.avalon.level";
050:
051: private Logger logger = null;
052: private RuntimeServices rsvc = null;
053:
054: private static final Map logLevels = new HashMap();
055:
056: static {
057: logLevels.put("trace", Priority.DEBUG);
058: logLevels.put("debug", Priority.DEBUG);
059: logLevels.put("info", Priority.INFO);
060: logLevels.put("warn", Priority.WARN);
061: logLevels.put("error", Priority.ERROR);
062: }
063:
064: /**
065: * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices)
066: */
067: public void init(RuntimeServices rs) throws Exception {
068: this .rsvc = rs;
069:
070: // if a logger is specified, we will use this instead of the default
071: String name = (String) rsvc.getProperty(AVALON_LOGGER);
072: if (name != null) {
073: this .logger = Hierarchy.getDefaultHierarchy().getLoggerFor(
074: name);
075: } else {
076: // use the toString() of RuntimeServices to make a unique logger
077: logger = Hierarchy.getDefaultHierarchy().getLoggerFor(
078: rsvc.toString());
079:
080: // if we have a file property, use it to create a FileTarget
081: String file = (String) rsvc
082: .getProperty(RuntimeConstants.RUNTIME_LOG);
083: if (StringUtils.isNotEmpty(file)) {
084: initTarget(file, rsvc);
085: }
086: }
087: }
088:
089: // creates a file target using the specified file name
090: private void initTarget(final String file,
091: final RuntimeServices rsvc) throws Exception {
092: try {
093: String format = null;
094: Priority level = null;
095: if (rsvc != null) {
096: format = rsvc.getString(AVALON_LOGGER_FORMAT,
097: "%{time} %{message}\\n%{throwable}");
098: level = (Priority) logLevels.get(rsvc.getString(
099: AVALON_LOGGER_LEVEL, "debug"));
100: }
101:
102: VelocityFormatter vf = new VelocityFormatter(format);
103:
104: // make the target and keep the default behavior of not appending
105: FileTarget target = new FileTarget(new File(file), false,
106: vf);
107:
108: logger.setPriority(level);
109: logger.setLogTargets(new LogTarget[] { target });
110: log(DEBUG_ID, "AvalonLogChute initialized using file '"
111: + file + '\'');
112: } catch (IOException ioe) {
113: rsvc
114: .getLog()
115: .warn(
116: "Unable to create log file for AvalonLogChute",
117: ioe);
118: throw new Exception("Error configuring AvalonLogChute : "
119: + 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: logger = Hierarchy.getDefaultHierarchy().getLoggerFor(
132: rsvc.toString());
133: initTarget(file, null);
134: // nag the theoretical user
135: log(WARN_ID,
136: "You shouldn't be using the init(String file) method!");
137: }
138:
139: /**
140: * logs messages
141: *
142: * @param level severity level
143: * @param message complete error message
144: */
145: public void log(int level, String message) {
146: /*
147: * based on level, call the right logger method
148: * and prefix with the appropos prefix
149: */
150: switch (level) {
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: switch (level) {
181: case WARN_ID:
182: logger.warn(WARN_PREFIX + message, t);
183: break;
184: case INFO_ID:
185: logger.info(INFO_PREFIX + message, t);
186: break;
187: case DEBUG_ID:
188: logger.debug(DEBUG_PREFIX + message, t);
189: break;
190: case TRACE_ID:
191: logger.debug(TRACE_PREFIX + message, t);
192: break;
193: case ERROR_ID:
194: logger.error(ERROR_PREFIX + message, t);
195: break;
196: default:
197: logger.info(message, t);
198: break;
199: }
200: }
201:
202: /**
203: * Checks to see whether the specified level is enabled.
204: * @param level
205: * @return True if the specified level is enabled.
206: */
207: public boolean isLevelEnabled(int level) {
208: switch (level) {
209: // For Avalon, no Trace exists. Log at debug level.
210: case TRACE_ID:
211: case DEBUG_ID:
212: return logger.isDebugEnabled();
213: case INFO_ID:
214: return logger.isInfoEnabled();
215: case WARN_ID:
216: return logger.isWarnEnabled();
217: case ERROR_ID:
218: return logger.isErrorEnabled();
219: default:
220: return true;
221: }
222: }
223:
224: /**
225: * Also do a shutdown if the object is destroy()'d.
226: * @throws Throwable
227: */
228: protected void finalize() throws Throwable {
229: shutdown();
230: }
231:
232: /** Close all destinations*/
233: public void shutdown() {
234: logger.unsetLogTargets();
235: }
236:
237: }
|