All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.automon.aspects.AutomonAspect.aj Maven / Gradle / Ivy

package org.automon.aspects;

import org.automon.implementations.NullImp;
import org.automon.implementations.OpenMon;
import org.automon.implementations.OpenMonFactory;
import org.automon.utils.AutomonPropertiesLoader;
import org.automon.utils.Utils;

import java.util.Properties;



/**
 * 

Aspect that advises the {@link org.aspectj.lang.annotation.Around} and {@link org.aspectj.lang.annotation.AfterThrowing} annotations. * The appropriate methods on {@link org.automon.implementations.OpenMon} methods are called. The advice typically times methods * and counts any exceptions thrown, however other behavior such as logging is also possible.

* *

Note a developer should implement and provide any methods for this class or {@link org.automon.aspects.AspectJBase} or * {@link org.automon.aspects.SpringBase}.

* *

Note: I used native aspect style instead of the @AspectJ style because @Around in @AspectJ style doesn't seem to allow for the * more performant use of the static part of the JoinPoint. The static part only seems to be available without first * creating the dynamic JoinPoint in native aspects. Native style aspects are more powerful and can later be extended by developers * with @AspectJ style, so it is probably the best option anyway.

*/ privileged public abstract aspect AutomonAspect { private OpenMonFactory factory = new OpenMonFactory(new NullImp()); private OpenMon openMon = new NullImp(); private AutomonMXBean automonJmx = new Automon(this); public AutomonAspect() { // Use OpenMon the user selects and register the aspect with jmx initOpenMon(); Utils.registerWithJmx(this, automonJmx); } private void initOpenMon() { Properties properties = new AutomonPropertiesLoader().getProperties(); String openMonStr = properties.getProperty(AutomonPropertiesLoader.CONFIGURED_OPEN_MON); // if the openMonString is a fully qualified classname then also register it in the factory i.e. com.mygreatcompany.MyOpenMon if (Utils.hasPackageName(openMonStr)) { factory.add(openMonStr); } setOpenMon(openMonStr); } /** * _monitor() advice - Wraps the given pointcut and calls the appropriate {@link org.automon.implementations.OpenMon} method * at the beginning and end of the method call. * * @return The advised methods value or void. * @throws Throwable If the method throws a {@link java.lang.Throwable} the advice will rethrow it. */ Object around() throws Throwable : _monitor() { // Note: context is typically a Timer/Monitor object returned by the monitoring implementation (Jamon, JavaSimon, Metrics,...) // though to this advice it is simply an object and the advice doesn't care what the intent of the context/object is. Object context = openMon.start(thisJoinPointStaticPart); try { Object retVal = proceed(); openMon.stop(context); return retVal; } catch (Throwable throwable) { openMon.stop(context, throwable); throw throwable; } } /** * exceptions() advice - Takes action on any Exception thrown. It typically Tracks/Counts any exceptions thrown by the pointcut. * Note arguments are passed on to {@link org.automon.implementations.OpenMon#exception(org.aspectj.lang.JoinPoint, Throwable)} */ after() throwing(Throwable throwable): exceptions() { openMon.exception(thisJoinPoint, throwable); } /** pointcut that determines what is monitored for performance/time */ public pointcut _monitor() : user_monitor() && _sys_monitor(); /** User should implement this pointcut to determine what should be monitored for performance/time */ public abstract pointcut user_monitor(); /** reserved pointcut for Automon team */ public pointcut _sys_monitor(); /** pointcut that determines what is monitored for exceptions. It can be the same as the {@link #_monitor()} pointcut */ public pointcut exceptions() : user_exceptions() && _sys_exceptions(); /** User should implement this pointcut to determine what should be monitored for performance/time */ public abstract pointcut user_exceptions(); /** reserved pointcut for Automon team */ public pointcut _sys_exceptions(); /* methods */ public boolean isEnabled() { return !(openMon instanceof NullImp); } /** Retrieve monitoring implementation */ public OpenMon getOpenMon() { return openMon; } /** Set monitoring implementation such as JAMon, Metrics, or JavaSimon */ public void setOpenMon(OpenMon openMon) { this.openMon = openMon; } /** * Take the string of any {@link org.automon.implementations.OpenMon} registered within this classes * {@link org.automon.implementations.OpenMonFactory}, instantiate it and make it the current OpenMon. If null is passed * in then use the default of iterating each of the preinstalled OpenMon types attempting to create them until one succeeds. * If one doesn't succeed then it would mean the proper jar is not available. If all of these fail then simply disable. * * @param openMonKey Something like jamon, metrics, javasimon */ public void setOpenMon(String openMonKey) { if (openMonKey==null || openMonKey.trim().equals("")) { this.openMon = factory.getFirstInstance(); } else { this.openMon = factory.getInstance(openMonKey); } } public OpenMonFactory getOpenMonFactory() { return factory; } // Note the mxbean was done as an inner class due to compilation order and AutomonAspect.aj not being compiled and so // not available to Automon if it was an external class. These methods are visible via the jconsole jmx console. public static class Automon implements AutomonMXBean { private AutomonAspect automonAspect; public Automon(AutomonAspect automonAspect) { this.automonAspect = automonAspect; } @Override public boolean isEnabled() { return automonAspect.isEnabled(); } @Override public void setOpenMon(String openMonKey) { automonAspect.setOpenMon(openMonKey); } @Override public String getOpenMon() { return automonAspect.getOpenMon().toString(); } @Override public String getValidOpenMons() { return automonAspect.getOpenMonFactory().toString(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy