Permalink
Browse files

Add performance monitoring

  • Loading branch information...
1 parent b7b0016 commit c4317182ac7ee42853f29a78ada7432acbdaec77 @jmarin jmarin committed Sep 29, 2012
View
@@ -23,6 +23,7 @@
<jersey.version>1.9-ea04</jersey.version>
<jackson.version>1.9.9</jackson.version>
<jaxb.version>2.2.6</jaxb.version>
+ <jamon.version>2.4</jamon.version>
</properties>
@@ -90,10 +91,17 @@
<!-- AspectJ -->
- <!-- <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId>
- <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version>
- </dependency> -->
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>${aspectj.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjweaver</artifactId>
+ <version>${aspectj.version}</version>
+ </dependency>
+
<!-- Hibernate Spatial -->
<dependency>
@@ -242,6 +250,14 @@
<version>2.6.0</version>
</dependency>
+ <!-- Monitoring -->
+ <dependency>
+ <groupId>com.jamonapi</groupId>
+ <artifactId>jamon</artifactId>
+ <version>${jamon.version}</version>
+
+ </dependency>
+
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
@@ -0,0 +1,29 @@
+package org.geo.spatialsearch.monitor;
+
+import java.util.Date;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public interface GlobalMonitorStatistics {
+
+ long getCallsCount();
+
+ long getTotalCallTime();
+
+ Date getLastAccessTime();
+
+ long lastCallTime(String methodName);
+
+ long callCount(String methodName);
+
+ long averageCallTime(String methodName);
+
+ long totalCallTime(String methodName);
+
+ long minimumCallTime(String methodName);
+
+ long maximumCallTime(String methodName);
+}
@@ -0,0 +1,13 @@
+package org.geo.spatialsearch.monitor;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public interface Monitor {
+
+ Monitor start();
+
+ Monitor stop();
+}
@@ -0,0 +1,11 @@
+package org.geo.spatialsearch.monitor;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public interface MonitorFactory {
+
+ Monitor start(String name);
+}
@@ -0,0 +1,24 @@
+package org.geo.spatialsearch.monitor;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public interface MonitorStatistics {
+
+ String getName();
+
+ long getLastCallTime();
+
+ long getCallCount();
+
+ long getAverageCallTime();
+
+ long getTotalCallTime();
+
+ long getMinimumCallTime();
+
+ long getMaximumCallTime();
+
+}
@@ -0,0 +1,69 @@
+package org.geo.spatialsearch.monitor.jamon;
+
+import org.geo.spatialsearch.monitor.Monitor;
+import org.geo.spatialsearch.monitor.MonitorStatistics;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public class JamonMonitor implements Monitor, MonitorStatistics {
+
+ private com.jamonapi.Monitor monitor;
+
+ public JamonMonitor(com.jamonapi.Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+ public Monitor start() {
+ monitor.start();
+ return this;
+ }
+
+ public Monitor stop() {
+ monitor.stop();
+ return this;
+ }
+
+ public String getName() {
+ return monitor.getLabel();
+ }
+
+ public long getCallCount() {
+ return (long) monitor.getHits();
+ }
+
+ public long getAverageCallTime() {
+ return (long) monitor.getAvg();
+ }
+
+ public long getLastCallTime() {
+ return (long) monitor.getLastValue();
+ }
+
+ public long getMaximumCallTime() {
+ return (long) monitor.getMax();
+ }
+
+ public long getMinimumCallTime() {
+ return (long) monitor.getMin();
+ }
+
+ public long getTotalCallTime() {
+ return (long) monitor.getTotal();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(monitor.getLabel()).append(": ");
+ sb.append("Last=").append(monitor.getLastValue()).append(", ");
+ sb.append("Calls=").append(monitor.getHits()).append(", ");
+ sb.append("Avg=").append(monitor.getAvg()).append(", ");
+ sb.append("Total=").append(monitor.getTotal()).append(", ");
+ sb.append("Min=").append(monitor.getMin()).append(", ");
+ sb.append("Max=").append(monitor.getMax());
+ return sb.toString();
+ }
+}
@@ -0,0 +1,75 @@
+package org.geo.spatialsearch.monitor.jamon;
+
+
+import java.util.Date;
+
+import org.geo.spatialsearch.monitor.GlobalMonitorStatistics;
+import org.geo.spatialsearch.monitor.Monitor;
+import org.geo.spatialsearch.monitor.MonitorFactory;
+
+import com.jamonapi.MonitorComposite;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+public class JamonMonitorFactory implements MonitorFactory, GlobalMonitorStatistics {
+
+ private com.jamonapi.MonitorFactoryInterface monitorFactory = com.jamonapi.MonitorFactory.getFactory();
+
+ @Override
+ public Monitor start(String name) {
+ return new JamonMonitor(monitorFactory.start(name));
+ }
+
+ @Override
+ public long getCallsCount() {
+ return (long) getMonitors().getHits();
+ }
+
+ @Override
+ public long getTotalCallTime() {
+ return (long) getMonitors().getTotal();
+ }
+
+ @Override
+ public Date getLastAccessTime() {
+ return getMonitors().getLastAccess();
+ }
+
+ public MonitorComposite getMonitors() {
+ return monitorFactory.getRootMonitor();
+ }
+
+ @Override
+ public long averageCallTime(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getAvg();
+ }
+
+ @Override
+ public long callCount(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getHits();
+ }
+
+ @Override
+ public long lastCallTime(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getLastValue();
+ }
+
+ @Override
+ public long maximumCallTime(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getMax();
+ }
+
+ @Override
+ public long minimumCallTime(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getMin();
+ }
+
+ @Override
+ public long totalCallTime(String methodName) {
+ return (long) monitorFactory.getMonitor(methodName, "ms.").getTotal();
+ }
+
+}
@@ -0,0 +1,64 @@
+package org.geo.spatialsearch.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.geo.spatialsearch.monitor.Monitor;
+import org.geo.spatialsearch.monitor.MonitorFactory;
+import org.geo.spatialsearch.monitor.GlobalMonitorStatistics;
+import org.geo.spatialsearch.rest.APIResponse;
+
+/**
+ * An aspect that monitors the performance of all three repositories used in the
+ * application.
+ *
+ */
+@Aspect
+public class PerformanceMonitor {
+
+ private final Log logger = LogFactory.getLog(getClass());
+
+ private MonitorFactory monitorFactory;
+
+ public PerformanceMonitor(MonitorFactory monitorFactory) {
+ this.monitorFactory = monitorFactory;
+ }
+
+ /**
+ * Times api method invocations and outputs performance results to a Log4J
+ * logger.
+ *
+ * @param method The join point representing the intercepted repository
+ * method
+ * @return The object returned by the target method
+ * @throws Throwable if thrown by the target method
+ */
+ @Around("execution(public * org.geo.spatialsearch.*.service.impl.*ServiceImpl+.*(..)) && "
+ + "@annotation(org.geo.spatialsearch.util.ResponseTime)")
+ public APIResponse monitor(ProceedingJoinPoint method) throws Throwable {
+ String name = createJoinPointTraceName(method);
+ Monitor monitor = monitorFactory.start(name);
+ try {
+ APIResponse apiResponse = (APIResponse) method.proceed();
+ monitor.stop();
+ apiResponse.setResponseTime(((GlobalMonitorStatistics) monitorFactory).lastCallTime(name));
+ return apiResponse;
+ } finally {
+ if (logger.isDebugEnabled()) {
+ logger.debug(monitor);
+ }
+ }
+ }
+
+ private String createJoinPointTraceName(JoinPoint joinPoint) {
+ Signature signature = joinPoint.getSignature();
+ StringBuilder sb = new StringBuilder();
+ sb.append(signature.getDeclaringType().getSimpleName());
+ sb.append('.').append(signature.getName());
+ return sb.toString();
+ }
+}
@@ -0,0 +1,16 @@
+package org.geo.spatialsearch.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @author Santosh Moghulla
+ *
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ResponseTime {
+}
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+ <bean id="performanceMonitor" class="org.geo.spatialsearch.util.PerformanceMonitor">
+ <constructor-arg ref="monitorFactory"/>
+ </bean>
+
+ <bean id="monitorFactory" class="org.geo.spatialsearch.monitor.jamon.JamonMonitorFactory"/>
+
+ <aop:aspectj-autoproxy>
+ <aop:include name="performanceMonitor"/>
+ </aop:aspectj-autoproxy>
+
+<!--
+ <bean id="loggingAdvisor"
+ class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
+ <property name="advice">
+ <bean class="gov.fcc.nbm.common.utils.LoggingInterceptor" />
+ </property>
+ <property name="pattern">
+ <value>.+DAO\..+</value>
+ </property>
+ </bean>
+-->
+</beans>
Oops, something went wrong.

0 comments on commit c431718

Please sign in to comment.