001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/framework/log/LoggerService.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.framework.log;
045:
046: // J2EE 1.3
047: import java.io.BufferedOutputStream;
048: import java.io.BufferedWriter;
049: import java.io.File;
050: import java.io.FileOutputStream;
051: import java.io.FileWriter;
052: import java.io.IOException;
053: import java.net.InetAddress;
054: import java.net.UnknownHostException;
055: import java.text.DateFormat;
056: import java.util.Date;
057: import java.util.Enumeration;
058: import java.util.Map;
059: import java.util.Properties;
060:
061: import javax.mail.Session;
062:
063: import org.deegree.framework.jndi.JndiUtils;
064: import org.deegree.framework.mail.EMailMessage;
065: import org.deegree.framework.mail.MailHelper;
066: import org.deegree.framework.mail.MailMessage;
067: import org.deegree.framework.util.BootLogger;
068: import org.deegree.framework.version.Version;
069: import org.deegree.framework.xml.XMLFragment;
070:
071: /**
072: * The Logger is used to log messages to files. This service will use a logging service provided by the application
073: * server or a 3rd party logging service such as Apache Log4J to enable asychronous call of the method log(). The log
074: * server is configured by a set of Properties which are provided to the class init.
075: * <p>
076: * There are some global properties as well: <BR>
077: * <UL>
078: * <LI><B>log.class </B>: the logging class.
079: * <LI><B>log.active </B>: to enable or disabel the logging service
080: * <LI><B>log.mail.active </B>: to activate the email notification
081: * <LI><B>log.mail.to </B>: the mail address
082: * <LI><B>log.mail.session </B>: the mail session used to send mail
083: * </UL>
084: * <P>
085: * Messages are logged using log(). If an error occurs during creation or logging, the message will be written to the
086: * server BootLogger.
087: *
088: * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </A>
089: *
090: * @author last edited by: UID=$Author: apoth $
091: *
092: * @version $Revision: 9349 $, $Date: 2007-12-27 09:12:34 -0800 (Thu, 27 Dec 2007) $
093: *
094: * @see LoggerFactory
095: * @see org.deegree.framework.util.BootLogger
096: */
097: abstract class LoggerService implements ILogger {
098:
099: protected static String defaultChannelName;
100:
101: private static String hostAddress;
102:
103: private static String hostName;
104:
105: private static String mailNotificationAddress;
106:
107: private static String mailSessionName;
108:
109: private static Session mailSession;
110:
111: private static String mailHostName;
112:
113: private static boolean sendMailIsActive;
114:
115: private static DateFormat df;
116:
117: public void init(Properties props) {
118:
119: df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
120: DateFormat.SHORT);
121:
122: try {
123:
124: // fetch all configuration parameters
125: LoggerService.defaultChannelName = props
126: .getProperty("log.channel.name");
127: LoggerService.mailNotificationAddress = props
128: .getProperty("log.mail.to");
129: String mailerActive = props.getProperty("log.mail.active");
130: LoggerService.mailSessionName = props
131: .getProperty("log.mail.session");
132: LoggerService.mailHostName = props
133: .getProperty("log.mail.smtphost");
134:
135: // set defaults if not set
136: if (mailerActive == null
137: || mailerActive.equalsIgnoreCase("false")) {
138: LoggerService.sendMailIsActive = false;
139: }
140: if (defaultChannelName == null) {
141: LoggerService.defaultChannelName = LoggerService.class
142: .getName();
143: }
144: if (mailNotificationAddress == null) {
145: LoggerService.mailNotificationAddress = "UNKNOWN@"
146: + LoggerService.mailHostName;
147: }
148:
149: hostAddress = InetAddress.getLocalHost().getHostAddress();
150: hostName = InetAddress.getLocalHost().getHostName();
151:
152: } catch (UnknownHostException ex) {
153: BootLogger.log("Unable to determine host: "
154: + ex.getMessage());
155: } catch (Exception ex) {
156: ex.printStackTrace();
157: BootLogger.log("Error while initializing "
158: + LoggerService.class.getName() + " : "
159: + ex.getMessage());
160: } finally {
161: BootLogger.logDebug("Using: defaultChannelName="
162: + defaultChannelName + ", mailNotificationAddress="
163: + mailNotificationAddress + ", mailSessionName="
164: + mailSessionName + ", log.mail.active="
165: + LoggerService.sendMailIsActive);
166: }
167: }
168:
169: /**
170: * Create logger instance
171: *
172: */
173: protected LoggerService() {
174: // only callable for the package.
175: }
176:
177: /**
178: * Log error with exception
179: *
180: * @param message
181: * the log message
182: * @param e
183: * the exception to be logged
184: * @param properties
185: * a given Property file in which specific email notification possibilities are saved.
186: */
187: public final void logError(String message, Throwable e,
188: Map properties) {
189: this .logError(message, e);
190: if (sendMailIsActive) {
191: this .sendMail(message, e, properties);
192: }
193: }
194:
195: /**
196: * Log warning message
197: *
198: * @param message
199: * the log message
200: */
201: public abstract void logWarning(String message);
202:
203: /**
204: * Log warning message with exception
205: *
206: * @param message
207: * the log message
208: * @param e
209: * the exception to be logged
210: */
211: public abstract void logWarning(String message, Throwable e);
212:
213: /**
214: * Log info message
215: *
216: * @param message
217: * the log message
218: */
219: public abstract void logInfo(String message);
220:
221: /**
222: * Log info message
223: *
224: * @param message
225: * the log message
226: * @param e
227: * the exception to be logged
228: */
229: public abstract void logInfo(String message, Throwable e);
230:
231: /**
232: * Log debug message
233: *
234: * @param message
235: * the log message
236: */
237: public abstract void logDebug(String message);
238:
239: /**
240: * Log debug message.
241: *
242: * @param message
243: * the log message
244: * @param e
245: * the exception to be logged
246: */
247: public abstract void logDebug(String message, Throwable e);
248:
249: /**
250: * Logs the given text to the specified file if log level is set to <code>LOG_DEBUG</code>.
251: *
252: * @param file
253: * file to log to
254: * @param content
255: * text to be logged
256: */
257: public void logDebugFile(File file, String content) {
258: if (getLevel() == LOG_DEBUG) {
259: logDebug("Writing debug file '" + file.getAbsolutePath()
260: + "'.");
261: BufferedWriter writer = null;
262: try {
263: writer = new BufferedWriter(new FileWriter(file));
264: writer.write(content);
265: } catch (IOException e) {
266: String msg = "Could not write to debug file '"
267: + file.getAbsolutePath() + "'.";
268: logError(msg, e);
269: } finally {
270: if (writer != null) {
271: try {
272: writer.close();
273: } catch (IOException e) {
274: String msg = "Error closing debug file '"
275: + file.getAbsolutePath() + "'.";
276: logError(msg, e);
277: }
278: }
279: }
280: }
281: }
282:
283: /**
284: * Logs the given text to a temporary file (created from specified prefix and suffix) if log level is set to
285: * <code>LOG_DEBUG</code>.
286: *
287: * @see File#createTempFile(String, String)
288: * @param filePrefix
289: * prefix for the temp file name
290: * @param fileSuffix
291: * suffix for the temp file name, can be null (then ".tmp" is used)
292: * @param content
293: * text to be logged
294: */
295: public void logDebugFile(String filePrefix, String fileSuffix,
296: String content) {
297: if (getLevel() == LOG_DEBUG) {
298: try {
299: File tmpFile = File.createTempFile(filePrefix,
300: fileSuffix);
301: logDebugFile(tmpFile, content);
302: } catch (IOException e) {
303: String msg = "Cannot create debug file for prefix '"
304: + filePrefix + "' and suffix '" + fileSuffix
305: + ".";
306: logError(msg, e);
307: }
308: }
309: }
310:
311: /**
312: * Logs the given {@link XMLFragment} to a temporary file (created from specified prefix and suffix ".xml") if log
313: * level is set to <code>LOG_DEBUG</code>.
314: *
315: * @param filePrefix
316: * prefix for the temp file name
317: * @param fragment
318: * XMLFragment to be logged (will be pretty-printed)
319: */
320: public void logDebugXMLFile(String filePrefix, XMLFragment fragment) {
321: if (getLevel() == LOG_DEBUG) {
322: logDebugFile(filePrefix, ".xml", fragment
323: .getAsPrettyString());
324: }
325: }
326:
327: /**
328: * Logs the given binary data to the specified file if log level is set to <code>LOG_DEBUG</code>.
329: *
330: * @param file
331: * file to log to
332: * @param data
333: * binary data to be logged
334: */
335: public void logDebugBinaryFile(File file, byte[] data) {
336: if (getLevel() == LOG_DEBUG) {
337: logDebug("Writing binary debug file '"
338: + file.getAbsolutePath() + "'.");
339: BufferedOutputStream out = null;
340: try {
341: out = new BufferedOutputStream(new FileOutputStream(
342: file));
343: out.write(data);
344: } catch (IOException e) {
345: String msg = "Could not write to debug file '"
346: + file.getAbsolutePath() + "'.";
347: logError(msg, e);
348: } finally {
349: if (out != null) {
350: try {
351: out.close();
352: } catch (IOException e) {
353: String msg = "Error closing debug file '"
354: + file.getAbsolutePath() + "'.";
355: logError(msg, e);
356: }
357: }
358: }
359: }
360: }
361:
362: /**
363: * Logs the given binary data to a temporary file (created from specified prefix and suffix) if log level is set to
364: * <code>LOG_DEBUG</code>.
365: *
366: * @see File#createTempFile(String, String)
367: * @param filePrefix
368: * prefix for the temp file name
369: * @param fileSuffix
370: * suffix for the temp file name, can be null (then ".tmp" is used)
371: * @param data
372: * binary data to be logged
373: */
374: public void logDebugBinaryFile(String filePrefix,
375: String fileSuffix, byte[] data) {
376: if (getLevel() == LOG_DEBUG) {
377: try {
378: File tmpFile = File.createTempFile(filePrefix,
379: fileSuffix);
380: logDebugBinaryFile(tmpFile, data);
381: } catch (IOException e) {
382: String msg = "Cannot create debug file for prefix '"
383: + filePrefix + "' and suffix '" + fileSuffix
384: + ".";
385: logError(msg, e);
386: }
387: }
388: }
389:
390: /**
391: * Sends email with exception string. If mail session or mail notification address is null no email is send.
392: *
393: * @param message
394: * message is in mail subject
395: * @param ex
396: * full exception is displayed in body
397: * @param properties
398: * list of properties listed in body
399: */
400: protected void sendMail(String message, Throwable ex, Map properties) {
401: if (sendMailIsActive && mailSessionName != null
402: && mailNotificationAddress != null) {
403: this .sendMailNotification(message, ex, properties);
404: }
405: }
406:
407: private void sendMailNotification(String message, Throwable ex,
408: Map properties) {
409: MailMessage mail;
410: StringBuffer emailBody = new StringBuffer();
411:
412: emailBody.append("A critical error occured in "
413: + Version.getVersion());
414: emailBody.append(" running on " + hostName + "/" + hostAddress);
415: emailBody.append(" on "
416: + df.format(new Date(System.currentTimeMillis())));
417: emailBody.append("\n\n");
418: if (message != null) {
419: emailBody.append("\n\nThe error message: " + message);
420: }
421: if (properties != null) {
422: emailBody.append("\n\nRequest data:\n--------------\n"
423: + properties.toString());
424: }
425: if (ex != null) {
426: emailBody.append("\n\nException:\n---------\n"
427: + ex.getMessage());
428: emailBody.append("\n\nStack Trace:\n------------\n\n"
429: + ex.toString());
430: }
431: emailBody.append("\n\nSystem Info:\n--------------\n"
432: + getSystemInfo());
433:
434: String subject = "Critical Error:" + Version.getVersion()
435: + " on " + hostName + "/" + hostAddress;
436:
437: mail = new EMailMessage("DO_NOT_REPLY@" + hostName,
438: mailNotificationAddress, subject, emailBody.toString());
439: try {
440: if (mailSession == null) {
441: mailSession = this .getMailSession();
442: }
443: new MailHelper().createAndSendMail(mail, mailSession);
444: } catch (Exception e) {
445: BootLogger.logError("Can't send email notification: "
446: + mail.getHeader(), e);
447: }
448: }
449:
450: /**
451: * Return system information (memory and properties) as string.
452: *
453: * @return system information (memory and properties) as string.
454: */
455: private String getSystemInfo() {
456: StringBuffer buf = new StringBuffer();
457: buf.append("Total Memory: "
458: + Runtime.getRuntime().totalMemory() / 1024
459: + " Kilobyte\n");
460: buf.append("Free Memory: " + Runtime.getRuntime().freeMemory()
461: / 1024 + " Kilobyte\n");
462: java.util.Properties sysprops = System.getProperties();
463: for (Enumeration e = sysprops.keys(); e.hasMoreElements();) {
464: String key = e.nextElement().toString();
465: String value = sysprops.getProperty(key);
466: buf.append(key + " : " + value + "\n");
467: }
468: return buf.toString();
469: }
470:
471: /**
472: *
473: */
474: private Session getMailSession() {
475: Session session = null;
476: try {
477: session = (Session) JndiUtils.lookup(mailSessionName,
478: Session.class);
479: } catch (Exception ex) {
480: BootLogger.logError("Error while initializing "
481: + LoggerService.class.getName() + " : "
482: + ex.getMessage(), ex);
483: } finally {
484: if (session == null) {
485: Properties p = System.getProperties();
486: p.put("mail.smtp.host", LoggerService.mailHostName);
487: session = Session.getDefaultInstance(p, null);
488: }
489: }
490: return session;
491: }
492:
493: }
|