He works with Java since 1999. At the moment he is as IT-Consultant at Logica Deutschland GmbH & Co. KG in Frankfurt. Andriy has posted 3 posts at DZone. View Full User Profile

Non-Stop Control of Logging Level

07.07.2009
| 6185 views |
  • submit to reddit

Sometimes there is a need to change the logging level in the some modules of an application server. This usually isn't managed easily: the change the logging level means a restart of the server in most cases. This is not always required, but is in most cases.

The restart of one application server in production operation is not really good idea. But if the application server or one its module doesn't operate correctly it is very useful to obtain the log file with debug logging-level. As the logging will usually be performed in INFO or ERROR level to save the unnecessary I/O operations and CPU overhead, with such logging levels it is very hard to analyse the problem. So, what have we do?

If the application server runs under JVM 1.5 or higher and uses the Spring framework there is one logical way to painlessly change the logging level: use a Java Management Extension.

Step 1: Create a bean with a logic to change the logging level.

For a simplicity, we change the level of the root logger only. The class needs two methods: get logging level for root logger and a method to set that level. The Logging framework used here is the popular log4j logger. The functionality is almost the same as other useful loggers. Every logger created exists only in a single instance, so you can call getRootLogger() method as often as you want without the problem of having many root-logger instances. To make our code compact I am using the annotations. It allows me to keep the code with a static data definitions, such as method description. The use of annotations is a tool, but not the objective. You can also achieve your aim  without annotations.

 @ManagedResource(objectName="Custom:type=Management,name="Log4j Logging", description="Log4j Managed Bean")
public class Log4jMBean
{
@ManagedAttribute(description="get the logging level to the root logger")
public String getRootLogLevel()
{
Logger root = Logger.getRootLogger();
Level level = root.getLevel();
return level;
}

@ManagedAttribute(description="set the new logging level to the root logger")
public void setRootLogLevel(String newLevel)
{
Logger root = Logger.getRootLogger();
Level level = Level.toLevel(newLevel);
root.setLevel(level);
}
}

There is no error checking, package or import statements in code. That class is simply a Java bean class with the spring-jmx annotations

Step 2: Load and register the logic.

The bean alone is not enough. Something must load that bean and allow remote access to it. Spring is the best choice here. We need a applicationContext-logcontrol.xml with some lines of code. That code informs Spring about  Log4jMBean and also says that this bean must be registered in the MBeanServer.

<config:annotation-config />
<context:mbean-export default-domain="Custom" registration="ignoreExisting" />
<bean id="log4jBean" class="my.company.jmx.Log4jMBean" />

That is all the code! Some explanation:
  • First line - says to the Spring framework that the code contains some annotations
  • Second line - calls the Spring mbean exporter and tells it to ignore our beans that are already registered in the MBeanServer
  • Third line - declares the bean to load within the Spring framework

I have missed the namespaces declaration. These have to be declared the context namespace.
Compile and package the two files to an JAR file. Place the xml file in a subdirectory, for example "conf".

Step 3: Use the package with Spring framework

Now the application server must use our library. Place your package on the classpath, for example WEB-INF/lib directory of the application. Place a line in one of Spring context xml files of the web application with the logging level you want to control.

That allows to load your Log4jMBean class and perform the registration of their instance at MBeanServer, wenn the web application starts up. The Spring framework automatically looks into the jar files in WEB-INF/lib directory and search for applicationContext-logcontrol.xml file. The access to the bean will be performed by JMX. By default, there is no activated JMX feature on a  JVM of version 1.5+, but you can activate it by means of set the command-line parameters for JVM. For example, the environment variable "JAVA_OPTS" allows to set any command-line parameters for Tomcat server.

The simpliest way to activate the access to MBeanServer is to start the JVM with such parameters:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=XXXX
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

where, the XXXX is an unused port of the system. The JavaVM activates MBeanServer and listens the port XXXX for incoming JMX connections.

Now, you can connect with the jconsole.exe programme from the JDK 1.5+ installation directory of your server, choose the page and look for the actual loggers and their logging-levels.

3
Your rating: None Average: 3 (2 votes)
Published at DZone with permission of its author, Andriy Maksymov.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Ran Biron replied on Wed, 2009/07/08 - 4:48am

Wouldn't it just be easier to monitor the configuration file for changes? Like log4j and most other (sane) log impementations?

Burkhard Graves replied on Wed, 2009/07/08 - 6:12am in response to: Ran Biron

Your suggestion would only work for expanded WAR files. Moreover there should be some problem with log4j's watchdog - see API of Spring's Log4jWebConfigurer and/or http://furiouspurpose.blogspot.com/2008/04/log4jwebconfigurer-not-suited-for-j2ee.html

 

Javin Paul replied on Mon, 2011/05/02 - 4:08am

Agree with Ran, log4j does samething by using watchdog thread which monitors on change in log4j.xml but I think JMX is more flexible way of doing it , with indroduction of MX4j you can have JMX page open on your browser and can easily change logging level without restarting system. you can also put authentication on JMX page to avoid any unauthorized access.

Javin
10 tips on logging in Java

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.