gamelan
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
New
 
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




Vote for the Developer.com Product of the Year Winners!




Developer Jobs

Be a Commerce Partner














 


Developer News -
Red Hat Fedora Claims It's the Leader in Linux    November 21, 2008
Dos and Don'ts of SOA Data Access    November 20, 2008
Mandrake Linux Founder Back, Virtually    November 20, 2008
Amazon: We're a Technology Company    November 19, 2008
Free Tech Newsletter -

Simplify your logging with AspectJ
By Ramnivas Laddad

Go to page: Prev  1  2  3  4  5  Next  

The beauty of AspectJ-based logging

Although logging APIs solve quite a few problems, as you have just seen they also leave some gaps. The limitations are not a result of the logging APIs or their implementations; rather, they stem from the fundamental limitations of objectoriented programming, which require embedding the logging invocations in each module. AOP and AspectJ overcome those limitations. AspectJ easily implements the invocation of logging statements from all the log points. The beauty is that you do not need to actually instrument any log points; writing an aspect does it automatically. Further, since there is a central place to control logging operations, you achieve consistency easily.

The most fundamental difference between conventional logging and AspectJ-based logging is modularization of the logging concern. Instead of writing modules that implement core concepts in addition to invoking logging operations, with AspectJ you write a few aspects that advise the execution of the operations in the core modules to perform the logging. That way, the core modules do not carry any logging-related code. By modularizing, you separate the logging concern from the core concerns.

The solution presented here builds on available logging toolkits. For the final act of logging, you can use any of the toolkits available. AspectJ comes into the picture to intercept the operations, collect the context, and form a message to pass on to the underlying logging system. Figure 2 shows the overview of AspectJ-based logging.

With AspectJ-based logging, the logger aspect separates the core modules and the logger object. Instead of the core modules embedding the log() method invocations in their source code, the logger aspect weaves the logging invocations into the core modules when they are needed. AspectJ-based logging reverses the dependency between the core modules and the logger; it is the aspect that encodes how the operations in the core modules are logged instead of each core module deciding for itself.

Developing logging and tracing aspects

Tracing is a special form of logging where the entry and/or exit of selected methods are logged. Tracing is useful during the development phase in order to understand system behavior, especially when a debugger is not an option, either due to the speed at which the activities occur or due to the distributed nature of the application. In this section, we will examine method tracing and exception logging. We will also use these examples to show how you can accomplish the task using different logging toolkits. These snippets will enable you to try logging for your own system.

Method call tracing

Let's develop an aspect that will enable tracing method calls in any system. Simply compile this aspect with the rest of the code and you will see the logging of every method call. No changes will be needed in any of your classes. Our first version, in listing 9, uses System.out as the logging stream.

Listing 9: Tracing methods: the first version, using System.out as the logging stream

 
import org.aspectj.lang.*;
 
public aspect TraceAspectV1 {
    pointcut traceMethods()                                         //1
        : (execution(* *.*(..))                                     //1
          || execution(*.new(..))) && !within(TraceAspectV1);       //1
    
    before() : traceMethods() {
        Signature sig = thisJoinPointStaticPart.getSignature();     //2
        System.out.println("Entering ["                             //2
                          + sig.getDeclaringType().getName() + "."  //2
                          + sig.getName() + "]");                   //2 
    }
}
  1. Traced methods pointcut: The traceMethods() pointcut captures the calls to methods that need tracing--in our case, it will be all the methods in the system. The !within(TraceAspectV1) part helps us avoid recursion caused by tracing method calls in the aspect itself. Once we compile the aspect along with the core modules, a log message will print to System.out before any method is executed. We could also, if required, easily produce a log message after the method execution by adding an after advice.
  2. Log advice: We use thisJoinPointStaticPart to get information about the method captured by the pointcut. The method getSignature() on thisJoinPointStaticPart returns the signature of the captured method. We use this object to get the name of the class and method to form and print the log message.

When we run this aspect with our shopping cart example, we get the following output:

> ajc *.java
> java Test
 
Entering [Test.main]
Entering [Inventory.<init>]
Entering [Item.<init>]
Entering [Item.<init>]
Entering [Item.<init>]
Entering [Inventory.addItem]
Entering [Inventory.addItem]
Entering [Inventory.addItem]
Entering [ShoppingCart.<init>]
Entering [ShoppingCartOperator.addShoppingCartItem]
Entering [Inventory.removeItem]
Entering [ShoppingCart.addItem]
Entering [ShoppingCartOperator.addShoppingCartItem]
Entering [Inventory.removeItem]
Entering [ShoppingCart.addItem]

Now let's modify the aspect to use the standard Java logging toolkit so that we can use the features it offers, such as the ability to dynamically modify the logging level. Note that we can introduce such a change to the whole system by modifying just a few lines in one aspect. Without AspectJ, we would have to modify every log statement in the system. In listing 10, we show how you can use the standard logging toolkit to perform logging that is identical in functionality to that in listing 9.

Listing 10: Tracing methods: the second version, using the standard logging toolkit

 
import java.util.logging.*;
import org.aspectj.lang.*;
 
public aspect TraceAspectV2 {
    private Logger _logger = Logger.getLogger("trace");
    
    TraceAspectV2() {
        _logger.setLevel(Level.ALL);
    }
    
    pointcut traceMethods()
        : (execution(* *.*(..))
          || execution(*.new(..))) && !within(TraceAspectV2);
 
    before() : traceMethods() {
        if (_logger.isLoggable(Level.INFO)) {
            Signature sig = thisJoinPointStaticPart.getSignature();
            _logger.logp(Level.INFO,
                         sig.getDeclaringType().getName(),
                         sig.getName(),
                         "Entering");
        }
    }
}

The aspect in listing 10 contains a logger object, and the constructor sets its logging level to an initial value. This logging level is only the initial level; any part of the system can later get hold of the "trace" logger object using Logger. getLogger("trace") and modify its level. Therefore, before we perform the actual logging, advice to the traceMethods() pointcut first checks if the current logging level is such that the logp() method call will result in a log message. It does this by calling isLoggable(). The check for the log level is needed for performance reasons only. It ensures that we do not perform a wasteful operation in assembling the log message if the message will not be logged. To perform the actual logging, we invoke the logp() method on the logger object with the appropriate log message and caller information.

Go to page: Prev  1  2  3  4  5  Next  


Tools:
Add www.developer.com to your favorites
Add www.developer.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed


Other Java Archives






internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers