Attachment 'ConfigurationServlet.java'

Download

   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 org.apache.log4j.servlet;
  17 
  18 import java.io.IOException;
  19 import java.io.PrintWriter;
  20 import java.util.ArrayList;
  21 import java.util.Collections;
  22 import java.util.Comparator;
  23 import java.util.Enumeration;
  24 import java.util.Iterator;
  25 import java.util.List;
  26 
  27 import javax.servlet.ServletConfig;
  28 import javax.servlet.ServletException;
  29 import javax.servlet.SingleThreadModel;
  30 import javax.servlet.http.HttpServlet;
  31 import javax.servlet.http.HttpServletRequest;
  32 import javax.servlet.http.HttpServletResponse;
  33 
  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 ConfigurationServlet extends HttpServlet implements SingleThreadModel
  79 {
  80 
  81     /**
  82      * The response content type: text/html
  83      */
  84     private static final String CONTENT_TYPE = "text/html";
  85 
  86     /**
  87      * Should not print html head and body?
  88      */
  89     private static final String CONFIG_FRAGMENT = "fragment";
  90 
  91     /**
  92      * The root appender.
  93      */
  94     private static final String ROOT = "Root";
  95 
  96     /**
  97      * The name of the class / package.
  98      */
  99     private static final String PARAM_CLASS = "class";
 100 
 101     /**
 102      * The logging level.
 103      */
 104     private static final String PARAM_LEVEL = "level";
 105 
 106     /**
 107      * Sort by level?
 108      */
 109     private static final String PARAM_SORTBYLEVEL = "sortbylevel";
 110 
 111     /**
 112      * All the log levels.
 113      */
 114     private static final String[] LEVELS = new String[]{
 115         Level.OFF.toString(),
 116         Level.FATAL.toString(),
 117         Level.ERROR.toString(),
 118         Level.WARN.toString(),
 119         Level.INFO.toString(),
 120         Level.DEBUG.toString(),
 121         Level.ALL.toString()};
 122 
 123     /**
 124      * Don't include html head.
 125      */
 126     private boolean isFragment;
 127 
 128     /**
 129      * Print the status of all current <code>Logger</code> s and an option to change their respective logging levels.
 130      * @param request a <code>HttpServletRequest</code> value
 131      * @param response a <code>HttpServletResponse</code> value
 132      * @exception ServletException if an error occurs
 133      * @exception IOException if an error occurs
 134      */
 135     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 136     {
 137 
 138         String sortByLevelParam = request.getParameter(PARAM_SORTBYLEVEL);
 139         boolean sortByLevel = ("true".equalsIgnoreCase(sortByLevelParam) || "yes".equalsIgnoreCase(sortByLevelParam));
 140 
 141         List loggers = getSortedLoggers(sortByLevel);
 142         int loggerNum = 0;
 143 
 144         PrintWriter out = response.getWriter();
 145         if (!isFragment)
 146         {
 147             response.setContentType(CONTENT_TYPE);
 148 
 149             // print title and header
 150             printHeader(out, request);
 151         }
 152 
 153         // print scripts
 154         out.println("<a href=\"" + request.getRequestURI() + "\">Refresh</a>");
 155 
 156         out.println("<table class=\"log4jtable\">");
 157         out.println("<thead><tr>");
 158 
 159         out.println("<th title=\"Logger name\">");
 160         out.println("<a href=\"?" + PARAM_SORTBYLEVEL + "=false\">Class</a>");
 161         out.println("</th>");
 162 
 163         out.println("<th title=\"Is logging level inherited from parent?\" style=\"text-align:right\" >*</th>");
 164         out.println("<th title=\"Logger level\">");
 165         out.println("<a href=\"?" + PARAM_SORTBYLEVEL + "=true\">Level</a>");
 166         out.println("</th>");
 167 
 168         out.println("</tr></thead>");
 169         out.println("<tbody>");
 170 
 171         // print the root Logger
 172         displayLogger(out, Logger.getRootLogger(), loggerNum++, request);
 173 
 174         // print the rest of the loggers
 175         Iterator iterator = loggers.iterator();
 176 
 177         while (iterator.hasNext())
 178         {
 179             displayLogger(out, (Logger) iterator.next(), loggerNum++, request);
 180         }
 181 
 182         out.println("</tbody>");
 183         out.println("</table>");
 184         out.println("<a href=\"\">Refresh</a>");
 185 
 186         if (!isFragment)
 187         {
 188             out.println("</body></html>");
 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 request, HttpServletResponse response) throws ServletException, IOException
 202     {
 203         String className = request.getParameter(PARAM_CLASS);
 204         String level = request.getParameter(PARAM_LEVEL);
 205 
 206         if (className != null)
 207         {
 208             setClass(className, level);
 209         }
 210 
 211         doGet(request, response);
 212     }
 213 
 214     /**
 215      * Print a Logger and its current level.
 216      * @param out the output writer.
 217      * @param logger the logger to output.
 218      * @param row the row number in the table this logger will appear in.
 219      * @param request the servlet request.
 220      */
 221     private void displayLogger(PrintWriter out, Logger logger, int row, HttpServletRequest request)
 222     {
 223         String color = null;
 224         String loggerName = (logger.getName().equals("") ? ROOT : logger.getName());
 225 
 226         color = ((row % 2) == 1) ? "even" : "odd";
 227 
 228         out.println("<tr class=\"" + color + "\">");
 229 
 230         // logger
 231         out.println("<td>");
 232         out.println(loggerName);
 233         out.println("</td>");
 234 
 235         // level inherited?
 236         out.println("<td style=\"text-align:right\">");
 237         if ((logger.getLevel() == null))
 238         {
 239             out.println("*");
 240         }
 241         out.println("</td>");
 242 
 243         // level and selection
 244         out.println("<td>");
 245         out.println("<form action=\"\" method=\"post\">");
 246         printLevelSelector(out, logger.getEffectiveLevel().toString());
 247         out.println("<input type=\"hidden\" name=\"" + PARAM_CLASS + "\" value=\"" + loggerName + "\">");
 248         out.print("<input type=\"submit\" name=\"Set\" value=\"Set \">");
 249         out.println("</form>");
 250         out.println("</td>");
 251 
 252         out.println("</tr>");
 253     }
 254 
 255     /**
 256      * Set a logger's level.
 257      * @param className class name of the logger to set.
 258      * @param level the level to set the logger to.
 259      * @return String return message for display.
 260      */
 261     private synchronized String setClass(String className, String level)
 262     {
 263         Logger logger = null;
 264 
 265         try
 266         {
 267             logger = (ROOT.equalsIgnoreCase(className) ? Logger.getRootLogger() : Logger.getLogger(className));
 268             logger.setLevel(Level.toLevel(level));
 269         }
 270         catch (Throwable e)
 271         {
 272             System // permetti system.out
 273             .out.println("ERROR Setting LOG4J Logger:" + e);
 274         }
 275 
 276         return "Message Set For " + (logger.getName().equals("") ? ROOT : logger.getName());
 277     }
 278 
 279     /**
 280      * Get a sorted list of all current loggers.
 281      * @param sortByLevel if <code>true</code> sort loggers by level instead of name.
 282      * @return List the list of sorted loggers.
 283      */
 284     private List getSortedLoggers(boolean sortByLevel)
 285     {
 286         Enumeration enum = LogManager.getCurrentLoggers();
 287         Comparator comp = new LoggerComparator(sortByLevel);
 288         List list = new ArrayList();
 289 
 290         // Add all current loggers to the list
 291         while (enum.hasMoreElements())
 292         {
 293             list.add(enum.nextElement());
 294         }
 295 
 296         // sort the loggers
 297         Collections.sort(list, comp);
 298 
 299         return list;
 300     }
 301 
 302     /**
 303      * Prints the page header.
 304      * @param out The output writer
 305      * @param request The request
 306      */
 307     private void printHeader(PrintWriter out, HttpServletRequest request)
 308     {
 309         out.println("<html><head><title>Log4J Control Console</title>");
 310 
 311         out.println("<style type=\"text/css\">");
 312         out.println("body{ background-color:#fff; }");
 313         out.println("body, td, th, select, input{ font-family:Verdana, Geneva, Arial, sans-serif; font-size: 8pt;}");
 314         out.println("select, input{ border: 1px solid #ccc;}");
 315         out.println("table.log4jtable, table.log4jtable td { border-collapse:collapse; border: 1px solid #ccc; ");
 316         out.println("white-space: nowrap; text-align: left; }");
 317         out.println("form { margin:0; padding:0; }");
 318         out.println("table.log4jtable thead tr th{ background-color: #5991A6; padding: 2px; }");
 319         out.println("table.log4jtable tr.even { background-color: #eee; }");
 320         out.println("table.log4jtable tr.odd { background-color: #fff; }");
 321         out.println("</style>");
 322 
 323         out.println("</head>");
 324         out.println("<body>");
 325         out.println("<h3>Log4J Control Console</h3>");
 326     }
 327 
 328     /**
 329      * Prints the Level select HTML.
 330      * @param out The output writer
 331      * @param currentLevel the current level for the log (the selected option).
 332      */
 333     private void printLevelSelector(PrintWriter out, String currentLevel)
 334     {
 335         out.println("<select id=\"" + PARAM_LEVEL + "\" name=\"" + PARAM_LEVEL + "\">");
 336 
 337         for (int j = 0; j < LEVELS.length; j++)
 338         {
 339             out.print("<option");
 340             if (LEVELS[j].equals(currentLevel))
 341             {
 342                 out.print(" selected=\"selected\"");
 343             }
 344             out.print(">");
 345             out.print(LEVELS[j]);
 346             out.println("</option>");
 347         }
 348         out.println("</select>");
 349     }
 350 
 351     /**
 352      * Compare the names of two <code>Logger</code>s. Used for sorting.
 353      */
 354     private class LoggerComparator implements Comparator
 355     {
 356 
 357         /**
 358          * Sort by level? (default is sort by class name)
 359          */
 360         private boolean sortByLevel;
 361 
 362         /**
 363          * instantiate a new LoggerComparator
 364          * @param sortByLevel if <code>true</code> sort loggers by level instead of name.
 365          */
 366         public LoggerComparator(boolean sortByLevel)
 367         {
 368             this.sortByLevel = sortByLevel;
 369         }
 370 
 371         /**
 372          * Compare the names of two <code>Logger</code>s.
 373          * @param object1 an <code>Object</code> value
 374          * @param object2 an <code>Object</code> value
 375          * @return an <code>int</code> value
 376          */
 377         public int compare(Object object1, Object object2)
 378         {
 379             Logger logger1 = (Logger) object1;
 380             Logger logger2 = (Logger) object2;
 381 
 382             if (!sortByLevel)
 383             {
 384                 return logger1.getName().compareTo(logger2.getName());
 385             }
 386             return logger1.getEffectiveLevel().toInt() - logger2.getEffectiveLevel().toInt();
 387         }
 388 
 389         /**
 390          * Return <code>true</code> if the <code>Object</code> is a <code>LoggerComparator</code> instance.
 391          * @param object an <code>Object</code> value
 392          * @return a <code>boolean</code> value
 393          */
 394         public boolean equals(Object object)
 395         {
 396             if (!(object instanceof LoggerComparator))
 397             {
 398                 return false;
 399             }
 400             return this.sortByLevel == ((LoggerComparator) object).sortByLevel;
 401         }
 402 
 403         /**
 404          * @see java.lang.Object#hashCode()
 405          */
 406         public int hashCode()
 407         {
 408             return super.hashCode();
 409         }
 410     }
 411 
 412     /**
 413      * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
 414      */
 415     public void init(ServletConfig config) throws ServletException
 416     {
 417         String fragmentParam = config.getInitParameter(CONFIG_FRAGMENT);
 418         isFragment = ("true".equalsIgnoreCase(fragmentParam) || "yes".equalsIgnoreCase(fragmentParam));
 419         super.init(config);
 420     }
 421 
 422 }

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.