001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.juli;
019:
020: import java.io.File;
021: import java.io.FileWriter;
022: import java.io.PrintWriter;
023: import java.sql.Timestamp;
024: import java.util.logging.ErrorManager;
025: import java.util.logging.Filter;
026: import java.util.logging.Formatter;
027: import java.util.logging.Handler;
028: import java.util.logging.Level;
029: import java.util.logging.LogManager;
030: import java.util.logging.LogRecord;
031: import java.util.logging.SimpleFormatter;
032:
033: /**
034: * Implementation of <b>Handler</b> that appends log messages to a file
035: * named {prefix}.{date}.{suffix} in a configured directory, with an
036: * optional preceding timestamp.
037: *
038: * @version $Revision: 483782 $ $Date: 2006-12-08 03:24:30 +0100 (ven., 08 déc. 2006) $
039: */
040:
041: public class FileHandler extends Handler {
042:
043: // ------------------------------------------------------------ Constructor
044:
045: public FileHandler() {
046: this (null, null, null);
047: }
048:
049: public FileHandler(String directory, String prefix, String suffix) {
050: this .directory = directory;
051: this .prefix = prefix;
052: this .suffix = suffix;
053: configure();
054: open();
055: }
056:
057: // ----------------------------------------------------- Instance Variables
058:
059: /**
060: * The as-of date for the currently open log file, or a zero-length
061: * string if there is no open log file.
062: */
063: private String date = "";
064:
065: /**
066: * The directory in which log files are created.
067: */
068: private String directory = null;
069:
070: /**
071: * The prefix that is added to log file filenames.
072: */
073: private String prefix = null;
074:
075: /**
076: * The suffix that is added to log file filenames.
077: */
078: private String suffix = null;
079:
080: /**
081: * The PrintWriter to which we are currently logging, if any.
082: */
083: private PrintWriter writer = null;
084:
085: // --------------------------------------------------------- Public Methods
086:
087: /**
088: * Format and publish a <tt>LogRecord</tt>.
089: *
090: * @param record description of the log event
091: */
092: public void publish(LogRecord record) {
093:
094: if (!isLoggable(record)) {
095: return;
096: }
097:
098: // Construct the timestamp we will use, if requested
099: Timestamp ts = new Timestamp(System.currentTimeMillis());
100: String tsString = ts.toString().substring(0, 19);
101: String tsDate = tsString.substring(0, 10);
102:
103: // If the date has changed, switch log files
104: if (!date.equals(tsDate)) {
105: synchronized (this ) {
106: if (!date.equals(tsDate)) {
107: close();
108: date = tsDate;
109: open();
110: }
111: }
112: }
113:
114: String result = null;
115: try {
116: result = getFormatter().format(record);
117: } catch (Exception e) {
118: reportError(null, e, ErrorManager.FORMAT_FAILURE);
119: return;
120: }
121:
122: try {
123: writer.write(result);
124: writer.flush();
125: } catch (Exception e) {
126: reportError(null, e, ErrorManager.WRITE_FAILURE);
127: return;
128: }
129:
130: }
131:
132: // -------------------------------------------------------- Private Methods
133:
134: /**
135: * Close the currently open log file (if any).
136: */
137: public void close() {
138:
139: try {
140: if (writer == null)
141: return;
142: writer.write(getFormatter().getTail(this ));
143: writer.flush();
144: writer.close();
145: writer = null;
146: date = "";
147: } catch (Exception e) {
148: reportError(null, e, ErrorManager.CLOSE_FAILURE);
149: }
150:
151: }
152:
153: /**
154: * Flush the writer.
155: */
156: public void flush() {
157:
158: try {
159: writer.flush();
160: } catch (Exception e) {
161: reportError(null, e, ErrorManager.FLUSH_FAILURE);
162: }
163:
164: }
165:
166: /**
167: * Configure from <code>LogManager</code> properties.
168: */
169: private void configure() {
170:
171: Timestamp ts = new Timestamp(System.currentTimeMillis());
172: String tsString = ts.toString().substring(0, 19);
173: date = tsString.substring(0, 10);
174:
175: String className = FileHandler.class.getName();
176:
177: ClassLoader cl = Thread.currentThread().getContextClassLoader();
178:
179: // Retrieve configuration of logging file name
180: if (directory == null)
181: directory = getProperty(className + ".directory", "logs");
182: if (prefix == null)
183: prefix = getProperty(className + ".prefix", "juli.");
184: if (suffix == null)
185: suffix = getProperty(className + ".suffix", ".log");
186:
187: // Get logging level for the handler
188: setLevel(Level.parse(getProperty(className + ".level", ""
189: + Level.ALL)));
190:
191: // Get filter configuration
192: String filterName = getProperty(className + ".filter", null);
193: if (filterName != null) {
194: try {
195: setFilter((Filter) cl.loadClass(filterName)
196: .newInstance());
197: } catch (Exception e) {
198: // Ignore
199: }
200: }
201:
202: // Set formatter
203: String formatterName = getProperty(className + ".formatter",
204: null);
205: if (formatterName != null) {
206: try {
207: setFormatter((Formatter) cl.loadClass(formatterName)
208: .newInstance());
209: } catch (Exception e) {
210: // Ignore
211: }
212: } else {
213: setFormatter(new SimpleFormatter());
214: }
215:
216: // Set error manager
217: setErrorManager(new ErrorManager());
218:
219: }
220:
221: private String getProperty(String name, String defaultValue) {
222: String value = LogManager.getLogManager().getProperty(name);
223: if (value == null) {
224: value = defaultValue;
225: } else {
226: value = value.trim();
227: }
228: return value;
229: }
230:
231: /**
232: * Open the new log file for the date specified by <code>date</code>.
233: */
234: private void open() {
235:
236: // Create the directory if necessary
237: File dir = new File(directory);
238: dir.mkdirs();
239:
240: // Open the current log file
241: try {
242: String pathname = dir.getAbsolutePath() + File.separator
243: + prefix + date + suffix;
244: writer = new PrintWriter(new FileWriter(pathname, true),
245: true);
246: writer.write(getFormatter().getHead(this ));
247: } catch (Exception e) {
248: reportError(null, e, ErrorManager.OPEN_FAILURE);
249: writer = null;
250: }
251:
252: }
253:
254: }
|