001: package org.jacorb.config;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import org.apache.avalon.framework.logger.Logger;
024: import org.apache.avalon.framework.logger.LogKitLogger;
025: import org.apache.avalon.framework.configuration.ConfigurationException;
026:
027: import org.apache.log.*;
028: import org.apache.log.format.*;
029: import org.apache.log.output.io.*;
030: import org.apache.log.output.io.rotate.*;
031:
032: import java.util.*;
033: import java.io.*;
034:
035: /**
036: * JacORB logger factory that creates named Avalon loggers with logkit
037: * as the underlying log mechanism. <BR> The semantics here is that any
038: * names logger retrieved using the logkit naming conventions for
039: * nested loggers will inherit its parent loggers log target e.g., a
040: * logger retrieved for <code>jacorb.naming</code>
041: * inherits the root logger's target (ie. <code>System.err</code>, or
042: * a file.
043: * <P>
044: * Log priorities for new loggers are also inherited from the parent
045: * logger. If no parent logger is available the priority defaults to the
046: * value of this factory's <code>defaultPriority</code> field. The
047: * priorities for loggers can be set via
048: * configuration properties that have the same name as the requested
049: * logger, plus a suffix of <code>.log.verbosity</code>.
050: * <P>
051: * The priority for all loggers that do not have a specific <name>.log.verbosity
052: * prop defined will be set to the value of the jacorb.log.default.verbosity
053: * property, if it's set. If not, the default is 0.
054: *
055: * @author Gerald Brose
056: * @version $Id: LogKitLoggerFactory.java,v 1.6 2006/07/17 09:05:30 alphonse.bendt Exp $
057: * @since JacORB 2.0 beta 3
058: */
059:
060: public class LogKitLoggerFactory implements LoggerFactory {
061: private final static String DEFAULT_LOG_PATTERN = "[%.20{category}] %.7{priority} : %{message}\\n%{throwable}";
062:
063: private final static String name = "logkit";
064: private PatternFormatter logFormatter = null;
065:
066: /** default priority for loggers created with this factory */
067: private int defaultPriority = 0;
068:
069: /** cache of created loggers */
070: private final Map namedLoggers = new HashMap();
071:
072: /** append to a log file or overwrite ?*/
073: private boolean append = false;
074:
075: /** the writer for console logging */
076: private Writer consoleWriter;
077:
078: /** this target for console logging */
079: private LogTarget consoleTarget;
080:
081: /** The default log file */
082: private LogTarget defaultTarget = null;
083:
084: private Configuration configuration = null;
085:
086: public void configure(
087: org.apache.avalon.framework.configuration.Configuration configuration)
088: throws org.apache.avalon.framework.configuration.ConfigurationException {
089: this .configuration = (Configuration) configuration;
090:
091: defaultPriority = configuration.getAttributeAsInteger(
092: "jacorb.log.default.verbosity", 0);
093:
094: append = configuration.getAttribute("jacorb.logfile.append",
095: "off").equals("on");
096:
097: logFormatter = new PatternFormatter(configuration.getAttribute(
098: "jacorb.log.default.log_pattern", DEFAULT_LOG_PATTERN));
099: switch (defaultPriority) {
100: case 0:
101: case 1:
102: case 2:
103: case 3:
104: case 4:
105: break;
106: default:
107: throw new ConfigurationException(
108: "'"
109: + defaultPriority
110: + "' is an illegal"
111: + " value for the property jacorb.log.default.verbosity. Valid values are [0-4]");
112: }
113: consoleWriter = new OutputStreamWriter(System.err);
114: consoleTarget = new WriterTarget(consoleWriter, logFormatter);
115: }
116:
117: /**
118: * @return the name of the actual, underlying logging mechanism,
119: * here "logkit"
120: */
121:
122: public final String getLoggingBackendName() {
123: return name;
124: }
125:
126: /**
127: * @param name the name of the logger, which also functions
128: * as a log category
129: * @return a Logger for a given name
130: */
131:
132: public Logger getNamedLogger(String name) {
133: return getNamedLogger(name, null);
134: }
135:
136: /**
137: * @param name - the name of the logger, which also functions
138: * as a log category
139: * @return a root console logger for a logger name hierarchy
140: */
141:
142: public Logger getNamedRootLogger(String name) {
143: return getNamedLogger(name, consoleTarget);
144: }
145:
146: /**
147: * @param name - the name of the logger, which also functions
148: * as a log category
149: * @param logFileName - the name of the file to log to
150: * @param maxLogSize - maximum size of the log file. When this size is reached
151: * the log file will be rotated and a new log file created. A value of 0
152: * means the log file size is unlimited.
153: *
154: * @return the new logger.
155: */
156:
157: public Logger getNamedLogger(String name, String logFileName,
158: long maxLogSize) throws IOException {
159: if (name == null)
160: throw new IllegalArgumentException(
161: "Log file name must not be null!");
162:
163: FileOutputStream logStream = new FileOutputStream(logFileName,
164: append);
165:
166: LogTarget target = null;
167: if (maxLogSize == 0) {
168: // no log file rotation
169: Writer logWriter = new OutputStreamWriter(logStream);
170: target = new WriterTarget(logWriter, logFormatter);
171: } else {
172: // use log file rotation
173: target = new RotatingFileTarget(append, logFormatter,
174: new RotateStrategyBySize(maxLogSize * 1000),
175: new RevolvingFileStrategy(new File(logFileName),
176: 10000));
177: }
178: return getNamedLogger(name, target);
179: }
180:
181: /**
182: * @param name the name of the logger, which also functions
183: * as a log category
184: * @param target the log target for the new logger. If null, the new logger
185: * will log to System.err
186: * @return the logger
187: */
188: private Logger getNamedLogger(String name, LogTarget target) {
189: Object o = namedLoggers.get(name);
190:
191: if (o != null) {
192: return (Logger) o;
193: }
194:
195: org.apache.log.Logger logger = Hierarchy.getDefaultHierarchy()
196: .getLoggerFor(name);
197:
198: int priority = getPriorityForNamedLogger(name);
199:
200: logger.setPriority(intToPriority(priority));
201:
202: if (target != null) {
203: // LogTarget was provided by caller
204: logger.setLogTargets(new LogTarget[] { target });
205: } else {
206: // use default LogTarget
207: if (defaultTarget == null) {
208: logger.setLogTargets(new LogTarget[] { consoleTarget });
209: } else {
210: logger.setLogTargets(new LogTarget[] { defaultTarget });
211: }
212: }
213:
214: Logger result = new LogKitLogger(logger);
215:
216: namedLoggers.put(name, result);
217:
218: return result;
219: }
220:
221: /**
222: * return the priority for a named logger. if no priority is
223: * specified for the requested name the priority of the first
224: * matching parent logger is returned.
225: * If there's no parent logger the factory default is returned.
226: *
227: * @param name the name of a logger
228: * @return the priority for that logger
229: */
230: private int getPriorityForNamedLogger(String name) {
231: String prefix = name;
232:
233: while (!prefix.equals("")) {
234: try {
235: int priorityForLogger = configuration
236: .getAttributeAsInteger(prefix
237: + ".log.verbosity");
238: if (priorityForLogger > 4) {
239: priorityForLogger = 4;
240: } else if (priorityForLogger < 0) {
241: priorityForLogger = 0;
242: }
243: return priorityForLogger;
244: } catch (ConfigurationException ce) {
245: }
246:
247: if (prefix.lastIndexOf(".") >= 0) {
248: prefix = prefix.substring(0, prefix.lastIndexOf("."));
249: } else {
250: prefix = "";
251: }
252: }
253:
254: // nothing found, return default
255: return defaultPriority;
256: }
257:
258: /**
259: * <code>intToPriority</code> returns the priority level for a given integer.
260: *
261: * @param priority an <code>int</code> value
262: * @return an <code>org.apache.log.Priority</code> value
263: */
264: private static org.apache.log.Priority intToPriority(int priority) {
265: switch (priority) {
266: case 4:
267: return org.apache.log.Priority.DEBUG;
268: case 3:
269: return org.apache.log.Priority.INFO;
270: case 2:
271: return org.apache.log.Priority.WARN;
272: case 1:
273: return org.apache.log.Priority.ERROR;
274: case 0:
275: default:
276: return org.apache.log.Priority.FATAL_ERROR;
277: }
278: }
279:
280: public void setDefaultLogFile(String fileName, long maxLogSize)
281: throws java.io.IOException {
282: FileOutputStream logStream = new FileOutputStream(fileName,
283: append);
284:
285: if (maxLogSize == 0) {
286: // no log file rotation
287: Writer logWriter = new OutputStreamWriter(logStream);
288: defaultTarget = new WriterTarget(logWriter, logFormatter);
289: } else {
290: // use log file rotation
291: defaultTarget = new RotatingFileTarget(
292: append,
293: logFormatter,
294: new RotateStrategyBySize(maxLogSize * 1000),
295: new RevolvingFileStrategy(new File(fileName), 10000));
296: }
297: }
298: }
|