Monday, November 05, 2007

Automatic Remote Logging Management via JMX.

Wow, the post title definitely sound “very technical”, and I do hope that it will attract more readers here. :-)

It all started a weeks ago, where I have accidentally discovered a “hidden JDK 5 treasure” (from Daniel Fuch, blogs http://blogs.sun.com/jmxetc/) , called java.lang.instrument, a Java package that provides services that allowing Java language agents to instrument programs running on the JVM. Most people use it for profiling, or pre-instrument purpose.


But I have a idea, why don't we create a logging management wrapper, which allows us to wrap any Java application, and provide us some logging management functionalities without any modification on our application source code. The logging agent will offer the following:

  • Abilities to change log level (debug, info, warning, error) on any configured logger dynamically without restart.
  • Abilities to locate any configured log output files.
  • Abilities to browse (either head, or tail) any configured log files.
Base on requirements above, I come out JMXMBean interface below:


public interface RemoteLoggingMBean {
  public void activateDebug(String loggerName);
public void activateInfo(String loggerName);
public void activateWarning(String loggerName);
public void activateError(String loggerName);
/**
* Retrieve current configured log output files base on given logger.
* The system will only return log files with the following appender
* org.apache.log4j.DailyRollingFileAppender, org.apache.log4j.FileAppender
* org.apache.log4j.RollingFileAppender;
* @param loggerName
* @return Array of file name with relataive file path points to current running directory.
*/
public String[] retrieveCurrentConfiguredLogFiles(String loggerName);
/**
* Similar to Unix head command, read a text file forward from the beggining
* of the file till it reaches line limit, or EOF
* @param fileName the logFileName.
* @param linesToRead, Number of line to be read.
* @return JMX CompositeData with the structure of StartFilePointer (SimpleType.Long),
* EndFilePointer(SimpleType.Long), LogMessages(SimpleType.String)
* @throws java.io.IOException
*/
public CompositeData headLog(String fileName, int linesToRead) throws OpenDataException, IOException;
public CompositeData headLog(String fileName, int linesToRead, long fromFilePointer) throws OpenDataException, IOException;
public CompositeData tailLog(String fileName, int linesToRead) throws OpenDataException, IOException;
public CompositeData tailLog(String fileName, int linesToRead, long fromFilePointer) throws OpenDataException, IOException;
}

The rest of code is delivered by using various JMX and Apache Log 4J API, which I am not going to discuss here, as this is obviously not JMX nor Java Logging tutorial.

If u interest, u could download the whole project source from here. Is not under any copy write protection. U are welcome to download it, modify it, change the author name, use it or distribute it to anyone. IMHO, The IT have to many unfair patents, or copy protection law, which in a way, have stop us on moving forward.

Anywhere, back to topic. To use the wrapper on any Java application that use Apache Log4J for logging, follows steps below:

  1. Either download the binary RemoteJMXLoggingAgent.jar, or build it from the source
  2. Put the binary to your application class path, make sure it sit together with log4j.jar
  3. Append the line at your Java Application startup script
"-javaagent:(deploy directory)/RemoteJMXLoggingAgent.jar
-Drmi.agent.port=AnyRMIPort (optional, default=3000)"


That's it, u application is now able to offer above Remote Logging management functionalities via JMX. To test this, open jconsole from any PC, and connect your remote application via the JMX URL below:
service:jmx:rmi:///jndi/rmi://hostname:rmi_port/remoteLoggerAgent

The Mbean on managing your application logger is called "org.coolboy.RemoteLoggingManager", have fun!


2 comments:

daniel said...

Hi, I'm glad you found my blog useful!
Also of interest is this article, which shows how to dynamically activate java.util.logging through JMX:
http://blogs.sun.com/jmxetc/entry/more_on_troubleshooting_with_jmx

cheers!

-- daniel

凯声 said...

Hi James, the source code is no longer exist. Where can I download it?
Thanks.