Attachment didn't seem to work - here's the source... sorry, I can't generate a patch 
because I can't access the log4j cvs & don't have the original source here.

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

package org.apache.log4j.servlet;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.PrintWriter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * A servlet used to dynamically adjust package logging levels
 * while an application is running.  NOTE: This servlet is
 * only aware of pre-configured packages and packages that contain objects
 * that have logged at least one message since application startup.
 * <br>
 * In order to use this servlet, you should define and map it
 * in your web application's deployment descriptor (web.xml file).
 * For example, add the following (if you're looking at the source
 * code for this file, rather than the JavaDoc, omit the HTML tags):
 * <br>
 * <pre>
 * <servlet><br>
 *   <servlet-name>Log4jAdminServlet</servlet-name><br>
 *   <servlet-class>org.apache.log4j.servlet.ConfigurationServlet</servlet-class<br>
 * </servlet><br>
 * <br>
 * <servlet-mapping><br>
 *   <servlet-name>Log4jAdminServlet</servlet-name><br>
 *   <url-pattern>/Log4jAdmin</url-pattern><br>
 * </servlet-mapping><br>
 * <br>
 * This servlet will then be accessible via
 * http://yourhost:yourport/yourwebapp/Log4jAdmin
 *
 * @author <a href="mailto:[EMAIL PROTECTED]">Luther E. Birdzell</a>
 * @author Yoav Shapira <[EMAIL PROTECTED]>
 * @since 1.3
 */
