Mackerel Advent Calendar 2018 の2日目の記事っす。よろしくお願いいたします。
Kamon は、JVM上で動作するアプリケーションの監視ツールキットです。
特定のベンダーに決められることなく、Metricsや、Tracing、Context Propagation APIs を提供してくれるツールキットです。
公式では、 StatsD, Prometheus, Kamino, Datadog, Zipkin, Jaeger などをサポートしておりますが、Mackerelがそこにありませんでしたので、ちょっと作ってみるかってことで、作りましたので、ご紹介させていただきます。
yoshiyoshifujii/kamon-mackerel
How to use
JVMで動くアプリケーションといっておりますが、基本、Scalaで書いたコードをJVMで実行するのを想定してlibraryを作っておりますので、ここでは、Scalaでどうやって組んでいけばメトリクスをMackerelで確認できるのか、手順を記載していきます。
sbt new
まずは、サンプルとして、プロジェクトを作成します。
今回は、簡単なWeb APIの雛形として、 akka/akka-http-quickstart-scala.g8 を作って、組んでみたいと思います。
なお、事前に、sbt、JVMがインストールされている前提となります。
私の環境では、
- AdoptOpenJDK v1.8.0_192
- sbt 1.2.6
がインストールされています。
それでは、以下のコマンドを実行します。
$ sbt new akka/akka-http-quickstart-scala.g8
すると、以下のようにだーっと出力されて、
Getting org.scala-sbt sbt 1.2.6 (this may take some time)...
downloading file:////Users/yoshiyoshifujii/.sbt/preloaded/org.scala-sbt/sbt/1.2.6/jars/sbt.jar ...
[SUCCESSFUL ] org.scala-sbt#sbt;1.2.6!sbt.jar (11ms)
...
で、以下の入力待ち状態になりますので、それぞれ、適切に入力したりEnterします。
This is a seed project which creates a basic build for an Akka HTTP
application using Scala.
name [My Akka HTTP Project]: example-akka-http
scala_version [2.12.7]:
akka_http_version [10.1.5]:
akka_version [2.5.18]:
organization [com.example]:
package [com.example]:
すると、直下に、 example-akka-http
というディレクトリが出来ていますので、これでベースとなるプロジェクトができます。
IntelliJ IDEAで開く
作ったプロジェクトをIDEAで開きます。
Import Project
をクリックして、
sbtを選んで、Nextを押します。
JDKは、1.8とか適切なのを選んで、Finishしますと、プロジェクトが開きます。
最初は、IntelliJ IDEAが色々と依存関係を成立させるためにダウンロードだなんだと時間がかかりますが、それを待ちます。
kamon-mackerelを依存関係に追加する
IntelliJ IDEAの初回ロードが終わりましたら、次に、build.sbtを開いて、kamon-mackerelを依存関係に追加します。
IDEAで、build.sbtを開きます。
lazy val akkaHttpVersion = "10.1.5"
lazy val akkaVersion = "2.5.18"
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.example",
scalaVersion := "2.12.7"
)),
name := "example-akka-http",
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-xml" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,
"com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,
"org.scalatest" %% "scalatest" % "3.0.5" % Test
)
)
このあたりに加えましょう。
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-xml" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"io.kamon" %% "kamon-core" % "1.1.0", // <= ここ!!
"io.kamon" %% "kamon-akka-http-2.5" % "1.0.1", // <= ここ!!
"com.github.yoshiyoshifujii" %% "kamon-mackerel" % "0.1.0", // <= ここ!!
"com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,
"com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,
"org.scalatest" %% "scalatest" % "3.0.5" % Test
)
すると、 Import Changes
って出てきますので、それを押します。
sbt-aspectj-runnerをpluginに追加
https://github.com/kamon-io/sbt-aspectj-runner のREADMEを参照し、 project/plugins.sbt
に以下を追記する。
resolvers += Resolver.bintrayRepo("kamon-io", "sbt-plugins")
addSbtPlugin("io.kamon" % "sbt-aspectj-runner" % "1.1.0")
KamonにReporterを追加
Mainとなる com.example.QuickstartServer
を開きます。
以下のようにimport文を追記して、Reporterを追加します。
...
import kamon.Kamon
import kamon.mackerel.MackerelAPIReporter
//#main-class
object QuickstartServer extends App with UserRoutes {
Kamon.addReporter(new MackerelAPIReporter())
...
さらに、 application.conf
を src/main/resources
直下に作成します。
kamon {
mackerel {
#
# Settings relevant to the MackerelAPIReporter
#
http {
# Mackerel API key to use to send metrics to mackerel directly over HTTPS.
api-key = ""
}
host {
id = ""
}
}
}
上記のように、api-keyとhostのidをconfigに設定しておく必要がありますので、Mackerelを開いて、それぞれ取得してきます。
Mackerelから設定値を取得
Mackerelを開いて、api-keyを取得します。
Hostを登録
Mackerelでは、エージェントをインストールすることでHostを登録するかと思いますが、今回は、APIを使ってHostを登録したいと思います。
ドキュメントは、こちら。 https://mackerel.io/ja/api-docs/entry/hosts#create
以下のcurlコマンドを実行します。
$ curl -i -X POST https://api.mackerelio.com/api/v0/hosts \
-H X-Api-Key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
-H Content-Type:application/json \
-d '{"name":"host_name_1","meta":{}}'
すると、 200 OK
で返ってきたら登録OKです。
HTTP/1.1 200 OK
...
{"id":"YYYYYYYYYYY"}%
この表示されているIDが、HostIDですので、こちらも使います。
これで、 api-key
と、 host-id
を取得できました。
Akka HTTPを起動
sbtを起動して、 run
を実行します。
$ cd example-akka-http/
$ sbt run
...
[info] Running com.example.QuickstartServer
23:37:29.340 [kamon.mackerel.MackerelAPIReporter] INFO kamon.mackerel.MackerelAPIReporter - Started the Mackerel API reporter.
Server online at http://127.0.0.1:8080/
以下のcurlを実行すると、いろいろとアクセスできます。
$ curl -i -X GET http://localhost:8080/users [~]
HTTP/1.1 200 OK
X-B3-TraceId: db805a66b23110ec
X-B3-Sampled: 0
X-B3-SpanId: 5388c20a0e8292b3
Server: akka-http/10.1.5
Date: Thu, 22 Nov 2018 14:42:14 GMT
Content-Type: application/json
Content-Length: 12
{"users":[]}%
$ curl -i -X POST http://localhost:8080/users -H Content-Type:application/json -d '{"name":"hoge","age":10,"countryOfResidence":"ooo"}' [~]
HTTP/1.1 201 Created
X-B3-TraceId: 4eb323d6196145e8
X-B3-Sampled: 0
X-B3-SpanId: dbfc829b7f2499b0
Server: akka-http/10.1.5
Date: Thu, 22 Nov 2018 14:45:45 GMT
Content-Type: application/json
Content-Length: 36
{"description":"User hoge created."}%
MackerelでMetricsを確認
Mackerelを開いて、HostのMetricsを確認してみます。
うん。なんか出てます。
まとめ
各メトリクスの内容については、Actorの数とかが可視化されたりしてます。
他にも、JVMを可視化する kamon-jmx を入れたりすることも可能ですので、色々とKamonのMetrics収集を組み込んだうえで、Mackerelで可視化するライフが送れると思います。
当記事を作成するにあたり作ったサンプルのコードは、 https://github.com/yoshiyoshifujii/example-akka-http です。
以上です。