Aspect-oriented system monitoring and tracing6473895Abstract An aspect oriented system for implementing system monitoring and tracing is provided in which the monitoring and tracing functionality needs not be coded into the resources being monitored or traced. Rather, an aspect is provided which encapsulates the monitoring/tracing behavior. This behavior may easily and transparently be forced onto the resource by compiling the object class for the resource along with the monitoring/tracing aspect. When the monitoring/tracing is no longer needed, it is removed simply by recompiling the resource object classes without the aspect. Claims What is claimed is: Description FIELD OF THE INVENTION
TABLE 1
DocumentServer Resource Object Class
public class DocumentServer {
private Monitor monitor;
private int serverid;
DocumentServer(Monitor m, int id) {
monitor = m;
serverid = id;
}
public Document convert(Document d, Format f) {
monitor.anEvent(new ServiceEvent(this));
try ( return convertData(d, f); }
catch (Exception e) {
monitor.anEvent(new ExceptionEvent(this, e));
}
finally {
monitor.anEvent(new CompletionEvent(this));
}
}
public void newDocument(Document d) {
monitor.anEvent(new ServiceEvent(this));
try { addDocument(d); }
catch (Exception e) {
monitor.anEvent(new ExceptionEvent(this, e));
}
finally {
monitor.anEvent(new CompletionEvent(this));
}
}
public int getId() { return id; }
}
Each resource object 150 must include behavior to interact (e.g., the italicized lines in Table 1) with the system monitor object 170, and the system monitor object must include behavior to interact (e.g., the parameter e.obj.getId( ) in Table 2) with the resource object 140. Exemplary code for the corresponding object class implementing the system monitor appears in Table 2, below. The code displayed in italics, e.obj.getId( ), implements a request from the monitor object to the resource object for information concerning a condition or event.
TABLE 2
Monitor Object Class Definition
public class ServiceMonitor {
private int totalServiceRequests, totalExceptions,
totalCompletions;
void anEvent(ServiceEvent e) {
printMessage("Service Request for server" + e.obj.getId());
totalServiceRequests++;
}
void anEvent(ExceptionEvent e) {
printMessage("Exception in server + e.obj.getId());
total Exceptions++;
}
void anEvent(CompletionEvent e) {
printMessage("Service Completion for server" + e.obj.getId());
totalCompletions++;
}
void printMessage(String msg) {
System.out.println("Monitor:" + msg);
}
}
Each resource object class to be monitored must be coded in a manner such as described for the document server class 140. So, for a system with a large number of resources to be monitored, this coding becomes increasingly complex and difficult to keep track of. FIG. 2 depicts a first way of implementing system monitoring according to the present invention. The system 200 to be monitored includes a number of resources such as in prior art system 100, as well as object 250 for providing access to the resources. A database server class 210 is provided for instantiating objects for storing and retrieving data in a database (not shown), a printer server class 220 is provided for instantiating objects for outputting information, a web server class 230 is provided for instantiating objects implementing hosting services for a World Wide Web (WWW) site (not shown), and a document server class 240 is provided for instantiating objects for storing and retrieving documents. Each of these servers may be practiced with a general purpose computing device such as a personal computer of a type known in the prior art. Each of these servers may also be practiced with special purpose workstations, dedicated to particular job functions, of types that are known in the art. Each of these server resources 210-240 will typically be accessed by one or more client computers (not shown) to service various types of requests. In this first embodiment of system monitoring, a monitor object class 260 is provided for instantiating a monitor object 220. The monitor object implements behavior for receiving and reacting to notification of a condition or an event. A monitor aspect 280 is also provided which provides for the detection and notification of the condition or event. In this embodiment of the present invention, the programming for the actual monitoring function is separated from the portions of the system 200 implementing the resources, and is implemented by a monitor aspect 280. The monitor aspect 280 modifies the functionality of the resource object classes 210-240 so that when a particular condition or event of interest occurs in an object's associated resource, the corresponding resource object instance 250 notifies the monitor object 270. Thus, neither the resource objects 250 nor the monitor object 270 are aware of the monitor aspect 280. The monitor aspect 280 does this by transparently forcing its behavior on the resource object definitions 210-240. In this embodiment, the code for the DocumentServer Resource Object Class may be devoted to implementing the resource functionality, such as shown in Table 3. The only monitoring behavior that is necessary is the public int getId( ) {return id;} method, which permits a monitor object to request information from the resource object.
TABLE 3
DocumentServer Resource Object Class
public class DocumentServer {
private int serverid;
DocumentServer(int id) {
serverid = id;
}
public Document convert(Document d, Format t) {
return convertData(d, f);
}
public void newDocument(Document d) {
addDocument(d);
}
public int getId() { return id; }
}
Tables 4 and 5, below, illustrate an exemplary monitor class definition 260 and a monitoring aspect definition 280 according to the present invention, respectively. Note that the code in Table 4 is the same as that in Table 2.
TABLE 4
Monitor Object Class Definition
public class ServiceMonitor {
private int totalServiceRequests, total Exceptions,
totalCompletions;
void anEvent(ServiceEvent e) {
printMessage("Service Request for server" + e.obj.getId());
totalServiceRequests++;
}
void anEvent(ExceptionEvent e) {
printMessage("Exception in server" + e.obj.getId());
total Exceptions++;
}
void anEvent(CompletionEvent e) {
printMessage("Service Completion for server" + e.obj.getId());
totalCompletions++;
}
void printMessage(String msg) {
System.out.println("Monitor:" + msg);
}
}
In this embodiment, the monitor object encapsulates the functionality for receiving and responding to a notification of the detection of a condition in the resource. Exemplary code for the monitoring aspect definition 280, shown in Table 5, below, encapsulates the monitoring functionality for detecting a condition and sending a notification of the detection to the monitor object 220. This monitoring functionality is the behavior that will be transparently forced on the resource object classes 210-240 when the system 200 is compiled.
TABLE 5
Monitor Aspect Definition
aspect ServiceMonitoringProtocol {
static ServiceMonitor monitor = new ServiceMonitoring();
introduce ServiceMonitor DatabaseServer.monitor = monitor;
introduce ServiceMonitor WebServer.monitor = monitor;
introduce ServiceMonitor PrinterServer.monitor = monitor;
introduce ServiceMonitor DocumentServer.monitor = monitor;
advise * DatabaseServer.query(..), * WebServer.post(..),
* WebServer.get(..), * PrinterServer.print(..),
* DocumentServer.convert(..),
* DocumentServer.newDocument(..) {
static before {
monitor.anEvent(new ServiceEvent(thisObject));
}
static catch (RuntimeException e) {
monitor.anEvent(new ExceptionEvent(thisObject, e));
throw e;
}
static finally {
monitor.an Event(new CompletionEvent(thisObject));
}
}
}
The behavior of the aspect is forced on the object class using a compiler that is aspect-oriented, i.e., one that can handle aspects. Such a compiler compiles the object class definitions and aspect definitions of a system such that the code from the aspects affects the behavior of the objects. Such a compiler is described in greater detail in copending patent application, U.S. Ser. No. 09/358,638, entitled AN ASPECT-ORIENTED PROGRAMMING INTEGRATED DEVELOPMENT ENVIRONMENT, filed concurrently with the present application and assigned to the present assignee, and is hereby incorporated into the present specification by reference. FIG. 3 depicts a second way of implementing system monitoring according to the present invention. The exemplary system 300 includes a number of resources such as in prior art system 100, as well as object classes for providing access to the resources. A database server class 310 is provided for instantiating objects for storing and retrieving data in a database, a printer server class 320 is provided for instantiating objects for outputting information, a web server class 330 is provided for instantiating objects implementing hosting services for a World Wide Web (WWW) site, and a document server class 340 is provided for instantiating objects for storing and retrieving documents. The server object class definitions 310-340 and resource objects instantiated therefrom 350, have similar or the same properties as analogous entities in the prior art system and the system of the previously discussed embodiment. Unlike the previous embodiment, there is no need for a monitor object 270 or monitor object class definition 260. Instead, the monitor aspect 370 encapsulates all the monitoring behavior. A monitor aspect 370 acts to force monitoring behavior on the resource object classes 310-340, as well as to create a monitor aspect instance 360, which transparently forces the resource objects 350 to provide notification of events to the monitor aspect instance 360. Additionally, the monitor aspect 370 includes functionality for handling the notifications of the events by allowing the monitor aspect 360 to break the encapsulation of the resource objects to get or change the state of the resource objects. Referring to Table 6, below, an exemplary monitor aspect definition 360, according to this embodiment of the present invention is shown.
TABLE 6
Service Monitor Aspect Definition
aspect ServiceMonitoring {
int totalServiceRequests, totalExceptions, totalCompletions;
advise * DatabaseServer.query(..), * WebServer.post(..),
* WebServer.get(..), * PrinterServer.print(..),
* DocumentServer.convert(..),
* DocumentServer.newDocument(..) {
before {
printMessage("Service Request for server" + thisObject.id); //
note the direct access!
totalServiceRequests++;
}
catch (RuntimeException e) {
printMessage("Exception in server" + thisObject.id);
total Exceptions++;
throw e;
}
finally {
printMessage("Service Completion for server" +
thisObject.id);
totalCompletions++;
}
}
static ServiceMonitoring monitor = new ServiceMonitoring();
advise DatabaseServer(..), WebServer(..),
PrinterServer(..), DocumentServer(..) {
static after {
monitor.addObject(thisObject);
// can be removed dynamically
}
}
void printMessage(String msg) {
System.out.println("Monitor:" + msg);
}
}
The italicized code in Table 6 shows some of the mechanisms in AspectJ that support the direct intervention of aspect instances in the objects. With either way of implementing system monitoring according to the present invention, all the programming for the system monitoring functionality is done separate from the programming for the resources. Thus, system monitoring may be implemented simply by compiling the objects along with the monitoring aspects. When monitoring is no longer needed, the objects are simply recompiled without the aspects. Related to system monitoring is the concept of tracing, which generally involves monitoring the execution of a program, and is commonly practices by monitoring accesses to particular objects forming the program. Referring to FIGS. 4 and 5, FIG. 4 illustrates a prior art way to implement tracing. In traditional functional and object-oriented languages, tracing is a somewhat ad-hoc addition to the system that involves a fair amount of human intervention. If a programmer wants to trace the calls to Point objects, the Point object class 401 definition must be edited to include calls 405 to a Tracing object class 410 throughout the Point object class 401 definition. Exemplary code for an object class, Point 401, is shown in Table 7, below.
TABLE 7
Point Class Definition without Tracing
class Point {
private int_x;
private int_y;
void setX(int x) {
_x = x;
}
void setY(int y) {
_y = y;
}
void set (int x, int y) {
_x = x; _y = y;
}
int getX( ) {
return _x;
}
int getY( ) {
return _y;
}
}
After tracing is implemented for the class, the code appears as in Table 8, below. As can be seen be the italicized lines in the modified object class Point 405, many lines of code are required to implement the tracing, and the code is scattered throughout the class definition.
TABLE 8
Point Class Definition with Tracing
class Point {
private int_x;
private int_y;
void setX(int x) {
Tracing.in("Point.setX " + "x = " + x);
_x = x;
Tracing.out("Point.setX");
}
void setY(int y) {
Tracing.in("Point.setY " + "y = " + y);
_y = y;
Tracing.out("Point.setY");
}
void set (int x, int y) {
Tracing.in("Point.set" + "x = " + x + "y = " + y);
_x = x; _y = y;
Tracing.out("Point.set");
}
int getX( ) {
Tracing.in("Point.getX");
try { return _x; }
finally { Tracing.out("Point.getX"); }
}
int getY( ) {
Tracing.in("Point.getY");
try { return _y;
finally { Tracing.out("Point.getY"); }
}
}
A Tracing object 410 is used to report the results of tracing, as shown in exemplary code in Table 9, below.
TABLE 9
Tracing Object Class Definition
class Tracing {
static boolean enabled = true;
public static void in(String name) {
if (enabled)
System.out.println("Entering " + name);
}
public static void out(String name) {
if (enabled)
System.out.println("Exiting " + name);
}
}
As with the problem associated with implementing and removing system monitoring, a problem with this approach is that whenever tracing is to be added, the object class definition must be edited to add the calls to a tracing object. When tracing is not longer desired, the object class definition must be edited again to remove the calls. Referring to FIG. 5, the present invention implements tracing in a localized tracing aspect 501, and the object class definition 410 is not edited. The aspect includes all the code necessary to perform tracing. When tracing is to enabled, the programmer merely has to compile to object class 410 with the Tracing aspect 501. Disabling tracing is accomplished simply by recompiling without the tracing aspect. To implement tracing with the present invention, a tracing aspect 501 is compiled along with the unmodified object class, Point 401. Exemplary code for the Tracing aspect is shown in Table 10.
TABLE 10
Tracing Aspect Definition
aspect Tracing {
advise * Point.*(..) {
static before {
System.out.println("Entering" + thisClassName + "." +
thisMethodName + " " +
Tracing.buildString(thisJoinPoint.methodParameterNames,
thisJoinPoint.methodParameters));
}
static after {
System.out.println("Exiting" + thisClassName + "." +
thisMethodName);
}
}
static StringBuffer buildString(String[] pnames, Object[] pvalues)
{
StringBuffer str = new StringBuffer();
for (int i = 0; i < pnames.length; i++) {
str.append(pnames[i]); str.append(" = ");
str.append(pvalues[i]); str.append(" ");
}
return str;
}
}
When tracing is no longer needed or desired, it is easily removed by simply recompiling the Point object class 401 without the Tracing aspect 501. System Monitoring/Tracing Aspect Library Referring to FIG. 6, in an alternative embodiment of the present invention, an aspect library 610 is provided including various generic monitoring and tracing functions as library aspects 612, including exemplary library aspect 615. When use of library aspects is desired, the library aspects are bound to object classes 620 by concrete aspects 630. When the system monitoring and tracing aspects are to be implemented as part of a generic library, it is beneficial to make them abstract, without reference to specific objects. To accomplish this, library aspects 615 are implemented with cross-cuts 617 which act as placeholders to allow a concrete aspect 630, defined by a developer, to define bindings 635 between the names of the cross-cuts 617 in the library aspect 615 to concrete points in the execution 625 of the object class 620. Aspect libraries and the implementation of library aspects are described in more detail in patent application, U.S. Ser. No. 09/357,738, entitled ASPECT-ORIENTED PROGRAMMING, filed concurrently with the present invention and assigned to the present assignee, and is hereby incorporated into the present specification by reference. While the present invention has been described in relation to an object-oriented environment, those skilled in the art will appreciate that these techniques may readily be applied to other programming paradigms without departing from the spirit and scope of the present invention.
|
Same subclass Same class Consider this |
||||||||||
