Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] general tracing aspect

> > To stop the overhead of getLog() on every invocation, lazt init the Logs
> > into a Map held as an instance variable in the aspect and
> > keyed on the Class retrieved from sig.getDeclaringType().

One way to avoid the per-class Map lookup for the logger when you have an
instance of the class being logged is to cache a reference to the logger in each
instance.  This trades space for time and works regardless of the per-class
logging implementation.

Wes

--------- MainLogging.java 
package log;

import runtimeModel.Main; // use your own target here
/**
 * Example of applying logging aspect
 */
public aspect MainLogging extends Logging {
    declare parents: Main implements Loggable;
    // alternatively...
    declare parents: com.bigco.gui..* implements Loggable;

    pointcut logPoints(Loggable me) : anyMethod(me);
}

--------- Logging.java
package log;

import java.util.Hashtable;
/**
 * Logging aspect allows concrete implementation to select
 * or define pointcuts, so long as it surfaces an instance.
 */
public abstract aspect Logging {
    protected interface Loggable{}
    private final Logger Loggable.logger 
       = Logger.getLogger(getClass());
    abstract pointcut logPoints(Loggable me);
   
    // alternate implementations
    pointcut anyMethod(Loggable me) :
        execution(* Loggable+.*(..)) && this(me);
    pointcut anyPublicMethod(Loggable me) :
        execution(public * Loggable+.*(..)) && this(me);
    // more  implementations...
    
    before(Loggable me) :  logPoints(me) {
        me.logger.log("before " + thisJoinPoint);
    }
    after (Loggable me) returning: logPoints(me) {
        me.logger.log(" after " + thisJoinPoint);
    }  
}

// Sample implementation, just to make this compile
class Logger {
    static Hashtable loggers = new Hashtable();
    public static Logger getLogger(Class c) {
        Logger result = (Logger) loggers.get(c);
        if (null == result) {
            result = new Logger(c);
            loggers.put(c, result);
        }
        return result;
    }
    final String className;

    private Logger(Class c) {
        className = c.getName();
    }

    public void log(String s) {
        System.out.println(className + ": " + s);
    }
}



Marc Tremblay wrote:
> 
> FYI:
> 
> >From looking at the source code for the Jakarta Commons logging project,
> it looks like the Logs are already cached in a Map by LogFactory, so in
> that case the only overhead is the actual call to getLog(...)
> 
> Log4j on the other hand, appears to do considerably more work to
> retrieve a logger.  Fortunately, the Jakarta Commons logging project can
> be used as a wrapper for Log4j and do this caching for us.
> 
> So if your aspect will assume it's using the Jakarta Commons logging,
> there's maybe not much point to complicate it's code by adding another
> layer of caching.
> 
> -- Marc
> 
> On Wed, 2003-04-23 at 08:17, Jon Cundill wrote:
> > Hi,
> >
> >  we use something like
> >
> >     public static void traceEntry(Signature sig) {
> >       Log log = LogFactory.getLog( sig.getDeclaringType() );
> >       if( log.isDebugEnabled() )
> >       {
> >               log.debug( "ENTERED " + sig.getName());
> >       }
> >     }
> >
> > This is for jakarta commons logging, but I would think plain Log4j would
> > work similarly.
> > To stop the overhead of getLog() on every invocation, lazt init the Logs
> > into a Map held as an instance variable in the aspect and
> > keyed on the Class retrieved from sig.getDeclaringType().
> >
> > Jon
> >
> > -----Original Message-----
> > From: aspectj-users-admin@xxxxxxxxxxx
> > [mailto:aspectj-users-admin@xxxxxxxxxxx]On Behalf Of Nuno Oliveira
> > Sent: 23 April 2003 14:50
> > To: rhill@xxxxxxxxxx
> > Cc: aspectj-users@xxxxxxxxxxx
> > Subject: RE: [aspectj-users] general tracing aspect
> >
> >
> > Your reply was most welcome! thanks :)
> >
> > The solution you provided solves the problem of the class name to use in
> > advice but doesn't comply with my whish to have a single Logger instance per
> > class. This way every class will be logging to the same logger (the defined
> > one). What I would need would be a way to create a static logger instance
> > per-class using a type patern instead of a specific Type or a way to specify
> > that the logging is to take place in the logger variable that each class
> > already has.
> >
> > Thanks again.
> > Nuno
> >
> > -----Original Message-----
> > From: Gilles DODINET [mailto:rhill@xxxxxxxxxx]
> > Sent: Wednesday, April 23, 2003 1:20 PM
> > To: Nuno Oliveira
> > Subject: Re: [aspectj-users] general tracing aspect
> >
> >
> > what about something like
> >
> > interface Loggable {}
> > declare parent : my.package.* implements Loggable;
> >
> > //init logger as soon as possible (<init> ? <clinit> ?)
> > private Logger Loggable.anotherLogger;
> >
> > pointcut method(Loggable o) :
> >                within(Loggable+)
> >                && execution(* *(..))
> >                && this(o);
> >
> > before(Loggable o): method(o)
> > {
> >            o.anotherLogger.enter(
> >
> > thisJoinPointStaticPart.getSignature().getName() ,
> >                              thisJoinPoint.getArgs());
> > }
> >
> > i have not tested it, tho i think that it should work, with quite little
> > modifications. please provide me with some feedbacks :)
> >
> > -- gd
> >
> >
> > > Message du 23/04/03 12:40
> > > De : Nuno Oliveira <noliveira@xxxxxx>
> > > A : aspectj-users@xxxxxxxxxxx
> > > Copie à :
> > > Objet : [aspectj-users] general tracing aspect
> > > Hello all,
> > >
> > > I have a bunch of classes each with its own static instance of a log4j
> > > logger. This instances all have the same name 'logger'. I want to add
> > > enter-leave tracing to each of the methods of all classes but would be
> > > interested in making this with a single aspect. However I'm having trouble
> > > with the sintax to refer to the logger in my advice, without using the
> > class
> > > name -which would defeat the purpose. I cannot use type patterns in
> > advice,
> > > rigth ? Can anyone provide any hints ? Using aspectJ, a sintatically wrong
> > > expression of my needs would be:
> > >
> > > package my.package;
> > >
> > > privileged aspect TraceEnterLeave
> > > {
> > >     pointcut method(): within(my.package..*) && execution(* *(..));
> > >
> > >     before(): method()
> > >     {
> > >
> > >
> > (my.package..*).logger.enter(thisJoinPointStaticPart.getSignature().getName(
> > > ) ,
> > >             thisJoinPoint.getArgs());
> > >     }
> > >
> > >     after() returning(Object o): method()
> > >     {
> > >
> > >
> > (my.package..*).logger.leave(thisJoinPointStaticPart.getSignature().getName(
> > > ), o);
> > >     }
> > > }
> > >
> > > A related question would be how to migrate the static logger declaration
> > in
> > > each class to that tracing aspect ? Could I use a type pattern to get the
> > > class name to instatiate each logger ?
> > >
> > > Thanks in advance.
> > >
> > > Nuno
> > >
> > > _______________________________________________
> > > aspectj-users mailing list
> > > aspectj-users@xxxxxxxxxxx
> > > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> > >
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> >
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top