RSS RSS feed
November 08, 2009
Hot Topics:

Simplify your logging with AspectJ

  • November 17, 2003
  • By Ramnivas Laddad
  • Send Email »
  • More Articles »

Earlier, we discussed why we want to use the logp() method to log messages instead of log(). Another reason to use logp() is that calling the log() method would cause the logging kit to deduce that the caller is the advice instead of the advised method. This happens because the log() method uses the call stack to infer the caller. In this example, the actual caller is the advice, but we want the real caller of the logged method (that triggered the advice) to be shown in the log message and not the advice, which just happens to be the caller due to the addition of the logger aspect.

We have a robust mechanism in AspectJ that addresses all these issues. It is the thisJoinPointStaticPart object, which contains information about the captured join point's class, method, precise source location, and so forth. The compiler creates this information at compile time, and neither compiler optimization nor the presence of the JIT/hotspot virtual machine alters this information. We use the information contained in thisJoinPointStaticPart to obtain the method and class name of the logged method.

Compiling this aspect with the shopping cart source code and running the Test class results in output similar to this:

> ajc *.java
> java Test
 
Oct 27, 2003 12:56:18 AM Test main
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory 
INFO: Entering
Oct 27, 2003 12:56:18 AM Item 
INFO: Entering
Oct 27, 2003 12:56:18 AM Item 
INFO: Entering
Oct 27, 2003 12:56:18 AM Item 
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory addItem
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory addItem
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory addItem
INFO: Entering
Oct 27, 2003 12:56:18 AM ShoppingCart 
INFO: Entering
Oct 27, 2003 12:56:18 AM ShoppingCartOperator addShoppingCartItem
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory removeItem
INFO: Entering
Oct 27, 2003 12:56:18 AM ShoppingCart addItem
INFO: Entering
Oct 27, 2003 12:56:18 AM ShoppingCartOperator addShoppingCartItem
INFO: Entering
Oct 27, 2003 12:56:18 AM Inventory removeItem
INFO: Entering
Oct 27, 2003 12:56:18 AM ShoppingCart addItem
INFO: Entering

The output shows a message being logged as soon as the execution of the program enters each method and constructor in the system. The toolkit also prints a timestamp corresponding to each of the logged messages.

Finally, let's modify our aspect to use the log4j toolkit from Apache. This example, like the earlier one, shows how easy it is to switch from one logging toolkit to another when you use AspectJ for logging. Listing 11 shows the same logging functionality implemented using the log4j logging toolkit instead of the standard Java logging toolkit.

Listing 11: Tracing methods: the third version, using the log4j toolkit

import org.apache.log4j.*;
 
import org.aspectj.lang.*;
 
public aspect TraceAspectV3 {
    Logger _logger = Logger.getLogger("trace");
 
    TraceAspectV3() {
        _logger.setLevel(Level.ALL);
    }
 
    pointcut traceMethods()
        : (execution(* *.*(..))
          || execution(*.new(..))) && !within(TraceAspectV3);
 
    before() : traceMethods() {
        if (_logger.isEnabledFor(Level.INFO)) {
            Signature sig = thisJoinPointStaticPart.getSignature();
            _logger.log(Level.INFO,
                        "Entering ["
                        + sig.getDeclaringType().getName() + "."
                        + sig.getName() + "]");
        }
    }
}

The API for both toolkits is the same for the most part. Therefore, we need to change only a few statements from our earlier version (the changes appear in bold in the listing). Note that log4j does not have a logp() method; instead, the log() method, along with the use of properties file, offers the equivalent functionality. We encode the caller information in the message that is passed as an argument to the log() method call. log4j requires a properties file that specifies the information to be logged and the format for each log message. For the purpose of this test, we used the following properties file (log4j.properties) to configure log4j:

log4j.rootCategory=DEBUG, dest1
log4j.appender.dest1=org.apache.log4j.ConsoleAppender
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout

When we compile the aspect in listing 11 with the rest of our classes and run the Test class, we see 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]

The output is similar to that using the standard Java logging toolkit. You can control the information being logged, such as the addition of a timestamp or the format of the log messages, by modifying the properties file. Please refer to the log4j documentation for more details.

But there's more

