KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > logging > Log4jConfigurationServlet


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package info.magnolia.logging;
17
18 import java.io.IOException JavaDoc;
19 import java.io.PrintWriter JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.Comparator JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 import javax.servlet.ServletConfig JavaDoc;
28 import javax.servlet.ServletException JavaDoc;
29 import javax.servlet.http.HttpServlet JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32
33 import org.apache.commons.lang.StringUtils;
34 import org.apache.log4j.Level;
35 import org.apache.log4j.LogManager;
36 import org.apache.log4j.Logger;
37
38
39 /**
40  * A servlet used to dynamically adjust package logging levels while an application is running. NOTE: This servlet is
41  * only aware of pre-configured packages and packages that contain objects that have logged at least one message since
42  * application startup.
43  * <p>
44  * web.xml configuration:
45  * </p>
46  *
47  * <pre>
48  * &lt;servlet>
49  * &lt;servlet-name>log4j&lt;/servlet-name>
50  * &lt;display-name>Log4j configuration Servlet&lt;/display-name>
51  * &lt;servlet-class>org.apache.log4j.servlet.ConfigurationServlet&lt;/servlet-class>
52  * &lt;/servlet>
53  * </pre>
54  *
55  * <p>
56  * The <code>fragment</code> parameter can be added if you don't want a full xhtml page in output, but only the
57  * content of the body tag, so that it can be used in portlets or struts tiles.
58  * </p>
59  *
60  * <pre>
61  * &lt;servlet>
62  * &lt;servlet-name>log4j&lt;/servlet-name>
63  * &lt;display-name>Log4j configuration Servlet&lt;/display-name>
64  * &lt;servlet-class>org.apache.log4j.servlet.ConfigurationServlet&lt;/servlet-class>
65  * &lt;init-param>
66  * &lt;param-name>fragment&lt;/param-name>
67  * &lt;param-value>true&lt;/param-value>
68  * &lt;/init-param>
69  * &lt;/servlet>
70  * </pre>
71  *
72  * @author Luther E. Birdzell lebirdzell@yahoo.com
73  * @author Yoav Shapira yoavs@apache.org
74  * @author Fabrizio Giustina
75  * @since 1.3
76  * @version $Revision: 1.2 $ ($Author: root $)
77  */

