November 17, 2017

Java EE 7 Performance Monitor with Interceptors, Event and Observes

Lets say you want to performance monitor your business class, that can be achieved with Java EE 7 Interceptors and @Observes. Lets start with the interceptor. Here will only want to encapsulate the actual aggregation and after collecting we use the Java EE 7 Event to send it to the @Observes. A clean separation of concerns.

package se.magnuskkarlsson.example.javaee7;

import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class PerformanceInterceptor {

    @Inject
    Event<PerformanceEvent> events;
    
    @AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
        String className = ctx.getTarget().getClass().getName();
        String methodName = ctx.getMethod().getName();
        long start = System.currentTimeMillis();
        Object object = null;
        try {
            object = ctx.proceed();
        } finally {
            long duration = System.currentTimeMillis() - start;
            events.fire(new PerformanceEvent(className, methodName, duration));
        }
        return object;
    }
}

And the class that holds the data is a POJO.

package se.magnuskkarlsson.example.javaee7;

public class PerformanceEvent {
   
    private final String clazz;
    private final String method;
    private final long duration;

    public PerformanceEvent(String clazz, String method, long duration) {
        this.clazz = clazz;
        this.method = method;
        this.duration = duration;
    }

    public String getClazz() {
        return clazz;
    }

    public String getMethod() {
        return method;
    }

    public long getDuration() {
        return duration;
    }

    @Override
    public String toString() {
        return "PerformanceEvent{" + "clazz=" + clazz + ", method=" + method + ", duration=" + duration + '}';
    }
    
}

And the @Observes.

package se.magnuskkarlsson.example.javaee7;

import java.util.logging.Logger;
import javax.enterprise.event.Observes;

public class PerformanceObserver {

    private final Logger log = Logger.getLogger(PerformanceObserver.class.getName());
    
    public void log(@Observes PerformanceEvent event) {
        log.info(event.toString());
    }

}

And to use in your class that we want to performance measure.

package se.magnuskkarlsson.example.javaee7.control;

import se.magnuskkarlsson.example.javaee7.PerformanceInterceptor;

@Stateless
@Interceptors(PerformanceInterceptor.class)
public class EmployeeBean {

// the public methods we want to measure goes here ...
}

And when we run it

00:37:38,008 INFO  [se.magnuskkarlsson.example.javaee7.PerformanceObserver] (default task-9) PerformanceEvent{clazz=se.magnuskkarlsson.example.javaee7.control.EmployeeBean, method=delete, duration=2}

No comments: