Статьи

Yammer Metrics, новый способ мониторинга вашего приложения

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

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

1
2
3
4
5
6
7
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependencies></span> <Зависимостей></span>
    <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><dependency></span> <Зависимость></span>
        <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><groupId>com.yammer.metrics</groupId></span> <Идентификатор_группы> com.yammer.metrics </ идентификатор_группы></span>
        <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><artifactId>metrics-core</artifactId></span> <Артефакт> Метрика-ядро </ артефакт></span>
        <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><version>2.2.0</version></span> <Версия> 2.2.0 </ версия></span>
    <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependency></span> </ Зависимость></span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"></dependencies></span> </ Зависимости></span>

Теперь пришло время добавить некоторые метрики в наш код. В метриках мы можем использовать 6 типов метрик:

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

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

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

1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public class MetricsApplication { Counter private final Counter numberOfSendCharacters = Metrics.newCounter(MetricsApplication.class, 'Total-Number-Of-Characters');</span> открытый класс MetricsApplication {Счетчик закрытого конечного счетчика numberOfSendCharacters = Metrics.newCounter (MetricsApplication.class, «Общее количество символов»);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Meter private final Meter sendMessages = Metrics.newMeter(MetricsApplication.class, 'Sent-Messages', 'Send', TimeUnit.SECONDS);</span> Meter private final Meter sendMessages = Metrics.newMeter (MetricsApplication.class, 'Sent-Messages', 'Send', TimeUnit.SECONDS);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Timer private final Timer responseTime = Metrics.newTimer(MetricsApplication.class, 'Response-Time');</span> Таймер приватный окончательный Таймер responseTime = Metrics.newTimer (MetricsApplication.class, 'Response-Time');</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">private LinkedList<String> historyOfQueries = new LinkedList<String>();</span> private LinkedList <String> historyOfQueries = new LinkedList <String> ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">{ Gauge Metrics.newGauge(MetricsApplication.class, 'lastQuery', new Gauge<String>() { @Override public String value() { return historyOfQueries.getLast(); } });</span> {Gauge Metrics.newGauge (MetricsApplication.class, 'lastQuery', new Gauge <String> () {@Override public String value () {return historyOfQueries.getLast ();}});</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} public void sendQuery(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException { updateMetrics(message);</span> } public void sendQuery (String message) выдает FailingHttpStatusCodeException, MalformedURLException, IOException {updateMetrics (message);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">TimerContext timerContext = responseTime.time();</span> TimerContext timerContext = responseTime.time ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">sendQueryToGoogle(message);</span> sendQueryToGoogle (сообщение);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">timerContext.stop();</span> timerContext.stop ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} private void sendQueryToGoogle(String message) throws FailingHttpStatusCodeException, MalformedURLException, IOException { WebClient webClient = new WebClient();</span> } private void sendQueryToGoogle (String message) выдает FailingHttpStatusCodeException, MalformedURLException, IOException {WebClient webClient = new WebClient ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HtmlPage currentPage = webClient.getPage('http:www.google.com');</span> HtmlPage currentPage = webClient.getPage ('http: www.google.com');</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Get the query input text HtmlInput queryInput = currentPage.getElementByName('q');</span> Получить входной текст запроса HtmlInput queryInput = currentPage.getElementByName ('q');</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">queryInput.setValueAttribute(message);</span> queryInput.setValueAttribute (сообщение);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Submit the form by pressing the submit button HtmlSubmitInput submitBtn = currentPage.getElementByName('btnG');</span> Отправьте форму, нажав кнопку отправки. HtmlSubmitInput submitBtn = currentPage.getElementByName ('btnG');</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">currentPage = submitBtn.click();</span> currentPage = submitBtn.click ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} private void updateMetrics(String message) { numberOfSendCharacters.inc(message.length());</span> } private void updateMetrics (String message) {numberOfSendCharacters.inc (message.length ());</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">sendMessages.mark();</span> sendMessages.mark ();</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">historyOfQueries.addLast(message);</span> historyOfQueries.addLast (сообщение);</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} }</span> }}</span>

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

Следующее свойство — это индикатор, который измеряет скорость отправки запросов с течением времени. Затем у нас есть таймер, который оценивает вызовы метода sendQueryToGoogle и его распределение по времени. И, наконец, LinkedList для хранения всех отправленных запросов. Этот экземпляр будет использоваться для возврата последнего выполненного запроса и используется в индикаторе для возврата последнего вставленного элемента.

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

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

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

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

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

Ссылка: Yammer Metrics, новый способ мониторинга вашего приложения от нашего партнера JCG Алекса Сото в блоге One Jar To Rule All .