- PVSM.RU - https://www.pvsm.ru -
В какой то момент разработки приложения, каждый из нас приходит к тому, что нам нужно больше информации о том, что происходит внутри приложения или же в возможности мониторить приложение. В случае с Play Framework уже существует готовое решение в виде отличной библиотеки с открытым исходным кодом Kamon [1] в паре с модулем kamon-play [2].
Но сегодня мы собираемся взглянуть на альтернативное решение, интеграцию и использование Drowizard Metrics [3] ранее известное как Codahale Metrics
с Play Framework.
Так я начал искать готовые решения которые могли бы мне помочь в интеграции этих двух инструментов.
Я нашел несколько не полных решений:
К сожалению модуль metrics-play [6] предоставляет только базовый функционал из всего что имеется в среде Dropwizard Metrics. Это может быть достаточно, если вам нужны простые метрики которые доступны через REST api, но у меня были более высокие требования и я решил дополнить функционал этого модуля написав следующие модули:
Собственно об этом мы будем говорить далее.
Metrics предоставляет мощный инструментарий для мониторинга поведения критических компонентов в продакшн среде. Так же, предоставляет средства отправки измеренных данных через репортеров. Metrics репортеры — это отличный способ отправки данных из самого приложения в предпочитаемую систему хранения и визуализации метрик.
На момент написания статьи поддерживаемые репортеры следующие:
Dropwizard Metrics и комьюнити также предосталяют другие репортеры, на пример Ganglia Reporter
, CSV Reporter
, InfluxDB Reporter
, ElasticSearch Reporter
и другие.
Добавление фэктори для поддержки репортеров в библиотеку является легкой задачей.
По умолчанию, для того что бы использовать метрики нужно вызвать 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 [8] будет создавать и надлежащим образом вызвать 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.
Давайте попробуем использовать библиотеку в реальном приложении и рассмотрим, как все работает. Исходный код приложения можно найти тут [9].
Я использую шаблон activator play-scala
с sbt plugin
. Мы должны добавить JCenter
в список resolvers
и зависимости:
name := """play_metrics_example"""
version := "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
Metrics так же поддерживает возможность использования автоматических проверок работоспособности приложения(health checks). Больше информации можно найти в официальной документации [10].
Для создания надлежащей среды использования метрик нужна поддержка большего количества репортеров. Это должно быть еще одним направлением развития библиотеки.
На данный момент, что бы измерить время выполнения Future
нужно в ручную выполнять все действия. Надлежащая поддержка Future может помочь в асинхронной среде Play Framework и может быть хорошим дополнением.
Hdrhistogram [11] предоставляет альтернативную реализацию коллектора (reservoir) высокого качества, который может быть использован для Histogram
и Timer
.
Автор: Timur_Kh
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/211256
Ссылки в тексте:
[1] Kamon: http://kamon.io/
[2] kamon-play: http://kamon.io/integrations/web-and-http-toolkits/play/
[3] Drowizard Metrics: http://metrics.dropwizard.io
[4] metrics-scala: https://github.com/erikvanoosten/metrics-scala
[5] metrics-play: https://github.com/kenshoo/metrics-play
[6] форк: https://github.com/breadfan/metrics-play
[7] metrics-reporter-play: https://github.com/htimur/metrics-reporter-play
[8] metrics-annotation-play: https://github.com/htimur/metrics-annotation-play
[9] тут: https://github.com/htimur/play_metrics_example
[10] официальной документации: http://metrics.dropwizard.io/3.1.0/manual/healthchecks/
[11] Hdrhistogram: http://hdrhistogram.org/
[12] Источник: https://habrahabr.ru/post/315554/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.