I wrote something similar, which I put as a public closure in category I, then connected to the services:
// TimingCategory.groovy /** * Provides common AOP timing functionality to Services which mixin this category. */ class TimingCategory { static Closure timer = { String label = "The call", Closure closure -> Long start = System.currentTimeMillis() def result = closure.call() Long end = System.currentTimeMillis() Long duration = end - start log.warn "${label} took ${duration} ms" return result } }
In other classes, you simply refer to closing the timer as such:
@Mixin(TimingCategory) public class WhateverService { public String doSomeWork() { timer "Doing a lot of work", { 1000.times { doSomething() } someMethodWithAStringReturnValue() } } }
This will give you the output of the "WARN: A lot of work took nn ms to complete" log and return the value of the internal closure as the return value of the doSomeWork method.
For your taglib instance, simply wrap out << ... in
timer "Writing an emoticon", {
code.
If you do not need to pass an internal return value, you can instead return the duration as a result of a close call.
Update
Perhaps I misunderstood - you ask how to terminate taglib without changing the taglib code? How about creating a custom taglib that takes a body and passes it to other tags for execution?
I have not tried this, but something like:
class TimedTagLib { static namespace = "timer" def timedTag = { attrs, body -> timer "Executing the timed tag", { out << body() } } }
And calling him like
<timer:timedTag><g:emoticon whatever="something">Text</g:emoticon></timer:timedTag>
Update 2:
Ok, so I tried. Works great. My last code (I added a second timer closure that returns a duration):
// TimedTagLib.groovy @Mixin(TimingCategory) class TimedTagLib { static namespace = "timer" def timedTag = { attrs, body -> def duration = returnTimer "Printing the timed tag", { out << body() } out << "Took ${duration} ms to print" } }
And the view:
// someView.gsp <timer:timedTag> <g:formatLocalDate date="${LocalDate.now()}" /> </timer:timedTag>
Final HTML:
03/19/2013 Took 6 ms to print
And he also wrote a magazine.