Статьи

Метрики: новый способ мониторинга вашего приложения

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


Все эти виды инструментализации могут быть достигнуты с помощью нативного
JMX  или модульного проекта, такого как
Metrics .
Метрики предоставляют эффективный способ измерить поведение ваших критических компонентов и сообщить о них различным системам, таким как
JConsole ,
System Console ,
Ganglia ,
Graphite ,
CSV , или сделать их доступными через веб-сервер.

Чтобы установить
метрики , нам нужно только добавить метрики зависимости. В этом примере мы будем использовать Maven.

<dependencies>
    <dependency>
        <groupId>com.yammer.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>


Теперь пришло время добавить некоторые метрики в наш код.
В
метриках мы можем использовать 6 типов метрик:
  • Датчики : мгновенное измерение дискретного значения. 
  • Счетчики : значение, которое можно увеличивать и уменьшать. Может использоваться в очередях для мониторинга оставшегося количества ожидающих заданий.
  • Метры : измерьте скорость событий с течением времени. Вы можете указать единицу тарифа, объем событий или тип события.
  • Гистограммы : измерение статистического распределения значений в потоке данных.
  • Таймеры : измеряют количество времени, необходимое для выполнения фрагмента кода, и распределение его продолжительности.
  • Проверка работоспособности : как следует из его названия, она централизует проверку работоспособности внешних систем нашей службой.

Итак, давайте напишем действительно простое приложение (на самом деле это консольное приложение), которое отправляет запросы в
поисковую систему Google . Мы измерим количество петиций, количество символов, отправленных в
Google , последнее найденное слово и таймер для измерения скорости отправки запроса и получения ответа.

Основной класс, в котором
будут применяться
меры , называется
MetricsApplication и отвечает за подключение к
Google и отправку введенного слова.

public class MetricsApplication {

 

//Counter

private final Counter numberOfSendCharacters = Metrics.newCounter(MetricsApplication.class, "Total-Number-Of-Characters");

//Meter

private final Meter sendMessages = Metrics.newMeter(MetricsApplication.class, "Sent-Messages", "Send", TimeUnit.SECONDS);

//Timer

private final Timer responseTime = Metrics.newTimer(MetricsApplication.class, "Response-Time");

private LinkedList<String> historyOfQueries = new LinkedList<String>();

{

//Gauge

Metrics.newGauge(MetricsApplication.class, "lastQuery", new Gauge<String>() {

 

@Override

public String value() {

return historyOfQueries.getLast();

}

});

}

public void sendQuery(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException {

updateMetrics(message);

TimerContext timerContext = responseTime.time();

sendQueryToGoogle(message);

timerContext.stop();

}

 

private void sendQueryToGoogle(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException {

WebClient webClient = new WebClient();

HtmlPage currentPage = webClient.getPage("http://www.google.com/");

//Get the query input text

HtmlInput queryInput = currentPage.getElementByName("q");

queryInput.setValueAttribute(message);

//Submit the form by pressing the submit button

HtmlSubmitInput submitBtn = currentPage.getElementByName("btnG");

currentPage = submitBtn.click();

}

private void updateMetrics(String message) {

numberOfSendCharacters.inc(message.length());

sendMessages.mark();

historyOfQueries.addLast(message);

}

}


Первое, что мы видим, это контрпример.
Этот счетчик будет подсчитывать количество символов, отправленных в
Google за всю жизнь приложений (пока вы не остановите это).

Следующее свойство — это индикатор, который измеряет скорость отправки запросов с течением времени.

Затем у нас есть таймер, который оценивает
вызовы метода sendQueryToGoogle и его распределение по времени.

И, наконец,
LinkedList для хранения всех отправленных запросов. Этот экземпляр будет использоваться для возврата последнего выполненного запроса и используется в индикаторе для возврата последнего вставленного элемента.

Обратите внимание, что в каждой мере мы устанавливаем класс, который будет использоваться как папка в
jconsole . Кроме того, предусмотрена метка для использования в качестве имени внутри папки.

Давайте посмотрим на скриншот
jconsole с предыдущей конфигурацией и выполнением трех поисков:


По умолчанию все метрики видны через
JMX . Но, конечно, мы можем сообщить об измерениях на
консоль ,
http-сервер ,
Ganglia или
Graphite .  

Также обратите внимание, что в этом примере мы смешиваем код бизнес-кода и метрик.
Если вы планируете использовать  
метрики в своем производственном коде, я предлагаю вам по возможности использовать логику метрик в AOP.

Мы изучили простой способ мониторинга наших приложений без
непосредственного использования
JMX . Также имейте в виду, что
Metrics поставляется с некоторыми встроенными метриками для инструментов
HttpClient ,
JDBI ,
Jetty ,
Jersey ,
Log4j ,
Logback или
веб-приложений .