如何配置 Akka 以使用 Kamon 向 Prometheus 公开指标?
How to configure Akka to expose metrics to Prometheus using Kamon?
我正在尝试配置基于 Akka 2.6.10 的项目,以将指标值公开给 Prometheus。我看到了这个 which uses Kamon 但我无法弄清楚我的配置中缺少什么。我的 build.sbt
文件具有以下配置:
name := """explore-akka"""
version := "1.1"
scalaVersion := "2.12.7"
val akkaVersion = "2.6.10"
lazy val kamonVersion = "2.1.9"
libraryDependencies ++= Seq(
// Akka basics
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion,
// Metrics: Kamon + Prometheus
"io.kamon" %% "kamon-core" % kamonVersion,
"io.kamon" %% "kamon-akka" % kamonVersion,
"io.kamon" %% "kamon-prometheus" % kamonVersion
)
和 plugins.sbt
:
resolvers += Resolver.bintrayRepo("kamon-io", "sbt-plugins")
addSbtPlugin("io.kamon" % "sbt-aspectj-runner" % "1.1.1")
我在 application.conf
上添加了:
kamon.instrumentation.akka.filters {
actors.track {
includes = [ "CounterSystem/user/Counter**" ]
}
}
然后我启动一个调用 counterActor 的 MainClass:
object MainClass extends App {
Kamon.registerModule("akka-test", new PrometheusReporter())
Kamon.init()
CounterActor.run()
}
import akka.actor.{Actor, ActorSystem, Props}
import kamon.Kamon
object CounterActor extends App {
run()
def run() = {
import Counter._
val actorSystem = ActorSystem("CounterSystem")
val countActor = actorSystem.actorOf(Props[Counter], "Counter")
(1 to 100).foreach { v =>
Thread.sleep(1000)
countActor ! Increment
}
(1 to 50).foreach { v =>
Thread.sleep(1000)
countActor ! Decrement
}
countActor ! Print
}
class Counter extends Actor {
import Counter._
val counter = Kamon.counter("my-counter")
var count = 0
override def receive: Receive = {
case Increment =>
count += 1
println(s"incrementing... $count")
counter.withoutTags().increment()
case Decrement =>
count -= 1
println(s"decrementing... $count")
counter.withoutTags().increment()
case Print =>
sender() ! count
println(s"[counter] current count is: $count")
}
}
object Counter {
case object Increment
case object Decrement
case object Print
}
}
我认为在此之后我可以使用 sbt run
启动应用程序并在 Prometheus 控制台上收听指标 (http://127.0.0.1:9090/graph),但我没有看到任何与我的演员相关的指标。我的猜测是我必须在 prometheus 文件 /etc/prometheus/prometheus.yml
中配置 scrape_config
。我对吗?我应该如何配置它?
我必须通过配置文件配置 Prometheus 来抓取 Kamon Web 服务
cat /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "kamon"
scrape_interval: "5s"
static_configs:
- targets: ['localhost:9095']
metrics_path: /
在 build.sbt
添加这 2 个 Kamon 库:
"io.kamon" %% "kamon-bundle" % "2.1.9",
"io.kamon" %% "kamon-prometheus" % "2.1.9",
在 application.conf
添加此配置:
kamon.instrumentation.akka.filters {
actors.track {
includes = [ "AkkaQuickStart/user/*" ]
# excludes = [ "AkkaQuickStart/system/**" ]
}
}
启动 Kamon 并调用计数器:
Kamon.init()
val counterSendMsg = Kamon.counter("counter-send-msg")
counterSendMsg.withTag("whom", message.whom).increment()
这是 Akka 快速入门的完整演示应用程序,其中 Kamon 配置为对消息进行计数:
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, ActorSystem, Behavior}
import kamon.Kamon
import scala.util.Random
object Greeter {
val counterSendMsg = Kamon.counter("counter-send-msg")
def apply(): Behavior[Greet] = Behaviors.receive { (context, message) =>
context.log.info("Hello {}!", message.whom)
//#greeter-send-messages
message.replyTo ! Greeted(message.whom, context.self)
counterSendMsg.withTag("whom", message.whom).increment()
//#greeter-send-messages
Behaviors.same
}
final case class Greet(whom: String, replyTo: ActorRef[Greeted])
final case class Greeted(whom: String, from: ActorRef[Greet])
}
object GreeterBot {
def apply(max: Int): Behavior[Greeter.Greeted] = {
bot(0, max)
}
private def bot(greetingCounter: Int, max: Int): Behavior[Greeter.Greeted] =
Behaviors.receive { (context, message) =>
val n = greetingCounter + 1
context.log.info("Greeting {} for {}", n, message.whom)
if (n == max) {
Behaviors.stopped
} else {
message.from ! Greeter.Greet(message.whom, context.self)
bot(n, max)
}
}
}
object GreeterMain {
def apply(): Behavior[SayHello] =
Behaviors.setup { context =>
//#create-actors
val greeter = context.spawn(Greeter(), "greeter")
//#create-actors
Behaviors.receiveMessage { message =>
//#create-actors
val replyTo = context.spawn(GreeterBot(max = 3), message.name)
//#create-actors
greeter ! Greeter.Greet(message.name, replyTo)
Behaviors.same
}
}
final case class SayHello(name: String)
}
object AkkaQuickstart {
def main(args: Array[String]): Unit = {
run()
}
def run() = {
Kamon.init()
import GreeterMain._
val greeterMain: ActorSystem[GreeterMain.SayHello] = ActorSystem(GreeterMain(), "AkkaQuickStart")
val allPerson = List("Charles", "Bob", "Felipe", "Simone", "Fabio")
def randomPerson = allPerson(Random.nextInt(allPerson.length))
while (true) {
greeterMain ! SayHello(randomPerson)
Thread.sleep(1000)
}
}
}
和我的 Prometheus 网络控制台:
我正在尝试配置基于 Akka 2.6.10 的项目,以将指标值公开给 Prometheus。我看到了这个 build.sbt
文件具有以下配置:
name := """explore-akka"""
version := "1.1"
scalaVersion := "2.12.7"
val akkaVersion = "2.6.10"
lazy val kamonVersion = "2.1.9"
libraryDependencies ++= Seq(
// Akka basics
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion,
// Metrics: Kamon + Prometheus
"io.kamon" %% "kamon-core" % kamonVersion,
"io.kamon" %% "kamon-akka" % kamonVersion,
"io.kamon" %% "kamon-prometheus" % kamonVersion
)
和 plugins.sbt
:
resolvers += Resolver.bintrayRepo("kamon-io", "sbt-plugins")
addSbtPlugin("io.kamon" % "sbt-aspectj-runner" % "1.1.1")
我在 application.conf
上添加了:
kamon.instrumentation.akka.filters {
actors.track {
includes = [ "CounterSystem/user/Counter**" ]
}
}
然后我启动一个调用 counterActor 的 MainClass:
object MainClass extends App {
Kamon.registerModule("akka-test", new PrometheusReporter())
Kamon.init()
CounterActor.run()
}
import akka.actor.{Actor, ActorSystem, Props}
import kamon.Kamon
object CounterActor extends App {
run()
def run() = {
import Counter._
val actorSystem = ActorSystem("CounterSystem")
val countActor = actorSystem.actorOf(Props[Counter], "Counter")
(1 to 100).foreach { v =>
Thread.sleep(1000)
countActor ! Increment
}
(1 to 50).foreach { v =>
Thread.sleep(1000)
countActor ! Decrement
}
countActor ! Print
}
class Counter extends Actor {
import Counter._
val counter = Kamon.counter("my-counter")
var count = 0
override def receive: Receive = {
case Increment =>
count += 1
println(s"incrementing... $count")
counter.withoutTags().increment()
case Decrement =>
count -= 1
println(s"decrementing... $count")
counter.withoutTags().increment()
case Print =>
sender() ! count
println(s"[counter] current count is: $count")
}
}
object Counter {
case object Increment
case object Decrement
case object Print
}
}
我认为在此之后我可以使用 sbt run
启动应用程序并在 Prometheus 控制台上收听指标 (http://127.0.0.1:9090/graph),但我没有看到任何与我的演员相关的指标。我的猜测是我必须在 prometheus 文件 /etc/prometheus/prometheus.yml
中配置 scrape_config
。我对吗?我应该如何配置它?
我必须通过配置文件配置 Prometheus 来抓取 Kamon Web 服务
cat /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "kamon"
scrape_interval: "5s"
static_configs:
- targets: ['localhost:9095']
metrics_path: /
在 build.sbt
添加这 2 个 Kamon 库:
"io.kamon" %% "kamon-bundle" % "2.1.9",
"io.kamon" %% "kamon-prometheus" % "2.1.9",
在 application.conf
添加此配置:
kamon.instrumentation.akka.filters {
actors.track {
includes = [ "AkkaQuickStart/user/*" ]
# excludes = [ "AkkaQuickStart/system/**" ]
}
}
启动 Kamon 并调用计数器:
Kamon.init()
val counterSendMsg = Kamon.counter("counter-send-msg")
counterSendMsg.withTag("whom", message.whom).increment()
这是 Akka 快速入门的完整演示应用程序,其中 Kamon 配置为对消息进行计数:
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, ActorSystem, Behavior}
import kamon.Kamon
import scala.util.Random
object Greeter {
val counterSendMsg = Kamon.counter("counter-send-msg")
def apply(): Behavior[Greet] = Behaviors.receive { (context, message) =>
context.log.info("Hello {}!", message.whom)
//#greeter-send-messages
message.replyTo ! Greeted(message.whom, context.self)
counterSendMsg.withTag("whom", message.whom).increment()
//#greeter-send-messages
Behaviors.same
}
final case class Greet(whom: String, replyTo: ActorRef[Greeted])
final case class Greeted(whom: String, from: ActorRef[Greet])
}
object GreeterBot {
def apply(max: Int): Behavior[Greeter.Greeted] = {
bot(0, max)
}
private def bot(greetingCounter: Int, max: Int): Behavior[Greeter.Greeted] =
Behaviors.receive { (context, message) =>
val n = greetingCounter + 1
context.log.info("Greeting {} for {}", n, message.whom)
if (n == max) {
Behaviors.stopped
} else {
message.from ! Greeter.Greet(message.whom, context.self)
bot(n, max)
}
}
}
object GreeterMain {
def apply(): Behavior[SayHello] =
Behaviors.setup { context =>
//#create-actors
val greeter = context.spawn(Greeter(), "greeter")
//#create-actors
Behaviors.receiveMessage { message =>
//#create-actors
val replyTo = context.spawn(GreeterBot(max = 3), message.name)
//#create-actors
greeter ! Greeter.Greet(message.name, replyTo)
Behaviors.same
}
}
final case class SayHello(name: String)
}
object AkkaQuickstart {
def main(args: Array[String]): Unit = {
run()
}
def run() = {
Kamon.init()
import GreeterMain._
val greeterMain: ActorSystem[GreeterMain.SayHello] = ActorSystem(GreeterMain(), "AkkaQuickStart")
val allPerson = List("Charles", "Bob", "Felipe", "Simone", "Fabio")
def randomPerson = allPerson(Random.nextInt(allPerson.length))
while (true) {
greeterMain ! SayHello(randomPerson)
Thread.sleep(1000)
}
}
}
和我的 Prometheus 网络控制台: