The Standard Log RMIs Logging Facilities

In addition to a distributed garbage collector, the RMI runtime also provides a fairly extensive logging facility that enables you to track the behavior of your applications. Unfortunately, RMIs logging is somewhat idiosyncratic. There are actually three different types of logs: the standard log, the specialized logs there are five of these, and the debugging log.

16.3.1 The Standard Log

The standard log is easy to use. You turn it on and off using the java.rmi.server.logCalls system property. This is a boolean system property. Note that this property can either be set at the command line or in code. There is no functional difference between the command line invocation: java -Djava.rmi.server.logCalls=true [other stuff] and using: java [same other stuff] to invoke a program that contains the line: System.getProperties .putjava.rmi.serverr.logCalls, true; Actually, this isnt quite true. At the command line, you always have permission to set system properties. Depending on your security policy, a program might not have permission to do so. Well explore this more in Chapt er 20 . Once youve turned logging on, you need to set the logging destination. This is done by using one of the static logging methods defined in the RemoteServer class, which is defined in the java.rmi.server package. The methods are: public static PrintStream getLog public static void setLogOutputStream out The first retrieves the stream currently used to do logging, and the second allows you to set it. The most common use of these is dumping to a simple log file, as in the following code snippet: private void setLogFile { try { FileOutputStream logFile = new FileOutputStreamC:\\temp\\foo; RemoteServer.setLoglogFile; } catch Exception e { System.out.printlnFailed to open log file; } } By default, the logging system uses System.err . That is, if you enable standard logging but dont specify where the logging messages should go, they will show up on System.err . You have to set the logging destination before you invoke any RMI methods. Once RMI starts logging to a particular PrintStream , it keeps logging to that PrintStream . The standard log records method calls that went through RMI and exceptions that were thrown by the server in the thread that handled the method call. Heres some output from a fairly typical log file: [ 2] [ 2] All of the logging output shown in this chapter was generated using the com.ora.rmibook.chapter16.LoggingImpLau ncher class. Sun Oct 29 19:26:53 PST 2000:RMI:RMI TCP Connection2 - 127.0.0.1:[127.0.0.1: sun.rmi. transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirtyjava.rmi.server.ObjID[], long, java.rmi.dgc.Lease] Sun Oct 29 19:26:53 PST 2000:RMI:RMI TCP Connectio n2- 127.0.0.1:[127.0.0.1: sun.rmi. transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirtyjava.rmi.server.ObjID[], long, java.rmi.dgc.Lease] Sun Oct 29 19:27:02 PST 2000:RMI:RMI TCP Connection3 - 127.0.0.1:[127.0.0.1: sun.rmi. transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirtyjava.rmi.server.ObjID[], long, java.rmi.dgc.Lease] Sun Oct 29 19:27:02 PST 2000:RMI:RMI TCP Connection3 - 127.0.0.1:[127.0.0.1: com.ora. rmibook.chapter9.Account_Impl[0]: public abstract strictfpcom.ora.rmibook.chapter9. valueobjects.Money com.ora.rmibook.chapter9.Account.getBalance throws java.rmi. RemoteException] Sun Oct 29 19:27:22 PST 2000:RMI:RMI TCP Connection3 - 127.0.0.1:[127.0.0.1: sun.rmi. transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirtyjava.rmi.server.ObjID[], long, java.rmi.dgc.Lease] Sun Oct 29 19:27:22 PST 2000:RMI:RMI TCP Connection3 - 127.0.0.1:[127.0.0.1: com.ora. rmibook.chapter9.Account_Impl[1]: public abstract strictfp com.ora.rmibook.chapter9. valueobjects.Money com.ora.rmibook.chapter9.Account.g etBalance throws java.rmi. RemoteException] Each of these lines records a method call and has a rather verbose format. The first line, for example, can be translated as follows: On Sunday Oct. 29, 19:26:53 PST 2000, a client called an instance of sun.rmi.transport.DGCImpl which had object identity [0;0:0:2]. The method dirty was invoked, and no exception was thrown. There are several interesting things here. The first is that the distributed garbage collector really is an RMI server; you can watch the distributed garbage collector, and see how it is behaving, simply by watching the method flow. The second interesting point is that theres an awful lot of leasing traffic going on here. The problem is that you cant tell any of this from the method call log. Practically speaking, while you can watch the distributed garbage collector work, you cant get much information from the transcript. For example, the leases being negotiated in this transcript are, in order, from: • The registry, opening a lease for the server named Bob • The registry, opening a lease for the server named Alex • The client, opening a lease for the server named Bob • The client, opening a lease for the server named Alex However, I was able to figure that out because I had a fair amount of other information about the servers which I used when looking at the log. Method call logs are not particularly useful unless youre watching them under carefully controlled conditions e.g., in which you do something and then immediately see associated entries in the log.

16.3.2 The Specialized Logs