Instrumenting the code
The immediate question is how do you instrument the code you want to measure without having to modify it? The first goal is to avoid being too intrusive in the code and, also, to avoid affecting the entire application just for the duration of a benchmark. The second goal is to be able to toggle the instrumentation and to be able to deactivate it in order to measure the application without monitoring (particularly, if you put it everywhere) and ignore the associated overhead on the metrics you take.
Nowadays, in Java and Java EE state, you have several options to instrument the code. We will browse through most of them, but here is an overview of the choices you have:
- Choice 1 – manual: In this solution, you wrap the instance you use with a Factory of the monitoring framework you rely on, and the returned instance is wrapped in a monitored proxy (new instance delegating to the original one). Concretely, it can look like the following:
@ApplicationScoped
public class QuoteResource {
@Inject
private QuoteService service;
@PostConstruct
private void monitorOn() {
service = MonitoringFactory.monitor(service);
}
}
From what we talked about earlier, this has a drawback of impacting the code and limiting the instrumentation to the code you own (or can modify). However, the big advantage is that it is simple to integrate and works with any kind of code (managed by the EE container or not). Concretely, most of the monitoring libraries will have such a utility and often just use it internally in other kinds of integrations.
- Choice 2 – through CDI (or the interceptor API): The Java EE standard way to inject logic into a service is to use an interceptor. We will detail how it works in a dedicated part but the overall idea is to flag a method as being monitored. Here again, the limitation will be to have access to the code you want to monitor through the CDI container. However, it is less impacting than the previous solution in terms of coding.
- Choice 3 – through a javaagent: The javaagent is the most powerful way to instrument the code. The drawback is that you need to configure it directly on the JVM, while the good point is that you can monitor almost every class (except for a few of the JVM itself).