The Artima Developer Community
Sponsored Link

Software and Return on Investment
The evolution of the remote Log Manager
by Gregg Wonderly
February 1, 2005
Summary
I am finishing up the remote LogManager monitoring facilities in my http://logman.jini.org project and I'd like to share some interesting details about the implemenation.

Advertisement

A Remote Log Monitoring Facility with Jini

I created an implementation of this concept using a factory model as described in my earler blog. That implementation is visible in the project source tree at http://logman.jini.org now.

There are some interesting classes that might be useful for other applications. I needed a streaming connection for the log stream, so I created a RemoteSocketStream class that is deserialized as an InputStream. Its readObject(ObjectInputStream) method will make the connection back to the remote socket, and pass a Uuid cookie back to id with the server.

The method signature that I added to the RemoteHandler interface is shown below.

    public HandlerControl listenToLogger(
        FormatterFactory fact ) throws IOException, UnsupportedOperationException;
Initially, the remote Handler is attached to the top level of the logger name space. This will cause all LogRecords of the appropriate Level in the tree of Loggers to be sent to the client.

The Implementation...

The HandlerControl interface returned by listenToLogger(FormatterFactory) provides the ability to adjust the logging stream. It is defined as follows.
public interface HandlerControl {
	/** Get the logging data stream. */
	public InputStream getInputStream() throws IOException;

	/** Set the log level of the remote {@link java.util.logging.Handler} */
	public void setLogLevel( Level l ) throws IOException;

	/** Add a {@link java.util.logging.Logger} to the set of loggers being monitored */
	public void addLogger( String name ) throws IOException;

	/** Remove a {@link java.util.logging.Logger} from the set of loggers being monitored */ 
	public void removeLogger( String name ) throws IOException;

	/** Close the {@link java.util.logging.Logger} stream */
	public void close() throws IOException;
}
There are of course many different ways to implement the actions of this interface. I want to talk about what I did because I think the implementation shows how mobile code and custom RPC mechanisms can be used to exploit connectivity between a client and service.

My implementation of the RemoteHandler.listenToLogger(FormatterFactory) method returns a RemoteSocketStream subclass called HandlerSocketStream. The super class, RemoteSocketStream, is a serializable java.io.InputStream subclass. The deserialization code in RemoteSocketStream.readObject(ObjectInputStream) makes the Socket connection back to the server so that data can start streaming out to the remote client. The client need only start reading from the InputStream to see the logging stream.

Exploiting a Socket Connection

The HandlerControl methods are layered on top of that Socket stream. Since the path to the server is already in place, it is not necessary to use an RMI interface for controlling the server end. Instead, I chose to send simple lines of text to implement the actions of the HandlerControl interface.

The remote socket reader, at the server, reads the lines of text comming back from the client and processes lines formatted as indicated below.

+
Add the indicated logger to the list of monitored loggers.
-
Remove the indicated logger from the list of monitored loggers.
=
Set the remote Handler Level to the indicated level.

Result is that the HandlerControl implementation does not need to be an RMI proxy. Instead, it is a Serializable class that uses a socket connection back to the service to implement the methods of the interface.

Solving the Reverse Path Problem

In the world of the Internet, and other places where Network Address Translation and Firewalling exists, there is not always a bidirectional, fully routable path between computers. Typically, a client computer will not be accessible from a server for connection initiation. Thus, in cases like this where a stream of data, generated at the server, needs to flow to the client, the implementation needs to be able to deal with this issue.

The solution developed here solves this problem by having the client make the connection to the server. This allows the route from the server to the client to not be an issue. When you develop services that you need to remotely adminster in remote networks, this type of solution can simplify several issues.

Summing it all Up

When you need a stream from a server to a client, consider a solution such as the RemoteSocketStream class I've created. It allows you to use a bi-directional path between the client and server to make simple RPC activities possible. The important thing to remember is that this works good for void method calls. But for method calls that return values, you might have to recreate multi-threaded call and return handling, or insert synchronization to force isolation through synchronization. It will depend on whether only one, or multiple threads might use this socket stream for traffic toward the server at the same time. In many cases there are no multi-threading issues, and you can stick synchronized on the method declarations to force synchronization in case the usage changes. This API has all void methods, so the only synchronization necessary is in the I/O operations toward the server. So that the complete String representing the command goes out in an atomic write operation.

Talk Back!

Have an opinion? Readers have already posted 3 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Gregg Wonderly adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Gregg Wonderly graduated from Oklahoma State University in 1988 with an MS in COMSCI. His areas of concentration include Operating Systems and Languages. His first job was at the AT&T Bell Labs facilities in Naperville IL working on software retrofit for the 5ESS switch. He designed a procedure control language in the era of the development of Java with similar motivations that the Oak and then Java language development was driven by. Language design is still at the top of his list, but his focus tends to be on application languges layered on top of programming languages such as Java. Some just consider this API design, but there really is more to it! Gregg now works for Cyte Technologies Inc., where he does software engineering and design related to distributed systems in highly available environments.

This weblog entry is Copyright © 2005 Gregg Wonderly. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use