78 public class Log4jConfigurationServlet extends HttpServlet JavaDoc {
79
80     /**
81      * Stable <code>serialVersionUID</code>
82      */

83     private static final long serialVersionUID = 64182;
84
85     /**
86      * The response content type: text/html
87      */

88     private static final String JavaDoc CONTENT_TYPE = "text/html"; //$NON-NLS-1$
89

90     /**
91      * Should not print html head and body?
92      */

93     private static final String JavaDoc CONFIG_FRAGMENT = "fragment"; //$NON-NLS-1$
94

95     /**
96      * The root appender.
97      */

98     private static final String JavaDoc ROOT = "Root"; //$NON-NLS-1$
99

100     /**
101      * The name of the class / package.
102      */

103     private static final String JavaDoc PARAM_CLASS = "class"; //$NON-NLS-1$
104

105     /**
106      * The logging level.
107      */

108     private static final String JavaDoc PARAM_LEVEL = "level"; //$NON-NLS-1$
109

110     /**
111      * Sort by level?
112      */

113     private static final String JavaDoc PARAM_SORTBYLEVEL = "sortbylevel"; //$NON-NLS-1$
114

115     /**
116      * All the log levels.
117      */

118     private static final String JavaDoc[] LEVELS = new String JavaDoc[]{
119         Level.OFF.toString(),
120         Level.FATAL.toString(),
121         Level.ERROR.toString(),
122         Level.WARN.toString(),
123         Level.INFO.toString(),
124         Level.DEBUG.toString(),
125         Level.ALL.toString()};
126
127     /**
128      * Don't include html head.
129      */

130     private boolean isFragment;
131
132     /**
133      * Print the status of all current <code>Logger</code> s and an option to change their respective logging levels.
134      * @param request a <code>HttpServletRequest</code> value
135      * @param response a <code>HttpServletResponse</code> value
136      * @exception ServletException if an error occurs
137      * @exception IOException if an error occurs
138      */

139     public void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc {
140
141         String JavaDoc sortByLevelParam = request.getParameter(PARAM_SORTBYLEVEL);
142         boolean sortByLevel = ("true".equalsIgnoreCase(sortByLevelParam) || "yes".equalsIgnoreCase(sortByLevelParam)); //$NON-NLS-1$ //$NON-NLS-2$
143

144         List JavaDoc loggers = getSortedLoggers(sortByLevel);
145         int loggerNum = 0;
146
147         PrintWriter JavaDoc out = response.getWriter();
148         if (!isFragment) {
149             response.setContentType(CONTENT_TYPE);
150
151             // print title and header
152
printHeader(out);
153         }
154
155         // print scripts
156
out.println("<a HREF=\"" + request.getRequestURI() + "\">Refresh</a>"); //$NON-NLS-1$ //$NON-NLS-2$
157

158         out.println("<table class=\"log4jtable\">"); //$NON-NLS-1$
159
out.println("<thead><tr>"); //$NON-NLS-1$
160

161         out.println("<th title=\"Logger name\">"); //$NON-NLS-1$
162
out.println("<a HREF=\"?" + PARAM_SORTBYLEVEL + "=false\">Class</a>"); //$NON-NLS-1$ //$NON-NLS-2$
163
out.println("</th>"); //$NON-NLS-1$
164

165         out.println("<th title=\"Is logging level inherited from parent?\" style=\"text-align:right\" >*</th>"); //$NON-NLS-1$
166
out.println("<th title=\"Logger level\">"); //$NON-NLS-1$
167
out.println("<a HREF=\"?" + PARAM_SORTBYLEVEL + "=true\">Level</a>"); //$NON-NLS-1$ //$NON-NLS-2$
168
out.println("</th>"); //$NON-NLS-1$
169

170         out.println("</tr></thead>"); //$NON-NLS-1$
171
out.println("<tbody>"); //$NON-NLS-1$
172

173         // print the root Logger
174
displayLogger(out, Logger.getRootLogger(), loggerNum++);
175
176         // print the rest of the loggers
177
Iterator JavaDoc iterator = loggers.iterator();
178
179         while (iterator.hasNext()) {
180             displayLogger(out, (Logger) iterator.next(), loggerNum++);
181         }
182
183         out.println("</tbody>"); //$NON-NLS-1$
184
out.println("</table>"); //$NON-NLS-1$
185
out.println("<a HREF=\"\">Refresh</a>"); //$NON-NLS-1$
186

187         if (!isFragment) {
188             out.println("</body></html>"); //$NON-NLS-1$
189
out.flush();
190             out.close();
191         }
192     }
193
194     /**
195      * Change a <code>Logger</code>'s level, then call <code>doGet</code> to refresh the page.
196      * @param request a <code>HttpServletRequest</code> value
197      * @param response a <code>HttpServletResponse</code> value
198      * @exception ServletException if an error occurs
199      * @exception IOException if an error occurs
200      */

201     public void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc {
202         String JavaDoc className = request.getParameter(PARAM_CLASS);
203         String JavaDoc level = request.getParameter(PARAM_LEVEL);
204
205         if (className != null) {
206             setClass(className, level);
207         }
208
209         doGet(request, response);
210     }
211
212     /**
213      * Print a Logger and its current level.
214      * @param out the output writer.
215      * @param logger the logger to output.
216      * @param row the row number in the table this logger will appear in.
217      * @param request the servlet request.
218      */

219     private void displayLogger(PrintWriter JavaDoc out, Logger logger, int row) {
220         String JavaDoc color = null;
221         String JavaDoc loggerName = (StringUtils.isEmpty(logger.getName()) ? ROOT : logger.getName());
222
223         color = ((row % 2) == 1) ? "even" : "odd"; //$NON-NLS-1$ //$NON-NLS-2$
224

225         out.println("<tr class=\"" + color + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
226

227         // logger
228
out.println("<td>"); //$NON-NLS-1$
229
out.println(loggerName);
230         out.println("</td>"); //$NON-NLS-1$
231

232         // level inherited?
233
out.println("<td style=\"text-align:right\">"); //$NON-NLS-1$
234
if ((logger.getLevel() == null)) {
235             out.println("*"); //$NON-NLS-1$
236
}
237         out.println("</td>"); //$NON-NLS-1$
238

239         // level and selection
240
out.println("<td>"); //$NON-NLS-1$
241
out.println("<form action=\"\" method=\"post\">"); //$NON-NLS-1$
242
printLevelSelector(out, logger.getEffectiveLevel().toString());
243         out.println("<input type=\"hidden\" name=\"" + PARAM_CLASS + "\" value=\"" + loggerName + "\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
244
out.print("<input type=\"submit\" name=\"Set\" value=\"Set \">"); //$NON-NLS-1$
245
out.println("</form>"); //$NON-NLS-1$
246
out.println("</td>"); //$NON-NLS-1$
247

248         out.println("</tr>"); //$NON-NLS-1$
249
}
250
251     /**
252      * Set a logger's level.
253      * @param className class name of the logger to set.
254      * @param level the level to set the logger to.
255      * @return String return message for display.
256      */

257     private synchronized String JavaDoc setClass(String JavaDoc className, String JavaDoc level) {
258         Logger logger = null;
259
260         try {
261             logger = (ROOT.equalsIgnoreCase(className) ? Logger.getRootLogger() : Logger.getLogger(className));
262             logger.setLevel(Level.toLevel(level));
263         }
264         catch (Throwable JavaDoc e) {
265             System // permetti system.out
266
.out.println("ERROR Setting LOG4J Logger:" + e); //$NON-NLS-1$
267
}
268
269         return "Message Set For " + (StringUtils.isEmpty(logger.getName()) ? ROOT : logger.getName()); //$NON-NLS-1$
270
}
271
272     /**
273      * Get a sorted list of all current loggers.
274      * @param sortByLevel if <code>true</code> sort loggers by level instead of name.
275      * @return List the list of sorted loggers.
276      */

277     private List JavaDoc getSortedLoggers(boolean sortByLevel) {
278         Enumeration JavaDoc enm = LogManager.getCurrentLoggers();
279         Comparator JavaDoc comp = new LoggerComparator(sortByLevel);
280         List JavaDoc list = new ArrayList JavaDoc();
281
282         // Add all current loggers to the list
283
while (enm.hasMoreElements()) {
284             list.add(enm.nextElement());
285         }
286
287         // sort the loggers
288
Collections.sort(list, comp);
289
290         return list;
291     }
292
293     /**
294      * Prints the page header.
295      * @param out The output writer
296      * @param request The request
297      */

298     private void printHeader(PrintWriter JavaDoc out) {
299         out.println("<html><head><title>Log4J Control Console</title>"); //$NON-NLS-1$
300

301         out.println("<style type=\"text/css\">"); //$NON-NLS-1$
302
out.println("body{ background-color:#fff; }"); //$NON-NLS-1$
303
out.println("body, td, th, select, input{ font-family:Verdana, Geneva, Arial, sans-serif; font-size: 8pt;}"); //$NON-NLS-1$
304
out.println("select, input{ border: 1px solid #ccc;}"); //$NON-NLS-1$
305
out.println("table.log4jtable, table.log4jtable td { border-collapse:collapse; border: 1px solid #ccc; "); //$NON-NLS-1$
306
out.println("white-space: nowrap; text-align: left; }"); //$NON-NLS-1$
307
out.println("form { margin:0; padding:0; }"); //$NON-NLS-1$
308
out.println("table.log4jtable thead tr th{ background-color: #5991A6; padding: 2px; }"); //$NON-NLS-1$
309
out.println("table.log4jtable tr.even { background-color: #eee; }"); //$NON-NLS-1$
310
out.println("table.log4jtable tr.odd { background-color: #fff; }"); //$NON-NLS-1$
311
out.println("</style>"); //$NON-NLS-1$
312

313         out.println("</head>"); //$NON-NLS-1$
314
out.println("<body>"); //$NON-NLS-1$
315
out.println("<h3>Log4J Control Console</h3>"); //$NON-NLS-1$
316
}
317
318     /**
319      * Prints the Level select HTML.
320      * @param out The output writer
321      * @param currentLevel the current level for the log (the selected option).
322      */

323     private void printLevelSelector(PrintWriter JavaDoc out, String JavaDoc currentLevel) {
324         out.println("<select id=\"" + PARAM_LEVEL + "\" name=\"" + PARAM_LEVEL + "\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
325

326         for (int j = 0; j < LEVELS.length; j++) {
327             out.print("<option"); //$NON-NLS-1$
328
if (LEVELS[j].equals(currentLevel)) {
329                 out.print(" selected=\"selected\""); //$NON-NLS-1$
330
}
331             out.print(">"); //$NON-NLS-1$
332
out.print(LEVELS[j]);
333             out.println("</option>"); //$NON-NLS-1$
334
}
335         out.println("</select>"); //$NON-NLS-1$
336
}
337
338     /**
339      * Compare the names of two <code>Logger</code>s. Used for sorting.
340      */

341     private static class LoggerComparator implements Comparator JavaDoc {
342
343         /**
344          * Sort by level? (default is sort by class name)
345          */

346         private boolean sortByLevel;
347
348         /**
349          * instantiate a new LoggerComparator
350          * @param sortByLevel if <code>true</code> sort loggers by level instead of name.
351          */

352         public LoggerComparator(boolean sortByLevel) {
353             this.sortByLevel = sortByLevel;
354         }
355
356         /**
357          * Compare the names of two <code>Logger</code>s.
358          * @param object1 an <code>Object</code> value
359          * @param object2 an <code>Object</code> value
360          * @return an <code>int</code> value
361          */

362         public int compare(Object JavaDoc object1, Object JavaDoc object2) {
363             Logger logger1 = (Logger) object1;
364             Logger logger2 = (Logger) object2;
365
366             if (!sortByLevel) {
367                 return logger1.getName().compareTo(logger2.getName());
368             }
369             return logger1.getEffectiveLevel().toInt() - logger2.getEffectiveLevel().toInt();
370         }
371
372         /**
373          * Return <code>true</code> if the <code>Object</code> is a <code>LoggerComparator</code> instance.
374          * @param object an <code>Object</code> value
375          * @return a <code>boolean</code> value
376          */

377         public boolean equals(Object JavaDoc object) {
378             if (!(object instanceof LoggerComparator)) {
379                 return false;
380             }
381             return this.sortByLevel == ((LoggerComparator) object).sortByLevel;
382         }
383
384         /**
385          * @see java.lang.Object#hashCode()
386          */

387         public int hashCode() {
388             return super.hashCode();
389         }
390     }
391
392     /**
393      * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
394      */

395     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
396         String JavaDoc fragmentParam = config.getInitParameter(CONFIG_FRAGMENT);
397         isFragment = ("true".equalsIgnoreCase(fragmentParam) || "yes".equalsIgnoreCase(fragmentParam)); //$NON-NLS-1$ //$NON-NLS-2$
398
super.init(config);
399     }
400
401 }
Popular Tags