Path: csiph.com!aioe.org!.POSTED!not-for-mail From: =?UTF-8?Q?Arne_Vajh=c3=b8j?= Newsgroups: comp.lang.java.programmer Subject: Re: Logging database statement duration in a DRY way Date: Fri, 19 Aug 2016 22:37:17 -0400 Organization: Aioe.org NNTP Server Lines: 91 Message-ID: References: <87wpjdhrbm.fsf@Equus.decebal.nl> <87pop4j41i.fsf@Equus.decebal.nl> NNTP-Posting-Host: 7SK6yTFfqwlIPNBLl3l7Qg.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 X-Notice: Filtered by postfilter v. 0.8.2 Xref: csiph.com comp.lang.java.programmer:35423 On 8/19/2016 10:17 PM, Arne Vajhøj wrote: > import java.util.Map; > import java.util.concurrent.ConcurrentHashMap; > > import org.aspectj.lang.JoinPoint; > import org.aspectj.lang.ProceedingJoinPoint; > import org.aspectj.lang.annotation.Around; > import org.aspectj.lang.annotation.Aspect; > import org.aspectj.lang.annotation.Pointcut; > > @Aspect > public class TimerAspect { > private static Map store = new > ConcurrentHashMap(); > @Pointcut("call(* java.sql.Connection.prepareCall(*)) && > !within(TimerAspect)") > public void start(ProceedingJoinPoint pjp, > JoinPoint.EnclosingStaticPart esp) {} > @Pointcut("call(* java.sql.PreparedStatement.close()) && > !within(TimerAspect)") > public void end(ProceedingJoinPoint pjp, > JoinPoint.EnclosingStaticPart esp) {} > @Around(value = "start(pjp, esp)") > public Object startAround(ProceedingJoinPoint pjp, > JoinPoint.EnclosingStaticPart esp) throws Throwable { > String loc = esp.getSignature().toString(); > long t1 = System.nanoTime(); > store.put(loc, t1); > Object res = pjp.proceed(); > return res; > } > @Around(value = "end(pjp, esp)") > public Object endAround(ProceedingJoinPoint pjp, > JoinPoint.EnclosingStaticPart esp) throws Throwable { > Object res = pjp.proceed(); > long t2 = System.nanoTime(); > String loc = esp.getSignature().toString(); > long t1 = store.remove(loc); > System.out.printf("%s : %d\n", loc, t2 - t1); > return res; > } > } Make that: import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; @Aspect public class TimerAspect { private static Map store = new ConcurrentHashMap(); @Pointcut("call(* java.sql.Connection.prepareCall(*)) && !within(TimerAspect)") public void start(ProceedingJoinPoint pjp, JoinPoint.EnclosingStaticPart esp) {} @Pointcut("call(* java.sql.PreparedStatement.close()) && !within(TimerAspect)") public void end(ProceedingJoinPoint pjp, JoinPoint.EnclosingStaticPart esp) {} @Around(value = "start(pjp, esp)") public Object startAround(ProceedingJoinPoint pjp, JoinPoint.EnclosingStaticPart esp) throws Throwable { long t1 = System.nanoTime(); Object res = pjp.proceed(); store.put(res.toString(), t1); return res; } @Around(value = "end(pjp, esp)") public Object endAround(ProceedingJoinPoint pjp, JoinPoint.EnclosingStaticPart esp) throws Throwable { long t1 = store.remove(pjp.getTarget().toString().toString()); Object res = pjp.proceed(); long t2 = System.nanoTime(); String loc = esp.getSignature().toString(); System.out.printf("%s : %d\n", loc, t2 - t1); return res; } } It is better at handling multiple PreparedStatements in same method. Arne