Question: A lot of times while writing applications, I wish to profile and measure the time taken for all methods in a **stacktrace**. What I mean is say:

```
Method A --> Method B --> Method C ...

```

`A` method internally calls `B` and it might call another. I wish to know the time taken to execute inside each method. This way in a web application, I can precisely know the percentage of time being consumed by what part of the code.

To explain further, most of the times in spring application, I write an aspect which collects information for every method call of a class. Which finally gives me summary. But I hate doing this, its repetitive and verbose and need to keep changing regex to accommodate different classes. Instead I would like this:

```
@Monitor
public void generateReport(int id){
...
}

```

Adding some annotation on method will trigger instrumentation api to collect all statistics of time taken by this method and any method later called. And when this method is exited, it stops collection information. I think this should be relatively easy to implement.

The questions is: Are there any reasonable alternatives that lets me do that for general java code? Or any quick way of collection this information. Or even a spring plugin for spring applications?

PS: Exactly like [XRebel](http://zeroturnaround.com/software/xrebel/), it generates beautiful summaries of time take by the security, dao, service etc part of code. But it costs a bomb. If you can afford, you should definitely buy it.

Answer: 
You want to write a [Java agent](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html). Such an agent allows you to redefine a class when it is loaded. This way, you can implement an aspect without polluting your source code. I have written a library, [Byte Buddy](https://github.com/raphw/byte-buddy), which makes this fairly easy. 

For your monitor example, you could use Byte Buddy as follows:

```
new AgentBuilder.Default()
 .rebase(declaresMethod(isAnnotatedWith(Monitor.class))
 .transform( (builder, type) ->
   builder
     .method(isAnnotatedWith(Monitor.class))
     .intercept(MethodDelegation.to(MonitorInterceptor.class);
  );

class MonitorInterceptor {
  @RuntimeType
  Object intercept(@Origin String method,
                                @SuperCall Callable<?> zuper)
      throws Exception {
    long start = System.currentTimeMillis();
    try {
       return zuper.call();
     } finally {
       System.out.println(method + " took " + (System.currentTimeMillis() - start);
     }
   }
}

```

The above built agent can than be installed on an instance of the instrumentation interface which is provided to any Java agent.

As an advantage over using Spring, the above agent will work for any Java instance, not only for Spring beans.
This is the exact reason why I built the open source tool [stagemonitor](http://www.stagemonitor.org/), which uses Byte Buddy to insert profiling code. If you want to monitor a web application you don't have to alter or annotate your code. If you have a standalone application, there is a [`@MonitorRequests`](https://github.com/stagemonitor/stagemonitor/wiki/Integrate-stagemonitor-into-non-servlet-based-applications#declaratively) annotation you can use.

[![Stagemonitor Call Tree](https://i.stack.imgur.com/TTFkg.png)](https://i.stack.imgur.com/TTFkg.png)