Статьи

Настройка пользовательских инструментов с помощью нового агента Relic Java Agent

Новая Relic (помните, есть бесплатная версия Lite ) позволяет вам определять медленные транзакции приложения из коробки. Это означает, что вы можете просто загрузить агент, запустить приложение, работающее с агентом, и вскоре увидеть медленные транзакции.

Хотя выявление медленных транзакций является ключом к настройке производительности, бывают случаи, когда мне нужна дополнительная информация о конкретной транзакции, которая не обязательно является самой медленной. Иногда я просто хочу узнать, сколько раз вызывается конкретный метод. В других, я хочу, чтобы информация о времени определенного метода не была автоматически снабжена инструментами. Или, может быть, я просто хочу исключить все вызовы рекурсивного метода из трассировки транзакции. New Relic предоставляет эти функции с помощью пользовательских инструментов .

Пользовательские инструменты с использованием Java-агента New Relic
Поскольку я работаю с Java-агентом New Relic, этот пост будет посвящен трем механизмам, которые он предоставляет для получения метрической информации об определенных транзакциях. Если вы заинтересованы в настройке пользовательских инструментов с другими нашими агентами, см. Ссылки в конце этого поста.

Один из способов настроить пользовательские инструменты с помощью агента Java — использовать API New Relic . Наш API позволяет создавать метрики, счетчики приращений, уведомления об ошибках, игнорировать транзакции и многое другое в вашем коде. Для начала:

1. Просто добавьте newrelic-api.jar в ваш путь к классу.
2. Вызвать соответствующий статический метод из API NewRelic в вашем коде.
3. Перекомпилируйте и перезапустите приложение с помощью агента Java.

Если вы предпочитаете аннотации , этот второй вариант может быть для вас:

1. Установите для enable_custom_tracing значение true в файле newrelic.yml. Обязательно добавьте флаг, если он еще не существует.
2. Добавьте newrelic-api.jar в ваш путь к классам.
3. Добавьте аннотацию Trace к методу, который вы хотите отслеживать.
4. Перекомпилируйте и перезапустите приложение с помощью агента Java.

Если изменение исходного кода невозможно или нежелательно, вы должны использовать третий механизм New Relic для пользовательского инструментария. Новая реликвия позволяет создавать XML-файл расширений, в котором указываются комбинации классов и методов, которые вы хотите отслеживать. New Relic затем прочитает файл при запуске и установит соответствующие классы.

Пример.
Давайте рассмотрим эти три опции для пользовательского инструментария на примере. Предположим, у вас есть следующий класс:

package com.example;
 
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
public class CustomSample {
 
    public void sampleMethod() throws Exception {
        Runnable myRunnable = new Runnable() {
 
            @Override
            public void run() {
                firstPart();
                secondPart();
            }
 
        };
        ScheduledExecutorService scheduledExecutor = Executors
                .newScheduledThreadPool(1);
        scheduledExecutor.scheduleWithFixedDelay(myRunnable, 0, 10000,
                TimeUnit.MILLISECONDS);
    }
 
    private void firstPart() {
        System.out.println("In the first part.");
    }
 
    private void secondPart() {
        System.out.println("In the second part.");
    }
 
}

Вариант 1. Новый Relic API.
Чтобы использовать новый Relic API, сначала поместите newrelic-api.jar в путь к классам. Тогда сам класс должен быть модифицирован. Предположим, вы хотите подсчитать количество вызовов метода. Это можно сделать, добавив вызов метода incrementCounter в API New Relic. Единственным входным параметром для этого метода является имя метрики. Ниже я решил вызвать метрику «CustomSample.run».

@Override
public void run() {
    firstPart();
    secondPart();
  NewRelic.incrementCounter(“CustomSample.run”);
}

Между тем, вы можете использовать метод recordMetric из API New Relic для записи времени, которое занимает метод firstPart. Этот метод принимает имя метрики и значение метрики в качестве параметров. Хотя я решил указать время ниже, значение может быть любым, что умещается в число с плавающей точкой. Например, я мог бы установить значение метрики равным значению с плавающей запятой, вытекающему из некоторой бизнес-логики.

Если вы решите измерять время метода самостоятельно, обязательно используйте метод System.nanoTime () вместо метода System.currentTimeMillis (). Время в миллисекундах основано на системных часах, которые могут быть сброшены, что приводит к времени запуска, которое позже, чем время остановки.

    private void firstPart() {
       long start = System.nanoTime();
        System.out.println("In the first part.");
        long timeDifference = System.nanoTime() -start;
        NewRelic.recordMetric(“CustomSample.firstPart”,
timeDifference);
    }

После внесения изменений в код перекомпилируйте и перезапустите приложение с помощью агента Java.

Вариант 2 — аннотации
Чтобы использовать аннотации New Relics, не забудьте установить для свойства enable_custom_tracing значение true в файле конфигурации newrelic.yml и поместить newrelic-api.jar в путь к классам. Если вы хотите использовать метрики для метода run, необходимо добавить аннотацию Trace. Кроме того, поскольку этот метод, скорее всего, будет началом транзакции, вам необходимо включить dispatcher = true, как показано ниже. Когда для этого свойства установлено значение true, новая транзакция запускается при достижении метода, если транзакция еще не выполняется. Если метод встречается после запуска транзакции, то эта транзакция будет продолжена, и новая не будет создана. Свойство диспетчера по умолчанию имеет значение false.

@Override
@Trace(dispatcher=true)
public void run() {
    firstPart();
    secondPart();
}

Чтобы отслеживать метод firstPart, вам также необходимо добавить аннотацию Trace к этому методу. Поскольку метод firstPart будет вызываться в методе run, то есть после того, как транзакция уже запущена, для свойства диспетчера можно по умолчанию задать значение false.

@Trace
 private void firstPart() {
    System.out.println("In the first part.");
}

После внесения изменений в код перекомпилируйте и перезапустите приложение с помощью агента Java.

Вариант 3 — Файлы расширения XML
Чтобы использовать файлы расширения XML, сначала необходимо создать файл XML. Файлы расширений XML должны соответствовать определению схемы newrelic-extension.xsd, которое можно найти в zip-файле агента Java, начиная с версии 2.10.0. Вы также найдете файл примера с именем newrelic-extension-example.xml, который инструментирует некоторые из методов, найденных в JDK.

Вот несколько указателей при создании файла:

1. Обязательно всегда указывайте имя и версию. Если у вас есть два файла с расширением XML с одинаковым именем, будет реализован только файл с более высокой версией.

2. metricPrefix является необязательным параметром на узле КИП, который используется как часть имени метрики. Если не установлено, по умолчанию используется «CUSTOM».

3. Методы, которые нужно отслеживать, вводятся в точечные разрезы. Отдельный точечный разрез должен использоваться для каждого класса. Тем не менее, несколько методов из этого класса могут быть перечислены в пределах одной и той же точки.

Файл расширения XML для инструментирования метода run показан ниже. Поскольку run на самом деле находится во внутреннем классе, имя класса — com.example.CustomSample $ 1. Кроме того, так как выполнение должно быть началом транзакции, для атрибута transactionStartPoint установлено значение true на узле среза точки.

<?xml version="1.0" encoding="UTF-8"?>
<urn:extension xmlns:urn="newrelic-extension"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="newrelic-extension extension.xsd " name="customExtension" version="1.0">
        <urn:instrumentation metricPrefix="EXAMPLE">
         <urn:pointcut transactionStartPoint="true">
            <urn:className>com.example.CustomSample$1</urn:className>
            <urn:method>
                <urn:name>run</urn:name>
            </urn:method>
        </urn:pointcut>
        </urn:instrumentation>
</urn:extension>

Чтобы также отслеживать методы firstPart и secondPart из класса CustomSample, необходимо добавить срез точки в XML выше. Эта точка разреза показана ниже. Обратите внимание, что для атрибута transactionStartPoint по умолчанию задано значение false, поскольку оба эти метода должны вызываться из метода run и, следовательно, будут вызываться внутри транзакции. Также обратите внимание, что если вы хотите исключить эти методы из трассировки стека, вы можете установить для атрибута excludeFromTransactionTrace значение true в узле среза точки.

<urn:pointcut>
    <urn:className>com.example.CustomSample</urn:className>
    <urn:method>
        <urn:name>firstPart</urn:name>
    <urn:method>
        <urn:name>secondPart</urn:name>
    </urn:method>
</urn:pointcut>

Как только файл расширения XML будет завершен, обязательно проверьте его. Это можно сделать с помощью следующей команды.

java -jar newrelic.jar instrument -file /path/to/extension.xml

Это приложение проверки будет проверять синтаксис XML и проверять, что все классы и методы, найденные в файле XML, присутствуют в пути к классам. Затем он выведет «PASS» или «FAIL» на консоль. Если файл XML не проходит проверку, причина, по которой он не прошел, также будет распечатана.

После того, как файл XML верен, задайте для свойства ‘extensions.dir’ в файле newrelic.yml каталог, в котором находится ваш файл XML. Затем перезапустите приложение с агентом.

Заключение
Я считаю, что эти опции для пользовательских инструментов очень полезны. Тем не менее, предостережение: пользовательские инструменты предназначены для использования только для нескольких методов. Вы не должны пытаться использовать каждый метод каждого класса. Это снизит производительность вашего приложения. Тем не менее, я призываю вас попробовать индивидуальные инструменты для себя. Больше примеров и документации по агенту Java можно найти здесь .