Results 1 to 10 of 10

Thread: Change to Log Levels dynamically via JMX

  1. #1
    Join Date
    Aug 2006
    Posts
    5

    Lightbulb Change to Log Levels dynamically via JMX

    Hi,

    I have a requirement where in I have to change the log levels dynamically at runtime. It is not possible for me to modify the log4j.properties or log4j.xml as my application is deployed as an .ear file.
    I am sure there could be some solution for this, I was thinking of JMX but not sure how. I appreciate if anyone help me in this regard and if possible explain with sample code.

    TechStack: Weblogic9.1, Apache log4j, Spring Framework, J2EE, hibernate etc

    Thanks
    Kris.

  2. #2
    Join Date
    Aug 2006
    Posts
    129

    Default

    export the bean below to jmx
    i did try this (jboss), but didn't have the time
    since the change did not affect the log immedially

    public class Log4jConfig {

    public void enableInfo(String target){
    LogManager.getLogger(target).setLevel(Level.INFO);
    }

    public void enableWarn(String target){
    LogManager.getLogger(target).setLevel(Level.WARN);
    }

    public void enableError(String target){
    LogManager.getLogger(target).setLevel(Level.ERROR) ;
    }

    public void enableDebug(String target){
    LogManager.getLogger(target).setLevel(Level.DEBUG) ;
    }

    }

  3. #3
    Join Date
    Aug 2006
    Posts
    5

    Default

    I did tried this option by following the below steps

    a. Create the management bean similar to what you posted
    b. Export the bean in the application context
    <beans>
    <bean id=loggingMBean class=com.toa.Log4jMBean/>
    <bean id=exporter class=org.springframework.jmx.export.MBeanExporter >
    <property name=beans>
    <map>
    <entry key=bean:name=appllogging value-ref=loggingMBean/>
    </map>
    </property>
    </bean>
    </beans>

    c. then I tried to run the applicaton in weblogic 9.1 by using following java system property
    Dcom.sun.management.jmxremote

    d. Ran JConsole to view mbeans and was able to see my applogging bean with all the methods but when I try to invoke them it has no impact on log levels of application. Still I see application reacts the way it is defined in log4j.xml file.

    Is this approach correct, if yes what is that I am missing here, Can we totally eliminate the need of log4j.xml.
    Do we need to pass anything for target parameter in the method of your example from jmx console.

    Thanks,
    Kris.

  4. #4
    Join Date
    Mar 2005
    Location
    San Francisco, CA
    Posts
    114

    Default

    I don't have a JMX solution, but here is a single-page JSP approach. Save this file as log4j.jsp.
    Code:
    <%@ page import="org.apache.log4j.*" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <html>
    <head><title>Dynamic Log4J Control</title></head>
    <body>
    <h1>Dynamic Log4J Control</h1>
    <%  String logName=request.getParameter("log");
        if (null!=logName) {
            Logger log=("".equals(logName) ? 
                Logger.getRootLogger() : Logger.getLogger(logName));
            log.setLevel(Level.toLevel(request.getParameter("level"),Level.DEBUG));
        } 
    %>
    <c:set var="rootLogger" value="<%= Logger.getRootLogger() %>"/>
    <form>
    <table border="1">
    <tr><th>Level</th><th>Logger</th><th>Set New Level</th></tr>
    <tr><td>${rootLogger.level}</td><td>${rootLogger.name}</td><td>
        <c:forTokens var="level" delims="," items="DEBUG,INFO,WARN,ERROR,OFF">
            <a href="log4j.jsp?log=&level=${level}">${level}</a>
        </c:forTokens>
    </td></tr>
    <c:forEach var="logger" items="${rootLogger.loggerRepository.currentLoggers}">
        <c:if test="${!empty logger.level.syslogEquivalent || param.showAll}">
            <tr><td>${logger.level}</td><td>${logger.name}</td><td>
            <c:forTokens var="level" delims="," items="DEBUG,INFO,WARN,ERROR,OFF">
                <a href="log4j.jsp?log=${logger.name}&level=${level}">${level}</a>
            </c:forTokens>
            </td></tr>
        </c:if>
    </c:forEach>
    <tr><td></td><td><input type="text" name="log"/></td><td>
    <select name="level">
        <c:forTokens var="level" delims="," items="DEBUG,INFO,WARN,ERROR,OFF">
            <option>${level}</option>
        </c:forTokens>
    </select> <input type="submit" value="Add New Logger"/></td></tr>
    </table>
    </form>
    Show <a href="log4j.jsp?showAll=true">all known loggers</a>
    </body>
    </html>

  5. #5
    Join Date
    Aug 2006
    Posts
    129

    Default

    you need the pass the package name as target

    (com.toa,org.springframework)

    you see the result when you define a quartz job which logs
    every invocation as info and change the log level to error

    you do not need to pass full package name

    add this method to you logbean to see the changes

    public String list(){
    StringBuffer html = new StringBuffer("<ul type=square>");
    Enumeration loggers = LogManager.getCurrentLoggers();
    Logger logger;
    while(loggers.hasMoreElements()){
    logger = (Logger) loggers.nextElement();
    html.append("<li>"+logger.getName()+"<dd>"+logger. getEffectiveLevel()+"</dd></li>");
    }
    return html.append("</ul>").toString();
    }

  6. #6
    Join Date
    Aug 2006
    Posts
    5

    Default

    Quote Originally Posted by wims.tijd
    you need the pass the package name as target

    (com.toa,org.springframework)

    you see the result when you define a quartz job which logs
    every invocation as info and change the log level to error

    you do not need to pass full package name

    add this method to you logbean to see the changes

    public String list(){
    StringBuffer html = new StringBuffer("<ul type=square>");
    Enumeration loggers = LogManager.getCurrentLoggers();
    Logger logger;
    while(loggers.hasMoreElements()){
    logger = (Logger) loggers.nextElement();
    html.append("<li>"+logger.getName()+"<dd>"+logger. getEffectiveLevel()+"</dd></li>");
    }
    return html.append("</ul>").toString();
    }
    Hi,

    Thanks a lot, it worked I appreciate your timely help.
    Please let me know if there any limitations with this approach.

    Thanks,
    Kris.

  7. #7
    Join Date
    Aug 2006
    Posts
    5

    Default

    Are there any limitations with this approach? does this work in appiications deployed across different nodes in a cluster.

    Thanks,
    Kris

  8. #8
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Depends on your application server JMX implementation - if the calls are spread across the rest of the JMX servers, then yes.
    Check your cluster configuration - note that with JMX one can create hierarchical servers (for example using jManage).
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  9. #9
    Join Date
    Aug 2006
    Posts
    5

    Default

    we have our application deployed on weblogic 9.1 on three nodes in a cluster and we are trying to achieve dynamic changes to log levels during runtime with no code or property file changes. In this scenario I was trying to understand whether this approach (JMX implementation for log4j) works with impact.

    Thanks,
    Kris

  10. #10
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    The JMX specs do not cover clustering or federation (grouping a set of JMX servers into one group so calls on the group are propagated to each individual server which in turn, can have other sub groups). This feature along with others are covered, AFAIK, by the next JMX iteration.
    That's why, at the moment, you'll have to rely on other tools or libraries to provide this functionality for you.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •