タダです.
Mackerel のプラグインには様々なものが既に用意されていますが,そのプラグインにないものがあれば作ってみようということで,FastAPI を動かすために必要な Uvicorn のプロセスを監視するプラグインを作ってみたのでこの記事でその模様をまとめます.
プラグインの種類
プラグインには2つの種類があり,メトリックプラグインとチェックプラグインがあります.前者はサーバーリソースの値をメトリック値を取得,送信するためのもので CPU やメモリなどが標準のサーバーのメトリックとしてありますが,標準のメトリック以外のものはカスタムメトリックとしてグラフに描画されます.後者はホスト上の特定プロセスの死活状況をチェックしたりするときに使い,メトリックプラグインのようにグラフの描画はないです.
メトリックプラグインとチェックプラグインを作る
それではメトリックプラグインとチェックプラグインを作っていきます.
メトリックプラグインを作る
Uvicorn のプロセスは uvicorn main:app --reload
のように実行しても1プロセスしかあがらないようで,ドキュメント にも本番環境では gunicorn と一緒に使うことが推奨されているため下記のようなコマンドを実行したとします.
gunicorn example:app -w [ワーカー数] -k uvicorn.workers.UvicornWorker
メトリックプラグインのコードとして次のものを用意しました.メトリックプラグインのインターフェース仕様で {metric name}\t{metric value}\t{epoch seconds}
というフォーマットで標準出力されることが求められているためスクリプトの最終行で echo -e "${metric_name}\t${metric}\t${date}"
を行っている以外は大したことしてないかと思います.スクリプトの実行権限を chmod +x uvicorn-metrics.sh
を与えることも忘れずにやりましょう.
uvicorn-metrics.s
#!/bin/sh metric_name="uvicorn.test_metric.number" metric=`ps aux |grep uvicorn | grep -v grep | wc -l` date=`date +%s` echo -e "${metric_name}\t${metric}\t${date}"
そして,/etc/mackerel-agent/mackerel-agent.conf
にも下記の定義を追加して sudo systemctl restart mackerel-agent
で再起動します.
[plugin.metrics.uvicorn]
command = "/xxx/xxx/uvicorn-metrics.sh"
数分待つと,メトリックのデータが送られてきてるのを確認できました.Uvicorn の8つのプロセスが記録されていることが確認できました.
チェックプラグインを作る
次にチェックプラグインをつくっていきますが,メトリックプラグイン同様にスクリプトとして次のようなものを用意しました.正常なプロセスの数はメトリックプラグインの記録された値として8を入れてその時は正常ですが,それ以外の値になったら Critical になるように設定しています(チェックプラグインの仕様はドキュメント に記載があります).スクリプトの実行権限を chmod +xuvicorn-ps-check.sh
で与えます.
uvicorn-ps-check.sh
#!/bin/sh count=`ps aux |grep uvicorn | grep -v grep | wc -l` if [ $count -eq 8(正常なプロセスの数) ]; then exit 0 else exit 2 fi
そして,/etc/mackerel-agent/mackerel-agent.conf
にも下記の定義を追加して sudo systemctl restart mackerel-agent
で再起動します.
[plugin.checks.uvicorn]
command = "/xxx/xxx/uvicorn-ps-check.sh"
数分待つと,Monitors のセクションに uvicorn が監視されていることを確認できました.
試しにプロセスを落としてアラートが出るかを確認してみます.
$ gunicorn main:app -w 8 -k uvicorn.workers.UvicornWorker ~中略~ [2021-06-29 22:20:44 +0000] [22251] [INFO] Waiting for application startup. [2021-06-29 22:20:44 +0000] [22251] [INFO] Application startup complete. ^C[2021-06-29 22:47:40 +0000] [22246] [INFO] Handling signal: int ~中略~ [2021-06-29 22:47:40 +0000] [22246] [INFO] Shutting down: Master
Critical 扱いでアラートが出ることが確認できました.プロセスが落ちてもその状況をモニタリングできるようになりました.
まとめ
今回の開発で a-know (id:a-know)さんの記事を参考に Uvicorn のプロセス監視のプラグインを作っていきました.a-know さんありがとうございます! Go でも作っていきたいけどまずはさくっとシェルスクリプト でプラグインを作れる体験を持てたのはとても大きかったです.こっからプラグイン開発に入り込んで行けたらなと思います.