Source code: info/crossbar/filtersAndListeners/ContextListener.java
1 /*
2 * @(#)ContextListener.java $Revision: 1.4 $ $Date: 2003/06/21 00:42:13 $
3 *
4 * Copyright 2002 by Daniel Kehoe <kehoe@fortuity.com>
5 * All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 package info.crossbar.filtersAndListeners;
29
30 import java.util.logging.*;
31 import java.util.*;
32
33 import java.io.*;
34
35 import javax.servlet.ServletContext;
36 import javax.servlet.ServletException;
37 import javax.servlet.ServletContextEvent;
38 import javax.servlet.ServletContextListener;
39
40
41 /**
42 * ContextListener class for use by <a href="http://www.crossbar.info/">Crossbar</a>
43 *
44 * @author Daniel Kehoe, <a href="http://www.fortuity.com/">Fortuity Consulting</a>
45 * @version <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/crossbar/crossbar-stylish/src/java/info/crossbar/filtersAndListeners/ContextListener.java">View source, revision history</a>
46 * $Revision: 1.4 $ $Date: 2003/06/21 00:42:13 $
47 * <p>
48 * DESCRIPTION:
49 * An application lifecycle event listener that executes when the servlet context is
50 * created and destroyed. Sets up logging for the application and initializes any classes needed
51 * throughout the application.
52 */
53 public class ContextListener implements ServletContextListener {
54
55 public void contextInitialized(ServletContextEvent sce) {
56 ServletContext context = sce.getServletContext();
57 if (context == null) {
58 String msg = "FATAL: cannot obtain application context!";
59 System.out.println(msg);
60 }
61 try {
62 // show we are initializing the application:
63 String msg = context.getServletContextName()
64 + " version " + context.getInitParameter("info.crossbar.version")
65 + ": initializing application";
66 System.out.println(msg);
67 context.log(msg);
68 /*
69 * Set up logging for the application.
70 */
71 Logger log = setLogging(context);
72 // show the application is done initializing:
73 msg = context.getServletContextName() + " ready to respond to requests";
74 log.info(msg);
75 System.out.println(msg);
76 context.log(msg);
77 } catch (ServletException se) {
78 String msg = "ContextListener ServletException: " + se.getMessage();
79 System.out.println(msg);
80 context.log(msg);
81 se.printStackTrace();
82 }
83 }
84
85 /**
86 * Set up logging for the application. Logging properties are set here for
87 * use throughout the application. Uses the Java Logging API.
88 *
89 * @param context the ServletContext object
90 * @return a Logger object
91 * @exception ServletException thrown by any error
92 */
93 public static Logger setLogging(ServletContext context)
94 throws ServletException {
95 LogManager logManager = LogManager.getLogManager();
96 // Reset all handlers:
97 logManager.reset();
98 // The root logger defaults to INFO, so we have to crank it up,
99 // or it will filter out FINE messages from all the children:
100 Logger rootLogger = Logger.getLogger("");
101 rootLogger.setLevel(Level.ALL);
102 Level debugLevel = Level.FINE;
103 // find out if a configuration parameter defines the debug level to log:
104 if (context.getInitParameter("info.crossbar.debuglevel") != null) {
105 try {
106 debugLevel = Level.parse(context.getInitParameter("info.crossbar.debuglevel").toUpperCase());
107 } catch (IllegalArgumentException iae) {
108 System.out.println(context.getServletContextName() + ": " + iae);
109 context.log(context.getServletContextName() + ": " + iae);
110 }
111 }
112 // determine the location where the log file belongs:
113 String logfile = "%t/" + context.getServletContextName() + ".log";
114 try {
115 logfile = getLogFilePath(context);
116 } catch (IOException ioe) {
117 context.log("can't use logfile: " + ioe);
118 }
119 // Set the parent of all subsequent loggers in the application.
120 java.util.logging.Logger log = java.util.logging.Logger.getLogger(getPackageParent(context));
121 // write log messages to the console only if they are severe:
122 ConsoleHandler ch = new ConsoleHandler();
123 ch.setLevel(Level.SEVERE);
124 log.addHandler(ch);
125 // write log messages to the application logfile at the specified level:
126 // (specify simple (non-XML) log messages for the application logfile):
127 try {
128 SimpleFormatter simpletext = new SimpleFormatter();
129 FileHandler fh = new FileHandler(logfile);
130 fh.setFormatter(simpletext);
131 fh.setLevel(debugLevel);
132 log.addHandler(fh);
133 } catch (IOException ioe) {
134 context.log("can't use logfile \"" + logfile + "\": " + ioe);
135 }
136 // put clues in the console and servlet log about the location of the logs:
137 System.out.println(context.getServletContextName() + " logging to: " + logfile);
138 context.log(context.getServletContextName() + " logging to: " + logfile);
139 log.info(context.getServletContextName() + ": logging at level \"" + debugLevel + "\"");
140 return log;
141 } // end of setLogging() method
142
143
144 /**
145 * Utility method returns a path to a servlet.log file.
146 *
147 * @param context the ServletContext object
148 * @return logFilePath String <tomcat>/logs/crossbar.log
149 * @exception ServletException thrown by any error
150 * @exception IOException thrown by attempts to access files that don't exist
151 */
152 protected static String getLogFilePath(ServletContext context)
153 throws ServletException, IOException {
154 String logFilePath = null;
155 // find out if a configuration parameter defines the path to a logfile:
156 if (context.getInitParameter("info.crossbar.logfilepath") != null
157 && !"DEFAULT".equals(context.getInitParameter("info.crossbar.logfilepath").toUpperCase())) {
158 logFilePath = context.getInitParameter("info.crossbar.logfilepath");
159 } else {
160 String logFileName = context.getServletContextName().toLowerCase() + ".log";
161 String slash = System.getProperty("file.separator");
162 // try getting the tempdir value, it looks like
163 // "C:\java\tomcat4\work\Standalone\localhost\crossbar",
164 // it works better than context.getRealPath("") because
165 // context.getRealPath("") doesn't work well when the
166 // app is deployed from an unexploded war file
167 String lengthyPath = ((File) context.getAttribute("javax.servlet.context.tempdir")).getParent();
168 if (lengthyPath == null) {
169 String msg = "FATAL: cannot obtain file system reference, cannot set log file";
170 System.out.println(msg);
171 context.log(msg);
172 throw new ServletException(msg);
173 }
174 lengthyPath = lengthyPath.substring(0, lengthyPath.lastIndexOf(slash));
175 lengthyPath = lengthyPath.substring(0, lengthyPath.lastIndexOf(slash));
176 logFilePath = lengthyPath.substring(0, lengthyPath.lastIndexOf(slash))
177 + slash + "logs" + slash + logFileName;
178 // when we're done, the log filepath should look like:
179 // "D:\Program Files\tomcat\logs\crossbar.log"
180 }
181 return logFilePath;
182 }
183
184 /**
185 * Utility method returns "info.crossbar" or something similar.
186 * Easy to override in derived applications. Used to set the java.util.logging.Logger
187 * object to be the parent of all subsequent loggers in the application.
188 *
189 * @return String such as "info.crossbar"
190 * @exception ServletException thrown by any error
191 */
192 protected static String getPackageParent(ServletContext context)
193 throws ServletException {
194 String pkg = ContextListener.class.getPackage().getName();
195 pkg = pkg.substring(0, pkg.lastIndexOf("."));
196 context.log("setting logging for all classes in \"" + pkg + "\"");
197 return pkg;
198 }
199
200 public void contextDestroyed(ServletContextEvent sce) {
201 }
202 }