##はじめに
システムの運用を担っているとそれなりに障害が発生し、何らかの対応が必要になります。とりあえず再発してもすぐに気づけるように…と監視で検知させるのが最初の一歩ですが、ツール標準の機能では検知させることが困難…というのもよくある話です。
とりあえず正常動作の判定はコマンドラインから叩けば出来るけど、アラート通知させるにはどうしよう?というところで、その昔は実行結果をログに出力してログ監視で拾ったりしていました。これでも実用には足りますが本来不要なログを経由して結果を取り出しているので、グラフ化が困難だったりログのローテート管理が必要になったり、想定外の結果が返った時は通知が抜けたりと強引な手法なのは否めません。
Datadogだとこのあたり簡単でわりとスマートに出来ますよというのがこの記事の主旨です。
##カスタムメトリクスって何?
Datadogのカスタムメトリクスは上で挙げたような「ツール標準の機能では取得できない項目」をデータとして活用するための機能です。
公式のドキュメントを追っていくと「カスタムメトリクスの送信」として以下4つの方法が記載されています。
- カスタムagentチェック
- DogStatD
- PowerShell
- DatadogのHTTP API
このうち上から3つは多少なりともコードが書けること(主にpythonとか)が要求されます。自分も含めてインフラエンジニアは「コードはわからんけどシェルスクリプトなら書けるよ」という人が多いのでは?と思いますが、この属性の人でも簡単に使えるのが4番目の「HTTP API」です。おおざっぱに言えば「正常動作判定の処理をシェルスクリプトで作ったら、curlコマンドで結果をDatadogに送ることができる」という仕組みです。
実装方法
公式ドキュメントの"Submit metrics"のコード例(curl)の項目を参照して…と一言で済ませたいところですが、微妙に分かりづらい感じなので自分が使っている(動いている)コードを載せて解説します(変数名やコマンド内容は修正しています)
目的としては「tomcat(java)プロセス内の特定スレッドが動作しているか定期的に監視し、落ちたらアラートを上げたい」というものです。基本はjpsコマンドでの出力結果をあれこれ加工して、最終的にwcコマンドに渡して数値化しています。
#!/bin/sh
# setting
API_KEY=hogehogehogehoge
currenttime=$(date +%s)
WORKDIR=/home/ec2-user
GROUP=`echo $HOSTNAME | cut -b 1-9`
NAME=`echo $HOSTNAME | cut -b 1-21`
# main
check-java-thread=`sudo jps | grep hogehoge | wc -l `
# post
curl -s -X POST -H "Content-type: application/json" \
-d "{ \"series\" :
[{\"metric\":\"check.java-thread\",
\"points\":[[$currenttime, $check-java-thread]],
\"type\":\"gauge\",
\"host\":\"$HOSTNAME\",
\"tags\":[\"autoscaling_group:$GROUP\", \"name:$NAME\"]}
]
}" \
"https://app.datadoghq.com/api/v1/series?api_key=$API_KEY"
setting(変数定義)
- API_KEY:DatadogのGUIから"Integration"→"API"で表示されるAPI Keyを設定
- currenttime:Datadogにメトリクスを送る時「何時のデータか」を指定するために、コマンド実行時間を取得
- GROUP:自分の運用するシステムではサーバ名に環境名を持っているので、hostnameコマンドで取り出す
- NAME:同上
main(サーバ上で実行される確認コマンド)
- コマンドラインでの確認方法をそのまま変数に格納
post(datadogにデータを送る、ここが一番重要)
- curlコマンド:POSTメソッドの使用とjson型の宣言
- series:このフィールド名で以下のメトリクスデータを定義
- metric:Datadog上で管理する時のメトリクス名
- points:送信するメトリクスの取得時間、データ本体(コマンドの実行結果が反映される)
- host:メトリクスに紐付けるホスト名
- type:メトリクスのデータ型を指定、string(文字列)/count(カウント数)/gauge(数字)/rate(パーセント)
- tags:メトリクスに紐づけるタグ
- interval:取得間隔、typeがcountかrateの場合は必要(この例では省略)
この書式でスクリプトを書いて、cronなどで任意のインターバルで実行するだけでDatadog上にカスタムメトリクスとして取得することが出来ます。この例の場合はJavaVMに特定スレッドが存在すれば=1、存在しない(落ちた)ときは=0なので、グラフで推移を見る事が出来て0の時はアラート通知させることが出来ます。
クラウド環境だとホスト名は可変する例が多いので、アラート通知の要/不要はモニター設定側でタグを使って制御するのが良いと思います(検証環境では通知不要とか)何らかの異常で結果がnullの時を想定するのであれば、アラート設定の"if data is missing"の設定などで対応できそうです。
メリットとデメリット
メリット
- シェルスクリプトで動かすことができればたぶんなんでもいける
- データ形式が4パターンあるので、およそ何らかの実行結果であればこの中で納まるはず
デメリット
- 「cronで回す」というところは変わらないので、cronが死んだら監視も止まる
- シビアな運用であればシェルスクリプトの設計センスもそれなりに必要
最後に
今のところ自分の環境ではこれで問題なく動いていますが、Datadogは色々と進化が早いのでそのうちアップデートが必要になるかもしれません…