こんにちは。qudoを打倒している者です。
以前上記の記事を書いたんですが、最近fireworqをサービスインしていくつかのqudoジョブをリプレイスしました。
動作は問題ないんですが、滞留してるジョブの数など、各種メトリクスがとれていない状態なので、今回はそれらのメトリクスをモニタリングする方法を考えます。
mackerelを利用する
mackerelをモニタリングツールとして利用している場合、fireworq公式のmackerel-agent-pluginが存在するため、それを利用するだけで済みます。(fireworqははてな社が開発しているOSSです)
cloudwatch + telegrafを利用する
cloudwatchにメトリクスを保管する場合を考えます。
弊社はお金ないのでこちらです。
メトリクスの収集パート
メトリクスの収集にはtelegrafを利用します。
telegrafはinfxludb社がOSSとして開発しているメトリクス収集用のエージェントです。
telegrafはプラグイン方式をとっており、様々なミドルウェアに対応したプラグインが存在します。
fireworq対応のプラグインは存在しないのですが、コマンド実行結果を入力として取り込むプラグイン「Exec」がありますので、こちらを利用してメトリクスを取り込みます。
The Exec input plugin parses supported Telegraf input data formats (line protocol, JSON, Graphite, Value, Nagios, Collectd, and Dropwizard) into metrics
Execインプットプラグインでは、データフォーマットとして複数種のフォーマットに対応しているようです。ここではシンプルにJSONで取り込むことにします。
fireworqのメトリクス取得エンドポイントについて
fireworqにはGETリクエストでメトリクスを取得できるエンドポイントが用意されています。
たとえば、
- /queues/stats
を叩くと、以下のように各キューのメトリクスがJSON形式で返却されます
curl ドメイン/queues/stats | jq .
{
"default": {
"total_pushes": 0,
"total_pops": 0,
"total_successes": 0,
"total_failures": 0,
"total_permanent_failures": 0,
"total_completes": 0,
"total_elapsed": 0,
"pushes_per_second": 0,
"pops_per_second": 0,
"outstanding_jobs": 0,
"total_workers": 20,
"idle_workers": 20,
"active_nodes": 1
}
}
この例ですと、「default」がキュー名に相当します。
あとはゴニョゴニョ加工するなりして、Execインプットプラグインに入力すればよさそうです。
mackerel-plugin-fireworqを流用できそう
上述のエンドポイントを自分で叩いてもいいんですが、mackerel-plugin-fireworqを流用する方法を考えます。
というのも、mackerel-plugin-fireworqは上述のメトリクスをいい感じに集約してmackerelに出力しているためです。
どういう風にデータを集約するかなど、なるべく自分で考えたくありません!!(怠惰
で、具体的にどう流用するかですが、mackerelのプラグインは単体実行できるコマンドとして提供されているため、mackerel-plugin-fireworqの実行結果をtelegrafのExecインプットプラグインに入力すればいいことになります。
しかし、mackerelプラグインは
項目名\t値\tタイムスタンプ
という複数行のTSVの形式でメトリクスを標準出力に出すため、そのままではExecインプットプラグインには取り込めません。
mackerel-plugin-fireworqの場合、以下のような出力になります。
fireworq.jobs.elapsed.jobs_average_elapsed_time 0 1620055407
fireworq.node.active_nodes 1 1620055407
fireworq.node.active_nodes_percentage 100 1620055407
fireworq.queue.workers.queue_idle_workers 20 1620055407
fireworq.queue.workers.queue_running_workers 0 1620055407
fireworq.queue.buffer.queue_outstanding_jobs 0 1620055407
fireworq.jobs.jobs_failure 0 1620055407
fireworq.jobs.jobs_success 0 1620055407
fireworq.jobs.jobs_outstanding 0 1620055407
fireworq.jobs.jobs_waiting 0 1620055407
fireworq.jobs.events.jobs_events_pushed 0 1620055407
fireworq.jobs.events.jobs_events_popped 0 1620055407
fireworq.jobs.events.jobs_events_failed 0 1620055407
fireworq.jobs.events.jobs_events_succeeded 0 1620055407
fireworq.jobs.events.jobs_events_completed 0 1620055407
上記のデータをJSONに加工できればよさそうです。
そこでgolangでちょっとしたCLIをしたためました。
canning(缶詰)をもじってkanningと命名しました。
mackerelがサバなので、それを加工するイメージです。(サバ缶的な
kanningはmackerel-agent-pluginの出力を標準入力からくわせると、JSONに整形して出力します。
たとえば、上記のmackerel-plugin-fireworqの出力を入力すると、
cat _test/fireworq_metrics.tsv | kanning | jq .
以下のようになります。
{
"jobs": {
"elapsed": {
"jobs_average_elapsed_time": 0
},
"events": {
"jobs_events_completed": 0,
"jobs_events_failed": 0,
"jobs_events_popped": 0,
"jobs_events_pushed": 0,
"jobs_events_succeeded": 0
},
"jobs_failure": 0,
"jobs_outstanding": 0,
"jobs_success": 0,
"jobs_waiting": 0
},
"node": {
"active_nodes": 1,
"active_nodes_percentage": 100
},
"queue": {
"buffer": {
"queue_outstanding_jobs": 0
},
"workers": {
"queue_idle_workers": 20,
"queue_running_workers": 0
}
}
}
現在、rootのfireworqとタイムスタンプは出力から落としています。
(kanningはテストまだ書いてないので、利用しないでください。しないと思いますが)
最終的なtelegrafのinput設定
mackerel-plugin-fireworqとkanningを組み合わせると、Execインプットプラグインの設定は以下のようになります。
[[inputs.exec]]
## Commands array
commands = [
"/tmp/fireworq.sh"
]
## Timeout for each command to complete.
timeout = "5s"
## measurement name suffix (for separating different commands)
name_suffix = "_mycollector"
## Data format to consume.
## Each data format has its own unique set of configuration options, read
## more about them here:
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
data_format = "json"
#!/bin/sh
mackerel-plugin-fireworq | kanning
メトリクスの入力パート(cloudwatchへの出力)
cloudwatchへの出力用プラグインが存在しますので、そちらを利用しましょう。
余談
cloudwatch-agentはtelegrafのforkのようです。
go.modでreplaceをかけてる
telegrafのExecインプットプラグインのようなものがあるかと期待したのですが、独自にメトリクスを取り込むような機能はオミットされているようなので、今回は利用を見送りました。
最後に
メトリクスコレクターって何を使うのがいいんでしょうか?
mackerelやdatadogを利用している場合、それぞれで提供されているエージェントを利用すればいいと思うのですが、cloudwatchを利用している場合、選択に悩みます。
今回は入力、出力に対応するプラグインが存在するということでtelegrafを利用しましたが、他に選択肢があればコメント欄でご教示いただけますと幸いです。