DataDog 用の jolokia AgentCheck書いてみた
記事名のとおりなんですが、AgentCheck用のインストール方法とか特に無くてファイルを置くだけっぽいので、 gist にあげておきます。コードが酷かったり、項目増やせなかったりするのは今後の課題。
モチベーションとか
そもそもの話、JVMの監視をするときには極々単純に以下の項目を監視したいわけです。
また、メモリの状態と言ってもJVMって Heap/NonHeap みたいな単純なものではありません。EdenとかSurvivorとかOldとかがあります。 (※G1GCではちょっと違う)
GCも、 Java8 のデフォルトでは ParallelGC Java9ではG1GCだったりで、見なければいけない項目も少しずつ違います。
JVMのメモリについては、詳しくはこちらの方のブログが分かりやすかったので、是非参照してください。
それなのに、監視サービスの某鯖とか某犬とかのJVM監視の項目を見ると、全然足りないんですよ。
鯖の方は、jstatで監視するなら十二分に満たしているんですが。
mackerel-agent-plugins/mackerel-plugin-jvm at master · mackerelio/mackerel-agent-plugins · GitHub
Jolokia(JMX)で監視する際には、鯖の方も項目を増やすプラグインを書いてみたりとかしています。
本題に戻って、DataDogのJmx監視のためのプロセスなんですが、JolokiaではなくてJmxFetchといって、JMX取得のためのJavaプロセスを内部で動かす方式となっています。
これが、dd-agentをDockerで動かして、AutoDiscoverを前提にすると Xmx512M
固定で起動します。公式のDockerのメモリ推奨量が256MBなのに。
https://github.com/DataDog/dd-agent/blob/5cad70dd33b58716ed102070c95edbd557bf3816/jmxfetch.py#L48
_JVM_DEFAULT_SD_MAX_MEMORY_ALLOCATION = " -Xmx512m"
コード見つつ動かしながら挙動調べた感じ、AutoDiscoverじゃなくて監視用のファイルを置いた場合にはプロセスのメモリ使用量を変更できそうでしたが、それだとAWSのECSとかでなんのタスクが動くかわからないものに対しては使えそうにありません。
そもそも、監視のプロセスだけで512MBも必要とか尋常じゃないです。AWSのECS上のTaskとして動かした場合、t2.small なんて1GBしかないんだから、残りの使えるメモリがもう半分以下しかないです。
サポートとかに聞いてもAutoDiscoverとかDocker上のdd-agentとかあんまり考慮されていなさそうだったのと、Docker起動時に外部の環境変数から変更できそうな感じじゃなかったので、Jolokiaで監視すればいいんじゃないかなと思い立った次第。
で、探したけどJolokiaようのAgentCheckスクリプトが見つからなかったので作ったのが冒頭のスクリプトになります。
使い方とか
dd-agentをDockerで動かしているので、Dockerfile置いておきます。
サーバー上で普通に動かしているのであれば、 check.d
ディレクトリにファイルを置くだけでいいはずです。
FROM datadog/docker-dd-agent:latest ADD jolokia.py /opt/datadog-agent/agent/checks.d/jolokia.py
buildして、
docker build -t dd-agent-jolokia .
dd-agentを起動(MacOSの場合。cgroupを通して監視するので、詳細は以下のリンクを参照)
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /proc:/host/proc:ro \ -v /sys/fs/cgroup:/host/sys/fs/cgroup:ro \ -e API_KEY=<API_KEY> \ -e SD_BACKEND=docker \ -e DD_LOGS_STDOUT=yes \ dd-agent-jolokia
https://hub.docker.com/r/datadog/docker-dd-agent/
監視対象のDockerはラベルを付けて起動 JavaagentでJolokiaを指定してポートを開けるようにすること。
docker run -d \ -p 13333 \ -l com.datadoghq.ad.check_names='["jolokia"]' \ -l com.datadoghq.ad.init_configs='[{}]' \ -l com.datadoghq.ad.instances='[{"host": "%%host%%", "port": "%%port%%" }]' \ jvm_application -javaagent /paht/to/jolokia-jvm-agent.jar,port=13333,host=0.0.0.0
起動したDockerContainerの監視はLabelをつければ自動で監視対象に追加してくれる仕組み。このあたり、DataDogの仕組みは素晴らしいですね。
https://docs.datadoghq.com/guides/autodiscovery/docs.datadoghq.com
ParallelGCの場合、監視項目はこれだけ増えます。 MemoryPoolから動的に項目取得してくるので、GCの種別を変えれば項目も変わります。
jolokia.class_load.loaded jolokia.class_load.total jolokia.class_load.unloaded jolokia.gc.count jolokia.gc.time jolokia.memory.code_cache.committed jolokia.memory.code_cache.init jolokia.memory.code_cache.max jolokia.memory.code_cache.used jolokia.memory.compressed_class_space.committed jolokia.memory.compressed_class_space.init jolokia.memory.compressed_class_space.max jolokia.memory.compressed_class_space.used jolokia.memory.heap.committed jolokia.memory.heap.init jolokia.memory.heap.max jolokia.memory.heap.used jolokia.memory.metaspace.committed jolokia.memory.metaspace.init jolokia.memory.metaspace.max jolokia.memory.metaspace.used jolokia.memory.non_heap.committed jolokia.memory.non_heap.init jolokia.memory.non_heap.max jolokia.memory.non_heap.used jolokia.memory.ps_eden_space.committed jolokia.memory.ps_eden_space.init jolokia.memory.ps_eden_space.max jolokia.memory.ps_eden_space.used jolokia.memory.ps_old_gen.committed jolokia.memory.ps_old_gen.init jolokia.memory.ps_old_gen.max jolokia.memory.ps_old_gen.used jolokia.memory.ps_survivor_space.committed jolokia.memory.ps_survivor_space.init jolokia.memory.ps_survivor_space.max jolokia.memory.ps_survivor_space.used jolokia.thread.count
雑感
勢い余って書いてしまったけど、本当に他に困っている人いないのかどうか・・・ みんなそこまでJVM内の項目気にしていないのかなぁ。 あと、いくらなんでも雑に書きすぎたかもしれない。