Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Spring Integration Internal Async Channels Instrumentation


#1

Hi ,
I want to Instrument my External Services , but the thing is i cannot use @async or any async solution provided by you in your document as the spring integration internally handles it asynchronous channels .
So i checked your custom instrumentation and i added the HttpUrlConnection class entry in that.
But still i am not able to find any thing

My XML looks like this . (All other configuration like extensions.dir are in place in YML.)

<?xml version="1.0" encoding="UTF-8"?> sun.net.www.protocol.http.HttpURLConnection getInputStream

I want to know whether i am doing correct . Or i am not able to trace this information on the new relic websight.

Please help.


#2

Instrumentation for the Java agent falls into basically 2 categories –

  1. The agent sees the call being made but hasn’t been configured to perform timing on it
  2. The agent doesn’t see the call being made because of many reasons it doesn’t have visibility to it (async, passed out of scope of the JVM, etc)

In the first case, most of these conditions can be instrumented using XML. In the 2nd case, annotation using an API is necessary – as in a change to the code – in order to make the call visible to the agent. This is not always guaranteed to be successful.

Others in the community may have had success in this so I will certainly defer to their experience.


#3

HI Jeanie ,

By using instrumentation , i am able to trace custom metrics. But the thing is it is not as full blown metrics what your javaagent internally do .
For eg I instrumented java rest template class exchange method. So there was no metrics which provides me information like how much total time the external call has taken. Instead it provides connect time , getInputStream time , getOutputStream time separately.

Thanks,
Udbhav


#4

Hi @udbhavsinghnitw,

Which method did you use to instrument? XML or API annotation? It maybe that you are not instrumenting in the correct location to get the details that you require.

Nemo


#5

From RestTemplate i instrumented Exchange . And using Custom Instrumentation XML.
"

org.springframework.web.client.RestTemplate

exchange

"

This is the way i am doing it.

And also i want to check if we can instrument beans. The problem using instrumenting beans is that it only show stats when it get loaded during bringing the application up.
So i need to know if we can instrument the beans which i define to collect stats at runtime instance for that bean in that request.

Let me know if i am providing the right context
Thanks,
Udbhav.


#6

Hello @udbhavsinghnitw,

Our XML instrumentation basically functions as an extension to the list of classes and methods that the agent tracks out of the box. Let’s take a made-up example, just to illustrate what happens when you target a specific class / method with XML instrumentation.

https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-xml-instrumentation-examples#example

The link above includes an example class called test.SampleTester, with a method called checkSample. If I put this in my XML file:

<?xml version="1.0" encoding="UTF-8"?>
<extension xmlns="https://newrelic.com/docs/java/xsd/v1.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="newrelic-extension extension.xsd "
    name="customExtension" version="1.0">
  <instrumentation metricPrefix="Custom">
    <pointcut transactionStartPoint="true">
      <nameTransaction/>
      <className>test.SampleTester</className>
      <method>
        <name>checkSample</name>
      </method>
    </pointcut>
  </instrumentation>
</extension>

I’ve just told the agent to wrap this method at runtime. The next time that class is loaded, we interrupt the class-loader and wrap the checkSample method in a couple of API calls using bytecode injection. We don’t alter the method call at all, but we place an api call to our agent at the point that the method is executed, and when the method returns its response, so that we know how long the method took to run overall.

The dispatcher=true flag tells the agent to start an APM Transaction when this method is called, if one isn’t already in progress. The <nameTransaction/> flag tells the agent to rename whatever transaction is in progress, new or old, based on the class / method name targeted in the pointcut.

Now, consider for a moment how Java works under the hood. Java is object oriented, and encapsulated. Each Java object owns any variables that are held by that object, and said variables aren’t visible to other objects in the JVM. But, because we’re adding API calls to the underlying method, we’re effectively calling out to our agent from inside the method, so we can pick up attributes that are specific to that method that wouldn’t normally be visible from outside. Like method parameters. That’s what the <parameters> node in the XML example allows you to do – pick up and decorate your Transaction Traces with specific method parameters.

Now, let’s assume for a moment that our checkSample method places an external request. If it does so using a method we instrument out of the box, like HttpUrlConnection, we’ll pick up that as well, and we’ll nest the external call underneath the call to checkSample in the web transaction’s breakdown table. However, if it places the external call using a method that we don’t trace out of the box, we can see that the method is called, but not what it’s doing (Java encapsulation again), so it will appear with a ? next to it in the transaction breakdown table. To remove the ?, we would need to add the method that places the external request to our XML file. Then we would effectively be inside that method as well, and can report on what methods are called from within it, what parameters are passed by it, etc…

Now, here’s where async comes in. Assuming your code is blocking, meaning that each method call waits for subsequent methods to complete their work before returning a response, instrumenting the first method in the chain gives you timing data for the whole request. All subsequent methods just add details to the method timing. But in the async world, you might trigger five tasks on five different threads, and not wait for a response (fire-and-forget) before moving on to the next method in the call stack. Because the async activity is happening on a different thread than the original method trace, the agent can’t link them together easily. It has difficulty telling which thread represents which work from which HTTP request.

Our Async API allows you to pass a token to the method that is executed asynchronously, and then link that token to the activity back on the main thread, so that the two are seen as one transaction. Were you to simply target the method that is executed asynchronously with XML instrumentation (adding dispatcher=true), you would start a second transaction on the async thread, rather than linking the async thread to the main thread. That would still show you the external request that was placed on the async thread, but it would show up as two separate Transactions in APM, one representing the incoming HTTP request, the other representing the asynchronous work that was part of that HTTP request. And it would not be easy to tell that the two were part of the same underlying task.

Now, there’s a lot that you can do with bytecode injection. Our built-in instrumentation modules are a bit more complex than simple XML point cuts. For recognized frameworks, we can weave in our own Async API calls, or leverage the way the framework tracks async thread context. If we can determine the point where the agent is losing track of the request, we could enter a feature request to improve our async tracking in that framework out of the box. There are a lot of async models out there, and we’re always working to improve our range of support.

All that said, at the end of the day with our current product set, we can probably get all of the segments of your HTTP request (synchronous and asynchronous) to show up in APM as separate Transactions using only XML instrumentation, but we won’t be able to get them to show up as the same Transaction without using the Async API.


Regarding monitoring Java MBeans, that’s a slightly different type of custom instrumentation. Most application servers expose Java mbean values over JMX, and our Custom JMX instrumentation allows you to specify the mbean object / metric name and add it to the list of Java mbeans that the agent tracks out of the box. Our agent accesses JMX remotely, in exactly the same way as say JConsole, making JConsole a very useful tool for surfacing what mbeans are available in a given environment. If it is visible in JConsole, we can probably import it into APM.

Note however that custom JMX metrics require an Insights custom dashboard to view, they don’t appear in the APM UI by default.