Browse DevX
Sign up for e-mail newsletters from DevX


Build a Distributed Logging Framework Using Java RMI : Page 3

The new J2SE logging API brings Java developers a variety of ways to perform logging. One thing you can do is to build a logging framework for your distributed and multithreaded Java applications with Java RMI.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Remote Log Access and Runtime Log-level Control
Because logs reside on each host, I need a way to remotely access these logs and, in addition, a method to control the logging levels for a host application. Java RMI is a natural choice under this circumstance, as it hides the low-level network communication details from the application logic.

The following code gives the definition of the LogServer RMI interface that each host application needs to implement for remote logging access and control.

public interface LogServer extends Remote { public LogRecord[] read() throws java.rmi.RemoteException; public void clear() throws java.rmi.RemoteException; public void setClassLogLevel(String className, Level logLevel) throws java.rmi.RemoteException; public Level getClassLogLevel(String className) throws java.rmi.RemoteException; public void setThreadLogLevel(String threadName, Level logLevel) throws java.rmi.RemoteException; public Level getThreadLogLevel(String threadName) throws java.rmi.RemoteException; }

The read() method returns all the existing log records. The clear() method removes all the log records. The setClassLogLevel()/getClassLogLevel() methods configure/query a class or package's current logging level. The setThreadLogLevel()/getThreadLogLevel() methods configure/query a thread's current logging level (I will address logging by thread in the next section).

As mentioned previously, LogRecord and Level can be used in this remote interface because they are both serializable.

LogServerImpl implements the LogServer interface; most of its methods are straightforward. Here is the source code for all the methods except those that are thread-logging related:

public class LogServerImpl extends UnicastRemoteObject implements LogServer { ... public LogRecord[] read() throws RemoteException { return memHandler.getRecords(); } public void clear() throws RemoteException { memHandler.removeAllRecords(); } public void setClassLogLevel(String className, Level logLevel) { Logger.getLogger(className).setLevel(logLevel); } public Level getClassLogLevel(String className) { Level level = Logger.getLogger(className).getLevel(); return (level == null) ? Level.OFF : level; } public void logByClass(Class cls, Level level, String msg) { Logger logger = Logger.getLogger(cls.getName()); logger.log(level, msg); } ... }

What I need to do next is expose the interface through the RMI registry. The following code shows the start() function of the LogServerImpl class, which exposes the interface in RMI.

public void start() { // Create and install a security manager if (System.getSecurityManager() == null) { System.setSecurityManager( new RMISecurityManager()); } try { // Bind this object to the name // LogServer.SERVICE_NAME Naming.rebind(LogServer.SERVICE_NAME, instance); } catch (Exception e) { e.printStackTrace(); } }

LogShell is a command-line utility for log access and control on a remote host. LogShell can talk to the host application only after the LogServer interface is published through RMI, so for it to work properly, each host application must invoke the start() function before making any logging requests. Figures 2 and 3 show LogShell being used to view log records and change log levels, respectively.

Figure 2: Here, LogShell is used to view and clear log records from a remote host.
Figure 3: LogShell changes and checks logging level for a class on a remote host.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date