Метрики
=======
Xitrum собирает информацию об использовании памяти, CPU и информацию об использовании
контроллеров каждой ноды вашего Akka кластера. Эти данные публикуются в JSON формате.
Xitrum так же позволяет публиковать ваши метрики.
Эти метрики базируются на библиотеке `Coda Hale Metrics `_.
Агрегирование метрик
--------------------
Память и CPU
~~~~~~~~~~~~
Информация по памяти и CPU собирается с помощью
`NodeMetrics `_
системы актров каждой ноды.
Память:
.. image:: ../img/metrics_heapmemory.png
CPU: Количество процессоров и средняя загрузка
.. image:: ../img/metrics_cpu.png
Метрики контроллера
~~~~~~~~~~~~~~~~~~~
Xitrum собирает состояния выполнения каждого контроллера в формате
`гистограммы `_.
Вы можете узнать сколько раз контроллер запускался, время выполнения для
не асинхронных запросов.
.. image:: ../img/metrics_action_count.png
Последнее время выполнения конкретного контроллера:
.. image:: ../img/metrics_action_time.png
Дополнительные метрики
~~~~~~~~~~~~~~~~~~~~~~
Дополнительные метрики вы можете собирать самостоятельно. Подробнее про использование читайте
`Coda Hale Metrics `_ и
`реализация на Scala `_. Используйте
пакет ``xitru.Metrics``, в нем ``gauge``, ``counter``, ``meter``, ``timer`` и ``histogram``.
Пример таймера:
::
import xitrum.{Action, Metrics}
import xitrum.annotation.GET
object MyAction {
lazy val myTimer = Metrics.timer("myTimer")
}
@GET("my/action")
class MyAction extends Action {
import MyAction._
def execute() {
myTimer.time {
// Задача время выполнения которой вы хотите замерить
...
}
...
}
}
Публикация метрик
-----------------
Xitrum публикует последние значения метрики в JSON формате через определенный интервал времени.
Этот интервал имеет не постоянное значение и может меняться.
Информация о памяти:
::
{
"TYPE" : "heapMemory",
"SYSTEM" : akka.actor.Address.system,
"HOST" : akka.actor.Address.host,
"PORT" : akka.actor.Address.port,
"HASH" : akka.actor.Address.hashCode,
"TIMESTAMP" : akka.cluster.NodeMetrics.timestamp,
"USED" : Number as byte,
"COMMITTED" : Number as byte,
"MAX" : Number as byte
}
Информация о CPU:
::
{
"TYPE" : "cpu",
"SYSTEM" : akka.actor.Address.system,
"HOST" : akka.actor.Address.host,
"PORT" : akka.actor.Address.port,
"HASH" : akka.actor.Address.hashCode,
"TIMESTAMP" : akka.cluster.NodeMetrics.timestamp
"SYSTEMLOADAVERAGE" : Number,
"CPUCOMBINED" : Number,
"PROCESSORS" : Number
}
MetricsRegistry использует `metrics-json `_ для разбора
JSON файла.
Просмотр метрик через Xitrum
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Xitrum предоставляет стандартный способ просмотра метрик по ссылке ``/xitrum/metrics/viewer?api_key=<смотри xitrum.conf>``.
По этой ссылке доступны графики представленные выше.
Графики созданы с использованием `D3.js `_.
Ссылка может быть сформирована следующим образом:
::
import xitrum.Config
import xitrum.metrics.XitrumMetricsViewer
url[XitrumMetricsViewer]("api_key" -> Config.xitrum.metrics.get.apiKey)
Jconsole
~~~~~~~~
Метрики можно просматривать через ``jconsole`` используя `JVM Reporter `_.
.. image:: ../img/metrics_jconsole.png
Запуск:
::
import com.codahale.metrics.JmxReporter
object Boot {
def main(args: Array[String]) {
Server.start()
JmxReporter.forRegistry(xitrum.Metrics.registry).build().start()
}
}
Затем используйте `jconsole `_.
Просмотр метрик сторонними средствами
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Метрики публикуются как ссылка SockJS ``xitrum/metrics/channel`` в формате JSON.
``jsAddMetricsNameSpace`` - шаблон JavaScript кода который предоставляет Xitrum
для установки соединения.
Реализуйте свой собственный JSON обработчик используя метод ``initMetricsChannel``.
Пример контроллера:
::
import xitrum.annotation.GET
import xitrum.metrics.MetricsViewer
@GET("my/metrics/viewer")
class MySubscriber extends MetricsViewer {
def execute() {
jsAddMetricsNameSpace("window")
jsAddToView("""
function onValue(json) {
console.log(json);
}
function onClose(){
console.log("channel closed");
}
window.initMetricsChannel(onValue, onClose);
""")
respondView()
}
}
Хранения метрик
~~~~~~~~~~~~~~~
Для экономии памяти, Xitrum не хранит старые значения метрик. Если вы хотите хранить эти
значения, вам передается реализовать собственный обработчик.
Например:
::
import akka.actor.Actor
import xitrum.metrics.PublisherLookUp
class MySubscriber extends Actor with PublisherLookUp {
override def preStart() {
lookUpPublisher()
}
def receive = {
case _ =>
}
override def doWithPublisher(globalPublisher: ActorRef) = {
context.become {
// When run in multinode environment
case multinodeMetrics: Set[NodeMetrics] =>
// Save to DB or write to file.
// When run in single node environment
case nodeMetrics: NodeMetrics =>
// Save to DB or write to file.
case Publish(registryAsJson) =>
// Save to DB or write to file.
case _ =>
}
}
}