1 package org.apache.turbine.services.logging;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import org.apache.log4j.Appender;
58 import org.apache.log4j.Category;
59 import org.apache.log4j.Layout;
60 import org.apache.log4j.PatternLayout;
61 import org.apache.log4j.Priority;
62 import org.apache.log4j.PropertyConfigurator;
63 import org.apache.log4j.RollingFileAppender;
64 import org.apache.log4j.WriterAppender;
65 import org.apache.log4j.net.SMTPAppender;
66 import org.apache.log4j.net.SocketAppender;
67 import org.apache.log4j.net.SyslogAppender;
68 import org.apache.turbine.services.logging.jdbc.JDBCAppender;
69 import org.apache.turbine.services.resources.TurbineResources;
70 import org.apache.turbine.util.RunData;
71
72 import javax.servlet.ServletContext;
73 import java.util.Enumeration;
74 import java.util.Hashtable;
75 import java.util.Properties;
76 import java.util.Vector;
77
78 /***
79 * Class implements the Logger interface using log4java package
80 * Messages can be written to following destination:
81 * <ul>
82 * <li>console</li>
83 * <li>file</li>
84 * <li>rollover file</li>
85 * <li>syslog</li>
86 * <li>remote server</li>
87 * <li>email</li>
88 * <li>database</li>
89 * </ul>
90 *
91 * @author <a href="mailto:Tomasz.Zielinski@e-point.pl">Tomasz Zielinski</a>
92 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
93 * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
94 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
95 * @version $Id: Log4JavaLogger.java,v 1.3 2002/04/05 07:04:55 dobbs Exp $
96 */
97 public class Log4JavaLogger extends BaseLogger
98 {
99 /*** global files appenders table */
100 protected static Hashtable filesTable;
101
102 /*** console appender */
103 protected static Appender consoleAppender = null;
104
105 /*** log4java logging interface */
106 protected Category logger;
107
108 /*** logging layout */
109 protected Layout layout;
110
111 /*** global initialization */
112 static
113 {
114 filesTable = new Hashtable();
115 consoleAppender = new WriterAppender(
116 new PatternLayout("%d [%t] %-5p %c - %m%n"), System.out);
117 }
118
119 public Log4JavaLogger()
120 {
121 super();
122 }
123
124 /*** Initialize and create new category (logger handler)*/
125 public void init(LoggingConfig loggingConfig)
126 {
127 // setup the logger
128 logger = Category.getInstance(loggingConfig.getName());
129 logger.setAdditivity(false);
130 //Priority is set for DEBUG becouse this implementation checks log level.
131 logger.setPriority(Priority.DEBUG);
132 // FIXME: set the pattern
133 layout = new PatternLayout("%d [%t] %-5p %c - %m%n");
134
135 // now do the rest of initialization
136 super.init(loggingConfig);
137
138 //if there are log4j properties defined, let them override all else
139 Properties props =
140 loggingConfig.getFacilityProperties(loggingConfig.getName());
141 PropertyConfigurator.configure(props);
142 }
143
144
145 /***
146 * Adds a local file as destinations for logger.
147 *
148 * @param loggingConfig The configuration of this logger.
149 */
150 protected void configureFiles(LoggingConfig loggingConfig)
151 {
152 Vector files = loggingConfig.getFiles();
153
154 //we may not always have 'files' defined, for example if its
155 //done in the log4j properties
156 if (files == null)
157 {
158 return;
159 }
160
161 for (Enumeration filesEnum = files.elements(); filesEnum.hasMoreElements(); )
162 {
163 String path = (String) filesEnum.nextElement();
164 //resolves relative paths
165 String pathTmp = ((ServletContext)loggingConfig.getServletContext())
166 .getRealPath(path);
167 if (pathTmp != null)
168 {
169 path=pathTmp;
170 }
171
172 Appender appender = null;
173 //checking if thereis such appender in the system
174 appender = (Appender)filesTable.get(path);
175 if (appender == null)
176 {
177 try
178 {
179 appender = new RollingFileAppender(layout, path, true);
180 ((RollingFileAppender)appender)
181 .setMaxBackupIndex(loggingConfig.getBackupFiles());
182 //finding file size
183 if (loggingConfig.getFileSize() > -1)
184 {
185 ((RollingFileAppender)appender)
186 .setMaximumFileSize(loggingConfig.getFileSize());
187 }
188 filesTable.put(path, appender);
189 }
190 catch (java.io.IOException e)
191 {
192 return;
193 }
194 logger.addAppender(appender);
195 }
196 }
197 }
198
199 /***
200 * It adds console as a destination for logger.
201 * @param loggingConfig configuration
202 */
203 protected void configureConsole(LoggingConfig loggingConfig)
204 {
205 this.console = loggingConfig.getConsole();
206 if (console)
207 {
208 if (consoleAppender != null)
209 {
210 logger.addAppender(consoleAppender);
211 }
212 }
213 }
214
215 /***
216 * This method should be implemented by user if the logger can handle console.
217 * It adds console as a destination for logger.
218 *
219 * @param loggingConfig configuration
220 */
221 protected void configureRemote(LoggingConfig loggingConfig)
222 {
223 String remoteHost = loggingConfig.getRemoteHost();
224 int remotePort=loggingConfig.getRemotePort();
225 if (remoteHost == null || remoteHost.trim().equals("") || remotePort <= 0)
226 {
227 return;
228 }
229 Appender appender = new SocketAppender(remoteHost, remotePort);
230 logger.addAppender(appender);
231 }
232
233 /***
234 * It adds remote demon as a destination for logger.
235 *
236 * @param loggingConfig configuration
237 */
238 protected void configureSyslog(LoggingConfig loggingConfig)
239 {
240 String syslogHost = loggingConfig.getSyslogHost();
241 if (syslogHost == null || syslogHost.trim().equals("") )
242 {
243 return;
244 }
245
246 Appender appender = new SyslogAppender(layout, syslogHost, logLevel);
247 logger.addAppender(appender);
248 }
249
250 /***
251 * It adds email as a destination for logger.
252 *
253 * @param loggingConfig configuration
254 */
255 protected void configureEmail(LoggingConfig loggingConfig)
256 {
257 String smtpHost = TurbineResources.getString("mail.server");
258 String emailFrom = loggingConfig.getEmailFrom();
259 String emailTo = loggingConfig.getEmailTo();
260 String emailSubject = loggingConfig.getEmailSubject();
261 String bufferSize = loggingConfig.getEmailBufferSize();
262
263 if (smtpHost == null || smtpHost.trim().equals("")
264 || emailFrom == null || emailFrom.trim().equals("")
265 || emailTo == null || emailTo.trim().equals("")
266 || emailSubject == null || emailSubject.trim().equals("")
267 || bufferSize == null || bufferSize.trim().equals("") )
268 {
269 return;
270 }
271
272 SMTPAppender appender = new SMTPAppender();
273 appender.setSMTPHost(smtpHost);
274 appender.setFrom(emailFrom);
275 appender.setTo(emailTo);
276 appender.setSubject(emailSubject);
277 appender.setBufferSize(new Integer(bufferSize).intValue());
278 appender.setLayout(layout);
279 appender.activateOptions();
280 logger.addAppender(appender);
281 }
282
283 /***
284 * It adds a db as a destination for logger.
285 *
286 * @param loggingConfig configuration
287 */
288 protected void configureDatabase(LoggingConfig loggingConfig)
289 {
290 String dbLogger = loggingConfig.getDbLogger();
291 String dbPool = loggingConfig.getDbPool();
292
293 if (dbLogger == null || dbLogger.trim().equals(""))
294 {
295 return;
296 }
297
298 JDBCAppender appender = new JDBCAppender();
299 appender.setOption(JDBCAppender.LOGGER_CLASS_OPTION, dbLogger);
300
301 /*
302 * This sucks, but we are stuck with setOption(String, String).
303 * I want people to be able to specify their own db logger
304 * implementation and the options without having to touch
305 * anything else, but log4j doesn't really make it that easy.
306 */
307 //appender.setOption(JDBCAppender.LOGGER_OPTION, "pool:" + dbPool);
308 appender.setLayout(layout);
309 appender.activateOptions();
310 logger.addAppender(appender);
311 }
312
313 /***
314 * It performs action that are need for deterimne whether
315 * logger was well configured or has any output
316 */
317 public boolean checkLogger()
318 {
319 Enumeration enum = logger.getAllAppenders();
320 if (enum.hasMoreElements())
321 {
322 return true;
323 }
324
325 return false;
326
327 }
328
329 /***
330 * Also do a shutdown if the object is destroy()'d.
331 */
332 protected void finalize() throws Throwable
333 {
334 shutdown();
335 }
336
337 /*** Close all destinations*/
338 public void shutdown()
339 {
340 Enumeration appenders = logger.getAllAppenders();
341 while (appenders.hasMoreElements())
342 {
343 Appender appender = (Appender)appenders.nextElement();
344 appender.close();
345 }
346 }
347
348 /***
349 * This is a log metod with logLevel == DEBUG
350 */
351 public void debug(String message)
352 {
353 log(DEBUG, message, null, null);
354 }
355
356 /***
357 * This is a log metod with logLevel == DEBUG
358 */
359 public void debug(String message, Throwable t)
360 {
361 log(DEBUG, message, null, t);
362 }
363
364 /***
365 * This is a log metod with logLevel == DEBUG
366 */
367 public void debug(String message, RunData data)
368 {
369 log(DEBUG, message, data, null);
370 }
371
372 /***
373 * This is a log metod with logLevel == DEBUG
374 */
375 public void debug(String message, RunData data, Throwable t)
376 {
377 log(DEBUG, message, data, t);
378 }
379
380 /***
381 * This is a log metod with logLevel == INFO
382 */
383 public void info(String message)
384 {
385 log(INFO, message, null, null);
386
387 }
388
389 /***
390 * This is a log metod with logLevel == INFO
391 */
392 public void info(String message, Throwable t)
393 {
394 log(INFO, message, null, t);
395
396 }
397
398 /***
399 * This is a log metod with logLevel == INFO
400 */
401 public void info(String message, RunData data)
402 {
403 log(INFO, message, data, null);
404
405 }
406
407 /***
408 * This is a log metod with logLevel == INFO
409 */
410 public void info(String message, RunData data, Throwable t)
411 {
412 log(INFO, message, data, t);
413
414 }
415
416 /***
417 * This is a log metod with logLevel == WARN
418 */
419 public void warn(String message)
420 {
421 log(WARN, message, null, null);
422 }
423
424 /***
425 * This is a log metod with logLevel == WARN
426 */
427 public void warn(String message, Throwable t)
428 {
429 log(WARN, message, null, t);
430 }
431
432 /***
433 * This is a log metod with logLevel == WARN
434 */
435 public void warn(String message, RunData data)
436 {
437 log(WARN, message, data, null);
438 }
439
440 /***
441 * This is a log metod with logLevel == WARN
442 */
443 public void warn(String message, RunData data, Throwable t)
444 {
445 log(WARN, message, data, t);
446 }
447
448 /***
449 * This is a log metod with logLevel == ERROR
450 */
451 public void error(String message)
452 {
453 log(ERROR, message, null, null);
454 }
455
456 /***
457 * This is a log metod with logLevel == ERROR
458 */
459 public void error(String message, Throwable e)
460 {
461 log(ERROR, message, null, e);
462 }
463
464 /***
465 * This is a log metod with logLevel == ERROR
466 */
467 public void error(Throwable e)
468 {
469 log(ERROR, null, null, e);
470 }
471
472 /***
473 * This is a log metod with logLevel == ERROR
474 */
475 public void error(String message, RunData data)
476 {
477 log(ERROR, message, data, null);
478 }
479
480 /***
481 * This is a log metod with logLevel == ERROR
482 */
483 public void error(String message, RunData data, Throwable e)
484 {
485 log(ERROR, message, data, e);
486 }
487
488 /***
489 * Creates new loging message form message and RunData, and sends it to the category.
490 */
491 private void log(int level, String message, RunData data, Throwable e)
492 {
493
494 if (level < logLevel)
495 {
496 return;
497 }
498
499 if (data != null)
500 {
501 message += runDataFilter.getString(data);
502 }
503 switch (level)
504 {
505 case DEBUG: logger.debug(message, e); break;
506 case INFO: logger.info(message, e); break;
507 case WARN: logger.warn(message, e); break;
508 case ERROR: logger.error(message, e); break;
509 default: logger.debug(message, e);
510 }
511 }
512 }
This page was automatically generated by Maven