Ранее в заметке Делаем метрики и мониторинг для Akka при помощи Kamon мы уже познакомились с некоторыми возможностями Kamon. Правда, нельзя сказать, что возможности эти были особо впечатляющими, так как метрики можно вполне успешно писать и безо всякого Kamon. Сегодня же мы познакомимся с некоторыми другими средствами, предоставляемыми этой несколько спорной, но определенно очень мощной библиотекой.
Первая довольно часто встречающаяся на практике задача — неявное пробрасывание некоторого контекста между акторами. Допустим, актор A1 проставляет некоторый контест, например, информацию о пользователе, запросе, с которым он пришел в бэкенд, а также, возможно, некоторых параметрах этого запроса. Затем актор A1 шлет запрос A2, тот шлет A3, и так далее, до A42. Отметим, что если в проекте используется Akka Cluster , акторы эти могут быть на очень даже разных машинах. В какой-то момент мы решили, что в акторе A42 неплохо бы получить информацию о контексте, полученном в акторе A1. Можно, конечно, пробрасывать этот контекст явно во всех сообщениях между акторами. Или менее явно, если воспользоваться имплиситами. Но для этого нам понадобится поправить код как минимум в 42 местах! А возможно и больше, так как акторы могут обмениваться несколькими типам сообщений.
К счастью, с помощью Kamon эту проблему можно решить намного проще.
В акторе A1 пишем что-то вроде:
«TestContext» ,
traceToken = Some ( s «dummy-trace-token» ) ,
autoFinish = true ) {
// … тут обычный код с запросами к остальным акторам …
}
Теперь в акторе A42 можно написать:
… и получить текущий контекст, в данном случае строчку «dummy-trace-token». Понятно, что в общем случае нам хотелось бы передавать что-то чуть более интересное, чем обычные строки. Это легко реализовать, создав новый case class с поддержкой сериализации в JSON . Работает такое пробрасывание контекста на магии AspectJ, поэтому в IntelliJ IDEA на забудьте в Run → Edit Configurations… → VM Options прописать -javaagent:/path/to/aspectjweaver-1.8.2.jar
. Также этот параметр требуется передавать JVM при запуске приложения в продакте, поэтому не забудьте поправить wrapper.conf или что вы там используете в проекте.
Не правда ли, приведенное выше решение лучше, чем внесение правок в 42 местах?
Рассмотрим еще пример. Когда в большом (и особенно — распределенном!) проекте что-то где-то начинает тормозить, определить, что именно, где именно и почему тормозит не всегда бывает просто. Kamon помогает нам и здесь.
Определим такой вот актор для сборки трейсов:
import akka. actor . { ActorLogging, Actor }
import kamon. trace . TraceInfo
class TraceSubscriber extends Actor with ActorLogging {
var traceNumber = 0
override def receive : Receive = {
case inf : TraceInfo =>
traceNumber = traceNumber + 1
val segmentsNumber = inf. segments . size
log. info (
s «»»|Trace number $traceNumber —
|Trace Name: ${inf.name},
|timestamp: ${inf.timestamp},
|elapsedTime: ${inf.elapsedTime},
|segmentsNumber: $segmentsNumber
|»»» . stripMargin . replace ( ‘ n ‘ , ‘ ‘ )
)
}
}
Подпишем его на трейсы:
system. actorOf ( Props ( new TraceSubscriber ) , «traceSubscriber» )
}
Kamon. tracer . subscribe ( traceSubscriber )
Теперь внутри блока Tracer.withNewContext (см выше) мы можем определять так называемые «сегменты»:
«Main/sayHello» ,
«ask» ,
«me.eax.example» ) {
// … тут обычный код …
}
При выходе из блока Tracer.withNewContext в актор traceSubscriber магическим образом будет прилетать информация обо всех сегментах, выполненных в рамках контекста. Помимо информации, используемой в примере кода выше, можно также получить данные и о каждом отдельном сегменте, включая время, которое этот сегмент выполнялся:
Само собой разумеется, частоту, с которой прилетают сэмплы трейсов, можно настроить через конфиг.
Полную версию исходного кода к этой заметке можно найти на GitHub . Обратите особое внимание на использование плагина sbt-aspectj, подкладывание файла META-INF/aop.xml, а также настройки проекта в build.sbt. Следует понимать, что этот пост поверхностно описывает сравнительно простой пример, а больше подробной информации о представленном выше функционале вы найдете на официальном сайте Kamon .
А используете ли вы в своих проектах описанные возможности Kamon?