public class ConfigurationServlet extends HttpServlet
  implements SingleThreadModel {
  /**
   * The response content type: text/html
   */
  private static final String CONTENT_TYPE = "text/html";

  /**
   * The root appender.
   */
  private static final String ROOT = "root";

  /**
   * The name of the class / package.
   */
  private static final String CLASS = "CLASS";

  /**
   * The logging level.
   */
  private static final String LEVEL = "LEVEL";

  /**
   * Print the status of all current <code>Logger</code>s and
   * an option to change their respective logging levels.
   *
   * @param request a <code>HttpServletRequest</code> value
   * @param response a <code>HttpServletResponse</code> value
   * @exception ServletException if an error occurs
   * @exception IOException if an error occurs
   */
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType(CONTENT_TYPE);

    PrintWriter out = response.getWriter();
    List loggers = getSortedLoggers();
    Logger logger = null;
    String loggerName = null;
    int loggerNum = 0;

    // print title and header
    printHeader(out, request);

    out.println("<table width=\"90%\" border=\"1\">");
    out.println("<FORM action=\"" + request.getRequestURI() + "\" method=\"post\">");

    out.println("<tr BGCOLOR=\"#5991A6\">");
    out.println(
      "<td><FONT  COLOR=\"BLACK\" FACE=\"Helvetica\"><B>Class</B></FONT></td>");
    out.print(
      "<td><FONT  COLOR=\"BLACK\" FACE=\"Helvetica\"><B>Level</B></FONT>");
    out.println("</td>");
    out.print(
      "<td><FONT  COLOR=\"BLACK\" FACE=\"Helvetica\"><B>Change Level</B></FONT>");
    out.println("</td>");
    out.println("</tr>");

    // print the root Logger
    displayLogger(out, Logger.getRootLogger(), loggerNum++, request);

    // print the rest of the loggers
    Iterator ii = loggers.iterator();

    while (ii.hasNext()) {
      displayLogger(out, (Logger) ii.next(), loggerNum++, request);
    }

    out.println("</table>");
    out.println(
      "<FONT SIZE=\"-3\" COLOR=\"BLACK\" FACE=\"Helvetica\">* "
      + "Inherits LEVEL From Parent.</FONT><BR>");
    out.println("<A href=\"" + request.getRequestURI() + "\">Refresh</A><HR>");

    // print set options
    out.println(
      "<input type=\"submit\" name=\"Submit\" value=\"Save changes\"></FONT>");
    out.println("</FORM>");
    out.println("</body></html>");

    out.flush();
    out.close();
  }

  /**
   * Change a <code>Logger</code>'s level, then call <code>doGet</code>
   * to refresh the page.
   *
   * @param request a <code>HttpServletRequest</code> value
   * @param response a <code>HttpServletResponse</code> value
   * @exception ServletException if an error occurs
   * @exception IOException if an error occurs
   */
  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    List loggers = getSortedLoggers();
    Logger logger = null;
    String loggerName = null;
    String newLevel = null;

    // deal with root logger first
    newLevel = request.getParameter(ROOT);
    setClass(ROOT,Level.toLevel(newLevel));

    Iterator ii = loggers.iterator();

    while (ii.hasNext()) {
      logger = (Logger) ii.next();
      loggerName = logger.getName();
      newLevel = (request.getParameter(loggerName));
      //System.out.println(loggerName + ": newLevel = " + newLevel);
      if ( logger.getLevel() == null && (newLevel == null || 
newLevel.equals("INHERITED"))
           || logger.getLevel() != null && logger.getLevel() == 
Level.toLevel(newLevel))
      {
      // level unchanged - do nothing
      } else {
      System.out.println("updating " + loggerName + " to " + newLevel);
        if (newLevel.equals("INHERITED")) {
        setClass(loggerName,null);
      } else {
        setClass(loggerName,Level.toLevel(newLevel));
        }
      }
    }

    doGet(request, response);
  }

  /**
    Print a Logger and its current level.

    @param out the output writer.
    @param logger the logger to output.
    @param row the row number in the table this logger will appear in.
    @param request the servlet request. */
  private void displayLogger(
    PrintWriter out, Logger logger, int row, HttpServletRequest request) {
    String color = null;
    String loggerName =
      (logger.getName().equals("root") ? ROOT : logger.getName());

    color = ((row % 2) == 1) ? "#E1E1E1" : "#FBFBFB";

    out.println("<tr BGCOLOR=\"" + color + "\">");
    out.println(
      "<td><FONT SIZE=\"-2\" COLOR=\"BLACK\" FACE=\"Helvetica\">" + loggerName
      + "</FONT></td>");
    out.println(
      "<td><FONT SIZE=\"-2\" COLOR=\"BLACK\" FACE=\"Helvetica\">"
      + ((logger.getLevel() == null)
      ? (logger.getEffectiveLevel().toString() + "*")
      : logger.getLevel().toString()) + "</FONT></td>");

    out.println(
      "<td><FONT SIZE=\"-2\" COLOR=\"BLACK\" FACE=\"Helvetica\">");

    if (logger.getLevel() == null) {

    out.println("<input type=radio name="+loggerName+" value=INHERITED 
checked>*INHERITED &nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=DEBUG>DEBUG 
&nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=INFO>INFO 
&nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=WARN>WARN 
&nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=ERROR>ERROR 
&nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=FATAL>FATAL 
&nbsp;&nbsp;&nbsp; ");
    out.println("<input type=radio name="+loggerName+" value=OFF>OFF 
&nbsp;&nbsp;&nbsp; ");

    } else {

    if (!loggerName.equals(ROOT)) out.println("<input type=radio name="+loggerName+" 
value=INHERITED>*INHERITED &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=DEBUG "
      + ((logger.getLevel().equals(Level.toLevel("DEBUG"))) ? " checked " : "")
      + ">DEBUG &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=INFO "
      + ((logger.getLevel().equals(Level.toLevel("INFO"))) ? " checked " : "")
      + ">INFO &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=WARN "
      + ((logger.getLevel().equals(Level.toLevel("WARN"))) ? " checked " : "")
      + ">WARN &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=ERROR "
      + ((logger.getLevel().equals(Level.toLevel("ERROR"))) ? " checked " : "")
      + ">ERROR &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=FATAL "
      + ((logger.getLevel().equals(Level.toLevel("FATAL"))) ? " checked " : "")
      + ">FATAL &nbsp;&nbsp;&nbsp; ");

    out.println("<input type=radio name="+loggerName+" value=OFF "
      + ((logger.getLevel().equals(Level.toLevel("OFF"))) ? " checked " : "")
      + ">OFF &nbsp;&nbsp;&nbsp; ");

    }

    out.println("</td></tr>");
  }

  /**
    Set a logger's level.

    @param className class name of the logger to set.
    @param level the level to set the logger to.
    @return String return message for display. */
  private synchronized String setClass(String className, Level level) {
    Logger logger = null;
    String message = null;

    try {
      logger =
        (className.equals(ROOT)) ? Logger.getRootLogger()
                                 : Logger.getLogger(className);

      logger.setLevel(level);
    } catch (Exception e) {
      System.out.println("ERROR Setting LOG4J Logger:" + e);
    }

    return "Message Set For "
    + (logger.getName().equals("root") ? ROOT : logger.getName());
  }

  /**
    Get a sorted list of all current loggers.

    @return List the list of sorted loggers. */
  private List getSortedLoggers() {
    Logger logger = null;
    Enumeration enum = LogManager.getCurrentLoggers();
    Comparator comp = new LoggerComparator();
    List list = new ArrayList();

    // Add all current loggers to the list
    while (enum.hasMoreElements()) {
      list.add(enum.nextElement());
    }

    // sort the loggers
    Collections.sort(list, comp);

    return list;
  }

  /**
   * Prints the page header.
   *
   * @param out The output writer
   * @param request The request
   */
  private void printHeader(PrintWriter out, HttpServletRequest request) {
    out.println(
      "<html><head><title>Log4J Control Console</title></head>"
      + "<body><H3>Log4J Control Console</H3>");
    out.println("<A href=\"" + request.getRequestURI() + "\">Refresh</A><HR>");
  }

  /**
   * Prints the Level select HTML.
   *
   * @param out The output writer
   */
  private void printLevelSelector(PrintWriter out) {
    out.println(
      "<tr BGCOLOR=\"#5991A6\"><td><FONT COLOR=\"BLACK\" "
      + "FACE=\"Helvetica\"><B>Level:</B></FONT></td>");
    out.println("<td><SELECT name=\"" + LEVEL + "\">");
    out.println(
      "<OPTION VALUE=\"" + Level.OFF + "\">" + Level.OFF + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.FATAL + "\">" + Level.FATAL + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.ERROR + "\">" + Level.ERROR + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.WARN + "\">" + Level.WARN + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.INFO + "\">" + Level.INFO + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.DEBUG + "\">" + Level.DEBUG + "</OPTION>");
    out.println(
      "<OPTION VALUE=\"" + Level.ALL + "\">" + Level.ALL + "</OPTION>");
    out.println("</SELECT><BR></td></tr>");
  }

  /**
   * Compare the names of two <code>Logger</code>s.  Used
   * for sorting.
   */
  private class LoggerComparator implements Comparator {
    /**
     * Compare the names of two <code>Logger</code>s.
     *
     * @param o1 an <code>Object</code> value
     * @param o2 an <code>Object</code> value
     * @return an <code>int</code> value
     */
    public int compare(Object o1, Object o2) {
      Logger logger1 = (Logger) o1;
      Logger logger2 = (Logger) o2;
      ;

      String logger1Name = null;
      String logger2Name = null;

      if (logger1 != null) {
        logger1Name = (logger1.getName().equals("root") ? ROOT : logger1.getName());
      }

      if (logger2 != null) {
        logger2Name = (logger2.getName().equals("root") ? ROOT : logger2.getName());
      }

      return logger1Name.compareTo(logger2Name);
    }

    /**
     * Return <code>true</code> if the <code>Object</code> is a
     * <code>LoggerComparator</code> instance.
     *
     *
     * @param o an <code>Object</code> value
     * @return a <code>boolean</code> value
     */
    public boolean equals(Object o) {
      return (o instanceof LoggerComparator);
    }

    /**
     * Returns the parent's hashcode.
     *
     * @return int The hashcode value
     */
     public int hashCode() {
       return super.hashCode();
     }
  }
}


//EOF




                                                                                       
                                                                                      
                      "Stephen Pain"                                                   
                                                                                      
                      <stephen.pain+exter        To:       "Log4J Users List" <[EMAIL 
PROTECTED]>                                                                
                      [EMAIL PROTECTED]>                cc:                            
                                                                                       
      
                                                 Subject:  Re: generating log4j.xml    
                                                                                      
                      20/08/2004 13:26                                                 
                                                                                      
                      Please respond to                                                
                                                                                      
                      "Log4J Users List"                                               
                                                                                      
                                                                                       
                                                                                      
                                                                                       
                                                                                      





This reminds me, I made changes to the Log4jAdmin page that I didn't get round to 
making public yet - I replaced the dropdown box with a set of radio boxes next to each 
logger, making it much easier (I think) to update the configuration.  I also added an 
"INHERITED" level (just sets the threshold back to null).

There's a small bug - if you try to set the level to INHERITED when it's specifically 
defined to be something else in the log4j.properties file, it won't work - instead, 
you have to change to something else (eg change from DEBUG -> WARN), hit apply, then 
try again with the inherited, and second time round it works.  I have an idea of where 
the problem is but haven't had time to fix it yet.

I'll attach the source, in case anyone's interested.

      (See attached file: ConfigurationServlet.java)

Cheers,
Stephen




                      Nathan Coast
                      <[EMAIL PROTECTED]        To:       Log4J Users List <[EMAIL 
PROTECTED]>
                      com>                     cc:
                                               Subject:  Re: generating log4j.xml
                      20/08/2004 13:01
                      Please respond to
                      "Log4J Users
                      List"






I'm about to push out a new version of the Log4J admin web app.  With the webapp, you 
can
modify the in-memory configuration but once you reboot, you're back to where you 
started
from.  I'd like to add a feature to write the modifications back to the config file.  
To
do this I'll need something to generate a config file from the current runtime 
configuration.

Shapira, Yoav wrote:

> Hi,
> I'm not that gung-ho about configuration-file-generation tools.  We've
> had some bitter experiences in the Tomcat area related to this.  The
> problem is that the code tends to develop faster than the
> configuration-file-generation tool and so the configuration file
> generator outputs either incomplete or invalid configuration files (at
> worst), or just doesn't expose all the functionality of the code (which
> is not that bad a scenario).
>
> If someone wants to develop and maintain it, good for them.  I'm not
> sure it belongs in the log4j core, at least initially.  If it stands the
> test of tiem (as a contrib module perhaps, or a sandbox one), and gets
> significant usage, then maybe.
>
> Yoav Shapira
> Millennium Research Informatics
>
>
>
>>-----Original Message-----
>>From: Paul Smith [mailto:[EMAIL PROTECTED]
>>Sent: Tuesday, August 17, 2004 11:42 PM
>>To: 'Log4J Users List'
>>Subject: RE: generating log4j.xml
>>
>>
>>>I'd be glad to volunteer as I need it for the project I'm working on.
>>>My concern is that any xml generator would become obsolete with log4j
>>>1.3. From the docs, I see that 1.3 xml configuration is achieved
>
> using
>
>>>something called the joran configurator
>>>http://www.qos.ch/logging/JoranConfigurator.html
>>>
>>>would it make more sense to develop something like a
>
> JoranConfigWriter?
>
>>Well, you could call it that, but the reading and configuring is done
>
> by
>
>>JoranConfigurator, but one could think that once a LoggerRepository is
>>configured, it's configuration could be output in any form (properties,
>>XML,
>>whatever).  If we have a class that walks the LoggerRepository loggers,
>>appenders, and plugins, and outputs the configuration file in some
>
> format
>
>>(obviously XML in the format JoranConfigurator can read would be the
>
> most
>
>>useful first version) that would be perfect.
>>It should be straightforward from a Junit point of view too.  Given an
>
> XML
>
>>configuration file, use JoranConfigurator to configure, then use
>>NathansCoolConfigWriter to write the xml file back out, and then
>
> compare
>
>>the
>>2 xml files together for success/failure.
>>
>>
>>>I know this has probably been asked a thousand times.... how far off
>
> is
>
>>>1.3?  a week, a month, a year?
>>
>>echo "how far off is 1.3?" > /dev/idontknow/
>>cheers,
>>Paul Smith
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: [EMAIL PROTECTED]
>>For additional commands, e-mail: [EMAIL PROTECTED]
>
>
>
>
>
> This e-mail, including any attachments, is a confidential business communication, 
> and may contain information that is confidential, proprietary and/or privileged.  
> This e-mail is intended only for the individual(s) to whom it is addressed, and may 
> not be saved, copied, printed, disclosed or used by anyone else.  If you are not 
> the(an) intended recipient, please immediately delete this e-mail from your computer 
> system and notify the sender.  Thank you.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]






--

This e-mail may contain confidential and/or privileged information. If you are not the 
intended recipient (or have received this e-mail in error) please notify the sender 
immediately and destroy this e-mail. Any unauthorized copying, disclosure or 
distribution of the material in this e-mail is strictly forbidden.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--

This e-mail may contain confidential and/or privileged information. If you are not the 
intended recipient (or have received this e-mail in error) please notify the sender 
immediately and destroy this e-mail. Any unauthorized copying, disclosure or 
distribution of the material in this e-mail is strictly forbidden.



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to