Java XML instrumentation examples

For your New Relic-monitored Java application, one custom instrumentation method is to use an XML file that lists the methods and classes you want to instrument. This documentation shows an example XML instrumentation file.

To edit your XML file directly from the New Relic UI: Go to rpm.newrelic.com/apm > (select an app) > Settings > Live Instrumentation. From here you can:

  • Download a sample XML file
  • Select an edit existing XML file
  • Search the instrumentation history

For basic info about XML instrumentation, see Java instrumentation by XML.

XML file format overview

Here is a summary of the XML file format's root and child nodes.

Root node: extension

The root node of an XML file is extension. It can have three different attributes:

Value Definition
name A unique but descriptive name identifying your XML extension.
enabled Identifies whether the extension will be read by the Java agent. Default is true. If false, New Relic will ignore the extension.
version The version of the extension. If two extensions have the same name, only the extension with the highest version will be used.
Instrumentation (child of extension)

The instrumentation node is a child of extension. It can have one attribute: metricPrefix. This is the prefix used for the metric names when the nameTransaction node is not specified. Default is CUSTOM.

Pointcut (child of instrumentation)

The pointcut is a child node of instrumentation and can have several attributes. Also, a pointcut can have several different child nodes.

Value Definition
transactionStartPoint If a transaction is not already in progress when this pointcut is reached, then a transaction will be started. If a transaction is already in progress, then that transaction will continue. A new transaction will not be created.
metricNameFormat

The name format to use for a metric. If not present, then this will default to the class name followed by the method name. You can only set the metricNameFormat on pointcuts where transactionStartPoint is set to false.

excludeFromTransactionTrace When true the transaction trace will not be provided if this pointcut initiates the transaction. If the pointcut is reached in the middle of a transaction, then the transaction trace will still be present, but this method will be excluded from the call graph.
ignoreTransaction When true the entire transaction will be ignored.
transactionType Sets the type of the transaction. Possible values are background (default) and web. When set to web, the transaction will be reported as a web transaction.
Child nodes for pointcut

A pointcut can have several different child nodes:

Value Definition
nameTransaction If this element is present, the agent will name the transaction using the class name and method(s) instrumented by this pointcut.
methodAnnotation The case sensitive full name of an annotation class including the package name. All methods that are marked with this annotation will be matched.
className

The case sensitive name of the class to match, including the package name. Pair this node with the method node. If this node is present on a pointcut, then the interfaceName node cannot be present on the same pointcut node.

The className node has the attribute includeSubclasses. If true the methods on the class with the matching name will be instrumented along with the matching methods on any child class of this class. If false (default), only methods on the exact class specified will be instrumented.

The className must follow these rules:

  • Inner classes can be instrumented.
  • The full package structure with dots between packages must be used.
  • To match subclasses of the specified class, set the attribute includeSubclasses to true.
interfaceName

The case sensitive name of an interface, including the package name, whose implementation classes will be matched. Pair this node with the method node. If this node is present on a pointcut, then the className node cannot be present on the same pointcut node.

The interfaceName must follow this rule: The full package structure with dots between packages must be used.

method A method on the class to instrument. Pair this node with a className node. Also, the method node can have children.
Child nodes for method

The method node can have several children. For more information and examples, see Troubleshooting Java custom instrumentation.

Value Definition
name

The exact case sensitive name of the method to match.

A method name node must follow these rules:

  • Public, protected, private, and package methods can all be instrumented.
  • Static and instance methods can be instrumented.
  • Constructors cannot be instrumented.
parameters

The parameter types of the method specified in order. If the parameters element is not present, then all methods matching the name will be matched. This includes private and protected declarations.

A method parameters node contains a list of the method's parameters, specified by type elements. Here are the major rules for the type elements:

  • Primitives are specified using their normal name: int, float, double, long, byte, short, boolean, char.
  • Objects require a full package structure. For example, do not use String in the XML; instead, use java.lang.String.
  • Do not use generics with collection objects. For example, write java.util.List instead of java.util.List<String>.
  • Include brackets for arrays. For example, an array of integers will be int[ ] and an array of strings will be java.lang.String[ ].
  • Include two sets of brackets for an array of arrays. For example, an array of arrays of longs would be long[ ][ ].
  • To send the parameter as an analytic event to Insights, add an XML attribute to the type element called attributeName.
  • To use a method with no parameters, the parameters node needs to be present to match a "no arguments" method.
returnType The case sensitive name of a class indicating a return type to match. All methods that return this class type will be matched.

Example

Below is a sample class and an XML file that could be used to instrument that class.

Sample class
package test;

public class SampleTester {

  private String configName;
  private Map<String, Long> maxSampleTimes;

  public SampleTester(String pConfigName) {
    configName = pConfigName;
  }

  public void checkSample(String name, long[] times) {
    if(times != null) {
      maxSampleTimes.put(name, getFirst(times));
    } else {
      maxSampleTimes.put(name, Long.valueOf(getFirst()));
    }
  }

  private Long getFirst(long[] times) {
    return Long.valueOf(times[0]);
  }
  
  private int getFirst() {
    return 0;
  }
  
  public void printMaxRepeat(long max) throws Exception {
    Runnable myRunnable = new Runnable() {

      @Override
      public void run() {
        try {
          printMax(max);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }

    };
    ScheduledExecutorService scheduledExecutor = Executors
      .newScheduledThreadPool(1);
    scheduledExecutor.scheduleWithFixedDelay(myRunnable, 0, 10000,
      TimeUnit.MILLISECONDS);
  }

  private void printMax(long max) {
    System.out.println("max is " + max);
  }

}
Sample XML instrumentation file and explanation
<?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="EXAMPLE">
    <pointcut transactionStartPoint="true">
    
      <!--class name is preceded by package name-->
      <className>test.SampleTester$1</className>
      <method>
        <name>checkSample</name>
        <parameters>
          <type attributeName="sampleName">java.lang.String</type>
          <type>long[]</type>
        </parameters>
      </method>
      <!--two methods with the same name but different signatures can share one node-->
      <method>
        <name>getFirst</name>
      </method>
      <method>
        <name>run</name>
      </method>
    </pointcut>

    <pointcut transactionStartPoint="false" ignoreTransaction="false"
      excludeFromTransactionTrace="false"
      metricNameFormat="SampleTester/methods">
      <className>test.SampleTester</className>
      <method>
        <name>printMaxRepeat</name>
      </method>
     <method>
        <name>printMax</name>
      </method>
    </pointcut>

  </instrumentation>
</extension>

The first block of the XML file specifies the name and version of the extension. As the XML extension is default enabled, that attribute is not specified.

The second block specifies the methods in SampleClass that should be instrumented. A transaction is started at the beginning of the block. It is worth noting that in the example class, there are two methods that share a name (getFirst) but have different signatures. These are instrumented with a single method node. By removing the parameters node, all methods with the same name can be matched under one method node.

In the third block, the specified methods do not have a transaction started on them. This is because the transaction has already been started in run. The transaction will not be ignored, and will be included in the transaction trace.

Do not instrument all of your methods, as this can lead to a metric grouping issue.

For more help

See the links below for more information:

Join the discussion about Java monitoring in the New Relic Online Technical Community! The Technical Community is a public platform to discuss and troubleshoot your New Relic toolset.

If you need additional help, get support at support.newrelic.com.