The Artima Developer Community
Sponsored Link

Weblogs Forum
The evolution of the remote Log Manager

3 replies on 1 page. Most recent reply: Feb 15, 2005 10:00 AM by Gregg Wonderly

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 3 replies on 1 page
Gregg Wonderly

Posts: 317
Nickname: greggwon
Registered: Apr, 2003

The evolution of the remote Log Manager (View in Weblogs)
Posted: Jan 31, 2005 5:19 PM
Reply to this message Reply
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.


Luis Matta

Posts: 6
Nickname: levmatta
Registered: Oct, 2004

Re: The evolution of the remote Log Manager Posted: Feb 1, 2005 11:41 AM
Reply to this message Reply
I liked this blog a lot. Keep them comming PLEASE.
(This comments are a little of your main topic.)
(Please bear in mind that I am just starting with this things.)

Also, what is your remote implementation of the input stream, are you taking in consideration position and number of bytes the client whant's (the one that receives the log data). This is a very hyped use case for Jini (separating client interface from actual implementation interfaces), but I would like to see how real people are using it.

Further of your topic: how are u using the UUID; how are you connecting the client with the server? (Yes I did understand some of the article). My problem is the sequence of actions, and who implements these interface. Can you explain the software structure further (possible future blogs :-)?

Thanks a lot.

Demetrie Gerodimos

Posts: 2
Nickname: amilla
Registered: Jan, 2005

Re: The evolution of the remote Log Manager Posted: Feb 9, 2005 11:57 AM
Reply to this message Reply
A quick solution we have been coding involves log4j+log4net with a UDP appender, and multiple clients listening for trace broadcasts. We achieved consistency across .net/j2ee platforms, and created ui consoles and headless services to sink traces. This implimentation seems more polished, good job.

Gregg Wonderly

Posts: 317
Nickname: greggwon
Registered: Apr, 2003

Re: The evolution of the remote Log Manager Posted: Feb 15, 2005 10:00 AM
Reply to this message Reply
> Also, what is your remote implementation of the input
> stream, are you taking in consideration position and
> number of bytes the client whant's (the one that receives
> the log data).

The client gets an InputStream. This stream does not support mark(). The client is able to use the API as they
see fit. In other applications, I've put an ObjectInputStream() on top of the InputStream so that the server can send serialized data to the client.

> Further of your topic: how are u using the UUID; how are
> you connecting the client with the server? (Yes I did
> understand some of the article). My problem is the
> sequence of actions, and who implements these interface.
> Can you explain the software structure further (possible
> future blogs :-)?

The Uuid is written from the client to the server so that random connections into the server can't occur to exploit that open connection for DOS or other attacks. After the client connects and IDs, the ServerSocket is closed.

Again, you can look at the http://logman.jini.org website for more information and access to the sources.

Flat View: This topic has 3 replies on 1 page
Topic: A Layering Challenge Previous Topic   Next Topic Topic: Polymorphism without Planning

Sponsored Links



Google
  Web Artima.com   

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