user-icon Marius Oehler
27. May 2020
timer-icon 5 min

How to Easily Trace Java Applications

In this blog post, we will show you how you can easily trace your Java application to gain insight into its runtime and performance behavior. Using inspectIT Ocelot, we show how to extract any kind of data from an application and how to analyse it with Jaeger.

Every developer has probably encountered the case that the application he or she is developing does not do what it should. In this case, debugging the application to understand its flow and to see what is really happening is usually helpful. But what does it look like if we are not interested in what the application does, but how long it takes?

Now, what are the possibilities to get information about an application’s timings? In small applications, you might be able to manually log the timings of certain functionality yourself. However, this is not very practical, especially for large applications and even not possible if the source code is not available.

Thankfully, there are many tools available to solve exactly these problems. In this blog post we want to show how to tackle this problem with inspectIT Ocelot and how an application can be traced with it.

inspectIT Ocelot Logo

Before we start, it has to be said, that inspectIT Ocelot is not only intended to trace a local application, but actually to be integrated into large application landscapes and to collect monitoring data at runtime of production systems and also to correlate these data with each other (e.g. in case of distributed tracing). If you are interested in this, you should definitely checkout Alexander’s blog post Ocelot meets Friends: Enhancing Modern Observability Platforms.

Let’s Get Started

Okay, first we set up our environment and all necessary components. Besides inspectIT Ocelot, we also require further tools, because inspectIT Ocelot is first of all “only” a Java agent which is solely used for data collection. So we also need something where we can store and analyze the data – in this case we used Jaeger as a kind of backend.

Jaeger can be set up quite easily using Docker:


Of course, we also have to download the inspectIT Ocelot Java Agent, so that we can integrate it into our application for data collection. You can download it from its Github repository.

Once the agent has been downloaded, you can integrate it into your Java application. This can be done using the special JVM argument “javaagent“:


Note, that the “javaagent” property has to be in front of the “jar” argument.

Now, the application starts together with our agent, which begins to collect data. But the agent doesn’t know what to do with the gathered data. So, the only thing left to do is to configure that the data should be sent to Jaeger. This can be done passing the system property “inspectit.exporters.tracing.jaeger.url” to the agent, specify a URL where Jaeger data is accepted:


And that’s it. From now on you should get some basic insights into your application. So, let’s open the Jaeger UI (localhost:16686) and see whether our data has been successfully collected.

In order to see our data in the Jaeger interface, we click on the “Find Trace” button on the left. This will load all the data. We can also set up additional filters to make it easier for us to search for data.

Overview of collected traces in Jaeger.

Each entry in the data list represents a trace, which is a flow through the system, starting from a specific entry point. In our case of a Web application, this corresponds to individual HTTP requests. Clicking on an entry shows us several details, for example, which methods were called and how much time was needed.

Jaeger's view for showing trace details

As you may have noticed, you are currently only seeing information about HTTP and JDBC calls. This is because the agent only collects data from common frameworks and technologies by default. In the next section, we will show how we get the agent to record our own implemented classes and methods as well.

Collecting Custom Data

The agent can be completely configured via system properties or configuration files. But to make our work with the configuration easier – and because it’s awesome – we used another component: the Ocelot Configuration Server. You can also start it with Docker:


Now, we just have to instruct our agent to get its configuration from the Configuration Server from now on. We can do this with the system property “inspectit.config.http.url“:


Next, we create a new configuration file in the configuration server interface. Its UI is available via localhost:8090.

Now we go deeper into the inspectIT Ocelot configuration, but don’t worry, it will not be that complicated! However, you should be familiar with YAML 😉

In the following we will now create two scopes. A scope is an important component in Ocelot and represents a set of methods which are monitored. In this example, we will only scratch the surface of what can be achieved with scopes. If you are interested in more details you should have a look into the documentation!

Ok, what are we doing: on the one hand, we will capture all public methods of all classes that own the controller annotation. Additionally, we record all public methods of classes whose fully-qualified class name starts with “org.springframework.samples.petclinic.model“.


Finally, the created scopes just have to be included in the “r_trace_method” rule and that’s it. Once the file is saved, the agent fetches the new configuration and applies it – the JVM does not need to be restarted.

Looking at our data in Jaeger again, we see that our traces are now much more detailed and give us a lot of information about the runtime behavior.

Trace details including additional span data

Conclusion

In the previous sections we have shown how easy and fast it is to trace a Java application and extract runtime information with the inspectIT Ocelot Agent.

As already mentioned, the main focus of the agent is the continuous monitoring of large-scale, distributed systems. However, thanks to its flexible configuration, it can be used in many ways, e.g. also for analyzing a small local application during development.

Of course, we have only scratched the surface of the possibilities and features of the inspectIT Ocelot Agent here. If you are more interested in this topic and APM, it is worth taking a look at the other blog posts about OpenAPM and inspectIT Ocelot.

Happy tracing!

Comment article