In this exceprted article, we covered an overview of method tracing using AspectJ. The corresponding chapter in the book covers a lot more details to show how you can extend the mechanism for a variety of purpose such as:

  • Exception logging: Since exception throwing is an important event in the system, logging the thrown exception is important. AspectJ-based solution offers a way to introduce such a functionality wihtout changing even a single line of code in the core part of the system. Similar to method tracing, you can switch the underlying logging implementation just by changing the aspect.
  • Method parameter logging: To gain a better understanding of the system, often you need method arguments in addition to method name. Through use of reflective API offered by AsepctJ, you can easily log the method parameters.
  • Indented logging: To improve comprehensibility of the logged output, it is desirable that the method calls in output refect the call depth, usually by indenting log messages appropriately. Through use of a simple reusable aspect, this functiuonality can be implemented quickly.

Further, the basic logging mechanism can be improved to introduce functionality such as profiling, testing, service-level monitoring and so on.

Conclusion

AspectJ-based logging is a low-investment, low-risk way to begin using AspectJ. Logging aspects also offer a unique plug-and-play nature. If this article convinced you of the benefits of using AspectJ for logging, you may start out by simply using it for debugging and tracing. Later, you can demonstrate to your team the benefits you have experienced, which may lead them to use AspectJ as well. At any point, including during the final shipment, you can exclude the AspectJ and logging aspects. The overall effect is that you can start using AspectJ with minimal risk.

Once you commit to AspectJ-based logging, you will start seeing even more benefits. You can use AspectJ-based solutions for core logging tasks that go beyond debugging and tracing. Implementation of such logging concerns is now nicely modularized. This solution leads to increased flexibility, improved accuracy, and better consistency. It saves you from the laborious and boring task of writing nearly identical log statements in code all over your system. The use of AspectJ also makes the job of choosing logging toolkits an easy task. You can start with any one that you are familiar with, and feel comfortable that changing the choice later on will require modifying only a few statements.

I welcome questions and comments! Email me at ramnivas at yahoo dot com.

Resources

[1] AspectJ in Action: Practical Aspect-oriented Programming, Ramnivas Laddad, Manning Publications, 2003.

[2] “I Want My AOP!”, Part 1-3, Ramnivas Laddad, JavaWorld, January-April, 2002. Available online at:

http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html

http://www.javaworld.com/javaworld/jw-03-2002/jw-0301-aspect2.html

http://www.javaworld.com/javaworld/jw-04-2002/jw-0412-aspect3.html

[3] “Crosscutting” (article series), Gregor Kiczales, Software Development Magazine, starting November 2003.

[4] AspectJ site including downloads and documentation: http://www.eclipse.org/aspectj

[5] AspectJ user mailing list: https://dev.eclipse.org/mailman/listinfo/aspectj-users

[6] “Design Pattern Implementation in Java and AspectJ”, Jan Hannemann and Gregor Kiczales. Proceedings of the 17th Annual ACM Conference on Object-Oriented Programming, Systems,Languages, and Applications (OOPSLA), November, 2002. Also available online at:

http://www.cs.ubc.ca/~gregor/hannemann-OOPSLA2002-aop-patterns.pdf

[7] “Aspect-Oriented Programming”, Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes, Jean-Marc Loingtier, and John Irwin. Proceedings of European Conference on Object-Oriented Programming (ECOOP'97), June 1997. Available online at:

ftp://ftp.ccs.neu.edu/pub/people/crista/publications/ecoop97/for-web.pdf

[8] “Test Flexibly with AspectJ and Mock Objects”, Nicholas Lesiecki, IBM DeveloperWorks, May 2002. Available online at:

http://www-106.ibm.com/developerworks/java/library/j-aspectj2

[9] Aspect-oriented programming site: http://aosd.net

[10] Eclipse/AspectJ integration: http://www.eclipse.org/ajdt

[11] Emacs/AspectJ integration: http://aspectj4emacs.sourceforge.net

[12] JBuilder/AspectJ integration: http://aspectj4jbuildr.sourceforge.net

[13] NetBeans/AspectJ integration: http://aspectj4netbean.sourceforge.net

[14] AOSD user mailing list: http://aosd.net/mailman/listinfo/discuss

About the Author

Ramnivas Laddad has been developing complex software systems for over a decade. He is an active member of the AspectJ user community and has been involved with aspect-oriented programming from its early form. Ramnivas has authored several articles, papers, and books. His most recent publication, "AspectJ in Action: Practical aspect-oriented programming" (Manning, 2003) has been labeled as the most useful guide to AOP/AspectJ. Ramnivas is also a mentor at AspectMentor, a consortium of AOP experts who provide assistance with training, consulting, and mentoring.

1 2 3 4 5




Networking Solutions





Partners

  • Partner With Us














More for Developers

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

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