Java Logging Assignment: Creating LocalLog and RemoteLog - Prof. Michael W. Hicks, Assignments of Programming Languages

Instructions for a java programming assignment in which students create a logging infrastructure for notable events in a program. The assignment covers creating loggable events using the logrecord class, implementing a log for collecting events using the log interface, and creating an api for using the log in programs using the logger class. For the final part of the assignment, students implement a distributed version of the log interface using remotelogclient and remotelogserver classes.

Typology: Assignments

Pre 2010

Uploaded on 02/13/2009

koofers-user-jcf
koofers-user-jcf 🇺🇸

10 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Homework 1
CMSC 433
Programming Language Technologies and Paradigms
Fall 2002
Due September 24, 2002
Introduction
In this project, you will create a simple infrastructure for logging messages in
your programs. The pro ject has three goals:
Create a simple debugging infrastructure for your own use.
Get some experience with Java interfaces and the ideas of abstraction and
code reuse.
Create a simple server for later expansion.
The logging system will be built in a number of steps, outlined below. We will
be building a simplification and variation of the Java 1.4 java.util.logging
package. You may wish to refer to the generated documentation1for all of
the classes that you will be using and writing in this assignment. All provided
Java files for this assignment can be found at http://www.cs.umd.edu/class/
fall2002/cmsc433-0201/hw1/java/. You can also get this assignment in PDF
and postscript.
1 Logging events
Alog collects and performs computations on notable events in a program, like
method entry and exit, thread creation, or whatever the programmer finds of
interest for a particular application. Before we can collect events, we have to
define what they are. This part of the homework defines a class for noteworthy
(loggable) events.
1http://www.cs.umd.edu/class/fall2002/cmsc433-0201/hw1/docs/
pf3
pf4
pf5
pf8

Partial preview of the text

Download Java Logging Assignment: Creating LocalLog and RemoteLog - Prof. Michael W. Hicks and more Assignments Programming Languages in PDF only on Docsity!

Homework 1

CMSC 433

Programming Language Technologies and Paradigms

Fall 2002

Due September 24, 2002

Introduction

In this project, you will create a simple infrastructure for logging messages in your programs. The project has three goals:

  • Create a simple debugging infrastructure for your own use.
  • Get some experience with Java interfaces and the ideas of abstraction and code reuse.
  • Create a simple server for later expansion.

The logging system will be built in a number of steps, outlined below. We will be building a simplification and variation of the Java 1.4 java.util.logging package. You may wish to refer to the generated documentation^1 for all of the classes that you will be using and writing in this assignment. All provided Java files for this assignment can be found at http://www.cs.umd.edu/class/ fall2002/cmsc433-0201/hw1/java/. You can also get this assignment in PDF and postscript.

1 Logging events

A log collects and performs computations on notable events in a program, like method entry and exit, thread creation, or whatever the programmer finds of interest for a particular application. Before we can collect events, we have to define what they are. This part of the homework defines a class for noteworthy (loggable) events.

(^1) http://www.cs.umd.edu/class/fall2002/cmsc433-0201/hw1/docs/

1.1 The LogRecord class

Loggable events are implemented as objects of the class LogRecord. Essentially a LogRecord notes an event, stored as a string, along with the time the event took place and a number to “uniqueify” the event. The public methods of this class you must implement are shown below:

public class LogRecord { public LogRecord(String event); public String getEvent(); public java.util.Date getTimestamp(); public String toString(); public void format(java.io.PrintWriter out); public static LogRecord fromFormat(java.io.BufferedReader in); }

Documentation that describes this class is found at http://www.cs.umd.edu/ class/fall2002/cmsc433-0201/hw1/docs/LogRecord.html. Some notes:

  1. The event ID should be unique to all LogRecords, so you should use a global counter to ensure this.
  2. The String returned by toString should have the following format: date / #id / event That is, output the LogRecord fields in order of timestamp, id, and event, and put a / in between each, and a # before the id. This results in output like the following:

Mon Aug 26 13:51:50 EDT 2002 / #2 / Exiting: HeapSortAlgorithm.downheap

  1. The format and fromFormat methods are going to be used in part ?? to communicate LogRecords between a client and server. Here is the way we suggest you implement them: - For format, you will output the fields of the LogRecord one at a time, e.g. event ID followed by timestamp followed by event. Each one will be separated by an unambiguous field separator to allow them to be easily read in by fromFormat. - The field separator for all fields in the LogRecord will be the newline (so newlines are not allowed in ID or event strings) - For the purpose of formatting a java.util.Date object, use a String representation of the Date as value of type long that represents the number of milliseconds since the beginning of Unix time, January 1, 1970, 00:00:00 GMT. See Date.getTime() and the wrapper class Long for more on how to do this.

routines. Running this program will result in sorting an array, and printing out all of the logged events at the conclusion, resulting in output like the following:

Mon Aug 26 13:51:50 EDT 2002 / #0 / Entering: HeapSortAlgorithm.sort Mon Aug 26 13:51:50 EDT 2002 / #1 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #2 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #3 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #4 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #5 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #6 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #7 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #8 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #9 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #10 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #11 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #12 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #13 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #14 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #15 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #16 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #17 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #18 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #19 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #20 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #21 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #22 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #23 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #24 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #25 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #26 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #27 / Entering: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #28 / Exiting: HeapSortAlgorithm.downheap Mon Aug 26 13:51:50 EDT 2002 / #29 / Exiting: HeapSortAlgorithm.sort

To use HeapSortAlgorithm.java, you will need to actually implement the Log interface, and change the first line of the main method to be something like:

log = new Logger(new LocalLog(100));

where LocalLog is an implementation of Log, described next.

3 A Local Log: the LocalLog class

The LocalLog class is a local implementation of the Log interface, and has the following skeleton:

public class LocalLog implements Log {

public LocalLog(int logSize); public void add(LogRecord record); public LogRecord[] getAll(long windowMS); public void setFilter(String strPat); public String toString(); }

The middle three methods implement the Log interface, while the first is the sole constructor for the class, and the last is a convenience routine for printing the contents of the log. You should implement LocalLog to keep track of records by storing them in some aggregation datastructure, such as an array, or an implementation of the java.util.Collection interface. Some notes:

  1. So that the log does not grow without bound, you must fix its size; this size is set by the logSize parameter to the constructor. If an attempt is made to add a record to a log that is full, the oldest record should be discarded before the new record is added.
  2. Choose your underlying datastructure so that you can easily implement getAll and add. That is, what datastructure allows you to easily discard the oldest record when the log is full? What datastructure allows you to easily determine and collect what records are of a certain age?

4 A Remote Log

For the final part of the assignment, you are to implement a distributed version of the Log interface. In particular, implement two classes RemoteLogClient and RemoteLogServer, where the former class implements the Log interface, but does so by communicating with the latter class, which is running in another process, possibly on a remote machine. It is in this process that the log records are stored and the commands are actually carried out.

4.1 The RemoteLogServer class

The skeleton of the RemoteLogServer class as follows:

public class RemoteLogServer { private Log log; RemoteLogServer(int port, int logSize); public static void main(String[] args); }

The constructor for RemoteLogServer takes as its arguments a port on which to listen for TCP connections, and the size logSize of the log it is keeping. When the constructor is called, it does two things. First, it instantiates its private Log instance variable with a LocalLog having the specified size. This is the data to

Log

LocalLog RemoteLogClient

RemoteLogServer Logger

LogRecord

Figure 1: Class/Interface relationship for Logging package

public void setFilter(String pattern); }

The constructor for RemoteLogClient takes as its arguments a java.net.InetAddress addr as the machine to which to connect, and a port to use for TCP connec- tions. These correspond to the machine name on which the RemoteLogServer is running and the port on which it is listening for connections. These arguments are simply stored in the RemoteLogClient when the constructor is called. When one of the remaining methods is called, RemoteLogClient will connect to the RemoteLogServer, send a command, retrieve the result (if any), and close the connection. Connections only remain open for the duration of a single command. The format of commands is as described for the RemoteLogServer class above. For the getAll method, the retrieved result will be a list of formatted LogRecords. You should therefore invoke the LogRecord.fromFormat method to turn these into LogRecord instances, until no further data is available. Finally, you should allow the client to get the host and port number of the server to connect to from the command line. That is, you should be able to start your program with arguments -Dhost=hostname -Dport=portnum. Again, you can use Integer.getInteger() for this. You will want to familiarize yourself with the java.net.Socket class for implementing the client.

Final Notes

The relationships among the classes you will be writing is shown in Figure ??. The Log interface (shown in italics) is implemented by the classes LocalLog

and RemoteLogClient, as visualized by the hollow arrows. The LocalLog class stores instances of LogRecord, as visualized by a dotted arrow, while the Logger interface creates LogRecords, visualized by the unbroken arrow, to store in a Log. Finally, the RemoteLogServer stores an instance of a LocalLog for actually managing the LogRecords sent to it from RemoteLogClient’s. This diagram does not depict the socket-based interaction between RemoteLogClient and RemoteLogServer. It is worth considering at this point what you have learned. What was the benefit of making Log an interface as opposed to a class? How might you extend this infrastructure to be more useful for debugging? One obvious example would be to add more event types to the Logger interface, outside of method entry and method exit. In what ways could the design you have implemented here be improved? In particular, what changes would make it easier to use? Or make it more efficient? We will be considering the answers to these questions during the course.