Моніторинг і метрики для Play Framework за допомогою Dropwizard Metrics

В якийсь момент розробки програми, кожен з нас приходить до того, що нам потрібно більше інформації про те, що відбувається усередині додатку або ж в можливості моніторити додаток. У випадку з Play Framework вже є готове рішення у вигляді чудової бібліотеки з відкритим кодом Kamon в парі з модулем kamon-play.
Але сьогодні ми збираємося глянути на альтернативне рішення, інтеграцію і використання Drowizard Metrics раніше відоме як
Codahale Metrics
з Play Framework.

Інтеграція
Так я почав шукати готові рішення, які могли б мені допомогти в інтеграції цих двох інструментів.
Я знайшов кілька не повних рішень:
  • metrics-scala — Чудова бібліотека, витончений API з хорошою підтримкою Scala, але у випадку з Play Framework не досить поддрежки.
  • metrics-play — Одне з перших рішень якими Google намагається задовольнити ваш запит, але ця бібліотека вже не підтримується і не сумісна з останніми версіями Play Framework і Dropwizard Metrics. Але є форк, який оновити до останніх версій, так що я вирішив спробувати його.
На жаль модуль metrics-play надає тільки базовий функціонал з усього що є в середовищі Dropwizard Metrics. Це може бути достатньо, якщо вам потрібні прості метрики які доступні через REST api, але у мене були більш високі вимоги і я вирішив доповнити функціонал цього модуля написавши наступні модулі:
Власне про це ми будемо говорити далі.

Підтримка Metrics репортерів в Play Framework

Metrics надає потужний інструментарій для моніторингу поведінки критичних компонентів у продакшн середовищі. Так само, надає засоби для відправки виміряних даних через репортерів. Metrics репортери — це відмінний спосіб надсилання даних з додатка в бажану систему зберігання та візуалізації метрик.
На момент написання статті підтримувані репортери наступні:
  • console — Періодично відправляє дані в стандартний потік виходу програми
  • graphite — Періодично відправляє дані в Graphite.
Dropwizard Metrics і ком'юніті також надають інші репортери, на приклад
Ganglia Reporter
,
CSV Reporter
,
InfluxDB Reporter
,
ElasticSearch Reporter
та інші.
Додавання фекторі для підтримки репортерів у бібліотеку є легким завданням.

Підтримка анотацій Metrics для Play Framework через Guice AOP

За умовчанням, для того що б використовувати метрики потрібно викликати Metric Registry для створення метрик, створити контекст і в ручну управляти їм. На приклад:
def doSomethingImportant() = {
val timer = registry.timer(name(classOf[WebProxy], "get-requests"))
val context = timer.time()
try // critical business logic
finally context.stop()
}

Що б тримати все
DRY
є анотації, модуль metrics-annotation-play буде створювати та належним чином викликати Timer для
@Timed
, Meter для
@Metered
, Counter
@Counted
і Gauge
@Gauge
.
@ExceptionMetered
також підтримується, він створює Meter, який вимірює частоту викидання винятків.
Попередній приклад можна переписати наступним чином:
@Timed
def doSomethingImportant = {
// critical business logic
}

чи ж можна сдекарировать весь клас, що створить метрики для всіх явних методів:
@Timed
class SuperCriticalFunctionality {
def doSomethingImportant = {
// critical business logic
}
}

Даний функціонал підтримується тільки для класів створених через Guice, так само є деякі обмеження AOP.
Приклад
Давайте спробуємо використовувати бібліотеку в реальному додатку і розглянемо, як все працює. Вихідний код програми можна знайти на тут.
Я використовую шаблон
activator play-scala
,
sbt plugin
. Ми повинні додати
JCenter
список
resolvers
та залежності:
name := """play_metrics_example"""

версія := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.8"

resolvers += Resolver.jcenterRepo

libraryDependencies ++= Seq(
"de.khamrakulov.metrics-reporter-play" %% "reporter-core" % "1.0.0",
"de.khamrakulov" %% "metrics-annotation-play" % "1.0.2",
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test
)

Для прикладу я використовую
сonsole
репортер, давайте додамо конфігурацію
application.conf
.
metrics {
jvm = false
logback = false

reporters = [
{
type: "console"
frequency: "10 seconds"
}
]
}

Як ви бачите я деактивував метрики
jvm
та
logback
, що б не втратити наші метрики і додав репортер, який буде виводити метрики
stdout
c періодичністю 10 секунд.
Тепер ми можемо почати використовувати анотації, я сдекорирую метод
index
контролера
HomeController
:
@Singleton
class HomeController @Inject() extends Controller {

@Counted(monotonic = true)
@Timed
@Metered
def index = Action {
Ok(views.html.index("Your new application is ready."))
}

}

насправді ви не повинні використовувати всі анотації разом, т. к.
@Timed
комбінує в собі
Counter
та
Meter
, але я це зробив для демонстрації можливостей.
Після старту програми та запиту
Головної Сторінки
, репортер повинен вивести метрики
stdout
:
-- Counters --------------------------------------------------------------------
controllers.HomeController.index.current
count = 1

-- Meters ----------------------------------------------------------------------
controllers.HomeController.index.meter
count = 1
mean rate = 0.25 events/second
1-minute rate = 0.00 events/second
5-minute rate = 0.00 events/second
15-minute rate = 0.00 events/second

-- Timers ----------------------------------------------------------------------
controllers.HomeController.index.timer
count = 1
mean rate = 0.25 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 14.59 milliseconds
max = 14.59 milliseconds
mean = 14.59 milliseconds
stddev = 0.00 milliseconds
median = 14.59 milliseconds
75% <= 14.59 milliseconds
95% <= 14.59 milliseconds
98% <= 14.59 milliseconds
99% <= 14.59 milliseconds
99.9% <= 14.59 milliseconds

Звичайно ж ви все ще можете переглянути метрики через REST api, для цього треба додати конфігурацію
routes
файл:
GET /admin/metrics com.kenshoo.play.metrics.MetricsController.metrics

Що далі?
Автоматична перевірка працездатності програми (Health Checks)
Metrics так само підтримує можливість використання автоматичних перевірок працездатності програми(health checks). Більше інформації можна знайти на офіційній документації.
Більше репортерів
Для створення належної середовища використання метрик потрібна підтримка більшої кількості репортерів. Це має бути ще одним напрямком розвитку бібліотеки.
Належна підтримка Future
На даний момент, що б виміряти час виконання
Future
треба в ручну виконувати всі дії. Належна підтримка Future може допомогти асинхронної середовищі Play Framework і може бути хорошим доповненням.
Підтримка HdrHistogram
Hdrhistogram надає альтернативну реалізацію колектора (reservoir) високої якості, який може бути використаний для
Histogram
та
Timer
.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.