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. For more information, see Java instrumentation by XML.
Edit XML file in UI
To edit your XML file directly from the New Relic UI: Go to one.newrelic.com > All capabilities > APM & services > (select an app) > Settings > Instrumentation. From here you can:
- Download a sample XML file.
- Select an edit existing XML file.
- Search the instrumentation history.
XML file format
The XML file format includes root and child nodes.
注意
Do not instrument all of your methods, as this can lead to a metric grouping issue.
The root node of an XML file is extension
. It can have three different attributes:
Value | Definition |
---|---|
| A unique but descriptive name identifying your XML extension. |
| Identifies whether the extension will be read by the Java agent. Default is |
| The version of the extension. If two extensions have the same name, only the extension with the highest version will be used. |
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
.
The pointcut
is a child node of instrumentation
and can have several attributes. Also, a pointcut
can have several different child nodes.
Value | Definition |
---|---|
| 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. |
| 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 |
| When |
| When |
| Sets the type of the transaction. Possible values are |
A pointcut
can have several different child nodes:
Value | Definition |
---|---|
| If this element is present, the agent will name the transaction using the class name and method(s) instrumented by this pointcut. |
| The case sensitive full name of an annotation class including the package name. All methods that are marked with this annotation will be matched. |
| 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 The The
|
| 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 The |
| A method on the class to instrument. Pair this node with a |
| The class name, including package, in the format used in bytecode, for example All methods that return an object of that class will be matched. |
| A boolean indicating whether to match lambdas. The
|
The method
node can have several children. For more information and examples, see Troubleshooting Java custom instrumentation.
Value | Definition |
---|---|
| The exact case sensitive name of the method to match. A method
|
| The parameter types of the method specified in order. If the A method
|
| The case sensitive name of a class indicating a return type to match. All methods that return this class type will be matched. |
Example
Here is a sample class and an XML file that could be used to instrument that class.
package test;
import java.util.HashMap;import java.util.Map;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;
public class SampleTester {
private String configName; private Map<String, Long> maxSampleTimes;
public SampleTester(String pConfigName) { configName = pConfigName; maxSampleTimes = new HashMap<>(); }
public void checkSample(String name, long[] times) { if (times != null) { maxSampleTimes.put(name, getFirst(times)); } else { maxSampleTimes.put(name, (long) getFirst()); } }
private Long getFirst(long[] times) { return times[0]; }
private int getFirst() { return 0; }
public void printMaxRepeat(final long max) throws Exception { Runnable myRunnable = new Runnable() { 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); }}
<?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</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.