В какой то момент разработки приложения, каждый из нас приходит к тому, что нам нужно больше информации о том, что происходит внутри приложения или же в возможности мониторить приложение. В случае с Play Framework уже существует готовое решение в виде отличной библиотеки с открытым исходным кодом Kamon в паре с модулем kamon-play.


Но сегодня мы собираемся взглянуть на альтернативное решение, интеграцию и использование Drowizard Metrics ранее известное как Codahale Metrics с Play Framework.



Интеграция


Так я начал искать готовые решения которые могли бы мне помочь в интеграции этих двух инструментов.


Я нашел несколько не полных решений:


  • metrics-scala — Отличная библиотека, изящный API c хорошей поддержкой 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"""

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

Что дальше?


Автоматическая проверка работоспособности приложения (Health Checks)

Metrics так же поддерживает возможность использования автоматических проверок работоспособности приложения(health checks). Больше информации можно найти в официальной документации.


Больше репортеров

Для создания надлежащей среды использования метрик нужна поддержка большего количества репортеров. Это должно быть еще одним направлением развития библиотеки.


Надлежащая поддержка Future

На данный момент, что бы измерить время выполнения Future нужно в ручную выполнять все действия. Надлежащая поддержка Future может помочь в асинхронной среде Play Framework и может быть хорошим дополнением.


Поддержка HdrHistogram

Hdrhistogram предоставляет альтернативную реализацию коллектора (reservoir) высокого качества, который может быть использован для Histogram и Timer.

Поделиться с друзьями
-->

Комментарии (0)