MuninでELBのメトリクスをモニタリングする


こんにちは、t_oookaです。
久々の投稿となりますが、今回は、MuninでELBのメトリクスを
モニタリングしてみようと思います。

環境は以下の通りです。

OS : Amazon Linux AMI 2013.09.2 64-bit
インスタンスタイプ : t1.micro

Muninとは

Muninはサーバのさまざまな情報をグラフ化して表示するソフトです。
名称は、北欧神話に登場する神オーディンに付き添う一対のワタリガラスからとられているようです。

Muninのインストール及び初期設定

まずは、必要なパッケージをインストールします。

# yum -y install munin.noarch munin-node.noarch

WebサーバはApacheを使用するので、追加でインストールしておきます。

# yum -y install httpd.x86_64

Muninを起動

# /etc/init.d/munin-node start
Starting Munin Node: [ OK ]

Apacheも起動します。

# /etc/init.d/httpd start
Starting httpd: [ OK ]

今回は、Basic認証用のユーザを追加します。
※ IDは任意のもので問題ありません。

# cd /etc/munin
# htpasswd -c munin-htpasswd admin
New password:
Re-type new password:
Adding password for user admin

MuninのWeb UIへのアクセスを確認しておきます。

http://(サーバIP)/munin/

munin_overview

ELBのメトリクスを取得するMuninのプラグインを作成

今回作成するプラグインではAWS CLIとjqコマンドを使用するので、
それぞれをインストールしておきます。

AWS CLIのインストール

pythonのバージョンを確認しておきます。
※ 2.6.3以降のバージョンであることを確認しておきます。

# python --version
Python 2.6.9

pipでインストールするので、pipをインストールします。

# easy_install pip

そして、awscliをインストールします。

# pip install awscli

jqコマンドもインストールします。

# yum -y install jq

続いて、Muninのプラグインを作成します。

# vi /usr/share/munin/plugins/aws_elb_
#!/bin/sh

# munin-node-configureでプラグインを管理するための設定
# 今回はひとつのプラグインで複数のメトリクスをモニタリングするため、
# suggestも指定します。

#%# family=auto
#%# capabilities=autoconf suggest

. $MUNIN_LIBDIR/plugins/plugin.sh

# AWS CLIを使用するための設定
export AWS_DEFAULT_REGION=$region
export AWS_ACCESS_KEY_ID=$access_key_id
export AWS_SECRET_ACCESS_KEY=$secret_access_key
export AWS_DEFAULT_OUTPUT=$default_output

# pluginの名称から動的にelbの名称を取得します。
# pluginの名称は「aws_elb_${ELBのメトリクス名}_${ELB名}とします。
elb_name=$(basename $0 | sed "s/$plugin_prefix//")

case "$1" in
# munin-node-configureで管理するための設定
# AWS CLIとjqコマンドが利用可能であることが前提としています。
autoconf)
which aws > /dev/null 2>&1
if [ "$?" -ne 0 ] ; then
echo "no (aws not found.)"
exit 0
fi
which jq > /dev/null 2>&1
if [ "$?" -ne 0 ] ; then
echo "no (jq not found.)"
exit 0
fi
echo "yes"
exit 0
;;
# メトリクスの取得が可能なELB名を動的に取得します。
# ELB名の取得にaws cloudwatch list-metricsコマンドを利用します。
suggest)
elbs=$(aws cloudwatch list-metrics \
--region "$region" \
--namespace "$namespace" \
--metric-name "RequestCount" \
| jq '.Metrics[].Dimensions[] | select(.Name=="LoadBalancerName").Value' \
| tr -d '"' \
| sort \
| uniq \
)

# 作成するプラグイン名(${ELBのメトリクス名}_${ELB名})を動的に生成します。
for metric in $metric_list
do
for elb in $elbs
do
echo "${metric}_${elb}"
done
done
exit 0
;;
# グラフの描画の関する設定を記述します。
config)
echo "graph_title $elb_name $metric_name"
echo 'graph_args -r --lower-limit 0'
echo 'graph_scale no'
echo "graph_vlabel $graph_vlabel"
echo "graph_category $graph_category"
echo "current.label $label"
echo 'current.min 0'
echo "current.draw $draw"
echo "current.type $type"
exit 0
;;
esac

# AWS CLIを利用して、ELBのメトリクス値を取得します。
# 今回は、5分間のメトリクスを取得して最新の値を採用するようにしています。
metric_value=$(aws cloudwatch get-metric-statistics \
--namespace $namespace \
--metric-name $metric_name \
--dimensions Name=LoadBalancerName,Value=$elb_name \
--statistics $statistics \
--start-time $(date --iso-8601=seconds -d '5 minutes ago') \
--end-time $(date --iso-8601=seconds) \
--period $period \
| jq ".Datapoints | sort_by(.Timestamp) | .[(length)-1].$statistics" \
)

# メトリクス値が取得できない場合は、メトリクス値を0とします。
if [ "$metric_value" = "" -o "$metric_value" = "null" ] ; then
echo "current.value 0"
else
echo "current.value $metric_value"
fi

実行権限を付与します。

# chmod +x /usr/share/munin/plugins/aws_elb_

また、プラグイン用の設定ファイルを作成します。

# vi /etc/munin/plugin-conf.d/aws_elb_
[aws_elb_*]
env.plugin_prefix aws_elb_
env.region ap-northeast-1
env.access_key_id XXXXXXXXXX
env.secret_access_key YYYYYYYYYY
env.default_output json

env.namespace AWS/ELB
env.period 60
env.graph_category aws_elb
env.draw LINE2
env.type GAUGE
env.metric_list RequestCount SurgeQueueLength BackendConnectionErrors SpilloverCount

[aws_elb_RequestCount_*]
env.plugin_prefix aws_elb_RequestCount_
env.metric_name RequestCount
env.statistics Sum
env.graph_vlabel Requests
env.label Requests

[aws_elb_SurgeQueueLength_*]
env.plugin_prefix aws_elb_SurgeQueueLength_
env.metric_name SurgeQueueLength
env.statistics Maximum
env.graph_vlabel QueueLength
env.label QueueLength

[aws_elb_BackendConnectionErrors_*]
env.plugin_prefix aws_elb_BackendConnectionErrors_
env.metric_name BackendConnectionErrors
env.statistics Sum
env.graph_vlabel ConnectionErrors
env.label ConnectionErrors

[aws_elb_SpilloverCount_*]
env.plugin_prefix aws_elb_SpilloverCount_
env.metric_name SpilloverCount
env.statistics Sum
env.graph_vlabel Spillover
env.label Spillover

プラグインの動作を確認します。
※ 動作確認用のリンクのため、のちほど削除します。

まず、/etc/munin/pluginsディレクトリへリンクを作成します。

# ln -s /usr/share/munin/plugins/aws_elb_ /etc/munin/plugins/aws_elb_

プラグインの動作確認には、munin-runコマンドを使用します。

「autoconf」の動作確認

#/usr/sbin/munin-run aws_elb_ autoconf
yes

「suggest」の動作確認

# /usr/sbin/munin-run aws_elb_ suggest
RequestCount_aws-elb-web-001
SurgeQueueLength_aws-elb-web-001
BackendConnectionErrors_aws-elb-web-001
SpilloverCount_aws-elb-web-001

問題なさそうなので、動作確認用のリンクを削除します。

# rm -f /etc/munin/plugins/aws_elb_

これで準備ができたので、プラグインを有効化します。

# /usr/sbin/munin-node-configure --shell | /bin/sh

リンクが/etc/munin/pluginsディレクトリへ作成されます。

# ls -l /etc/munin/plugins/aws_elb_*
lrwxrwxrwx 1 root root 33 Mar 14 09:38 /etc/munin/plugins/aws_elb_BackendConnectionErrors_aws-elb-web-001 > /usr/share/munin/plugins/aws_elb_
lrwxrwxrwx 1 root root 33 Mar 14 09:38 /etc/munin/plugins/aws_elb_RequestCount_aws-elb-web-001 > /usr/share/munin/plugins/aws_elb_
lrwxrwxrwx 1 root root 33 Mar 14 09:38 /etc/munin/plugins/aws_elb_SpilloverCount_aws-elb-web-001 > /usr/share/munin/plugins/aws_elb_
lrwxrwxrwx 1 root root 33 Mar 14 09:38 /etc/munin/plugins/aws_elb_SurgeQueueLength_aws-elb-web-001 > /usr/share/munin/plugins/aws_elb_

念のため、動作を確認しておきます。

「config」の動作確認

# /usr/sbin/munin-run aws_elb_RequestCount_aws-elb-web-001 config
graph_title aws-elb-web-001 RequestCount
graph_args -r --lower-limit 0
graph_scale no
graph_vlabel Requests
graph_category aws_elb
current.label Requests
current.min 0
current.draw LINE2
current.type GAUGE

メトリクス値が取得できているかを確認します。

# /usr/sbin/munin-run aws_elb_RequestCount_aws-elb-web-001
current.value 247730

最後に設定を反映するため、munin-nodeを再起動します。

# /etc/init.d/munin-node restart
Stopping Munin Node agents: [ OK ]
Starting Munin Node: [ OK ]

しばらくすると、categoryに「aws_elb_」が追加され、ELBのメトリクスの
グラフが追加されます。

munin_aws_elb-day_request_count

おまけ

Muninのズーミング機能を利用できるようにする

パッケージからインストールすることで基本的にはMuninを利用することが
できるのですが、そのままではズーミング機能が利用できない状態でした。

Apacheのエラーログを確認すると、Permissionの問題のようなので、

# view /var/log/httpd/error_log
munin-cgi-graph: Can't open /var/log/munin/munin-cgi-graph.log (Permission denied) at /usr/share/perl5/vendor_perl/Log/Log4perl/Appender/File.pm line 103., referer:

Permissionを変更するとズーミング機能が利用できるようになります。

# chown munin:apache /var/log/munin
# chmod g+w /var/log/munin

jqコマンドでjsonのフィルタを行う

MuninのプラグインでELBのメトリクスを取得する部分で、jqコマンドを使用して
jsonのフィルタの行っているので、その部分について補足しようと思います。

まずは、jqコマンドによるフィルタの行わない場合の出力を確認しておきます。

$ aws cloudwatch get-metric-statistics \
--region ap-northeast-1 \
--namespace AWS/ELB \
--metric-name RequestCount \
--dimensions Name=LoadBalancerName,Value=aws-elb-web-001 \
--statistics Sum \
--start-time `date --iso-8601=seconds -d '5 minutes ago'` \
--end-time `date --iso-8601=seconds` \
--period 60 \
> requestcount.json
$ cat requestcount.json
{
"Datapoints": [
{
"Timestamp": "2014-03-19T04:52:00Z",
"Sum": 526437.0,
"Unit": "Count"
},
{
"Timestamp": "2014-03-19T04:53:00Z",
"Sum": 512481.0,
"Unit": "Count"
},
{
"Timestamp": "2014-03-19T04:55:00Z",
"Sum": 515601.0,
"Unit": "Count"
},
{
"Timestamp": "2014-03-19T04:56:00Z",
"Sum": 527037.0,
"Unit": "Count"
},
{
"Timestamp": "2014-03-19T04:54:00Z",
"Sum": 546592.0,
"Unit": "Count"
}
],
"Label": "RequestCount"
}

5件のメトリクスが結果として出力されています。

最新のメトリクス値のみ取得したいので、jqコマンドを使用して
以下の順番でフィルタしていきます。

  1. メトリクスのみ取得
  2. メトリクスをTimestampでソート
  3. 最新のメトリクスのみ取得
  4. 最新のメトリクスの値のみ取得

1. メトリクスのみ取得

まず、メトリクスのみ取得したいので、Datapointsのみを出力する
ようにします。

$ cat requestcount.json | jq '.Datapoints'
[
{
"Unit": "Count",
"Sum": 526437,
"Timestamp": "2014-03-19T04:52:00Z"
},
{
"Unit": "Count",
"Sum": 512481,
"Timestamp": "2014-03-19T04:53:00Z"
},
{
"Unit": "Count",
"Sum": 515601,
"Timestamp": "2014-03-19T04:55:00Z"
},
{
"Unit": "Count",
"Sum": 527037,
"Timestamp": "2014-03-19T04:56:00Z"
},
{
"Unit": "Count",
"Sum": 546592,
"Timestamp": "2014-03-19T04:54:00Z"
}
]

2. メトリクスをTimestampでソート

ソートを行う場合はsort_by関数を使用します。

$ cat requestcount.json | jq '.Datapoints | sort_by(.Timestamp)'
[
{
"Unit": "Count",
"Sum": 526437,
"Timestamp": "2014-03-19T04:52:00Z"
},
{
"Unit": "Count",
"Sum": 512481,
"Timestamp": "2014-03-19T04:53:00Z"
},
{
"Unit": "Count",
"Sum": 546592,
"Timestamp": "2014-03-19T04:54:00Z"
},
{
"Unit": "Count",
"Sum": 515601,
"Timestamp": "2014-03-19T04:55:00Z"
},
{
"Unit": "Count",
"Sum": 527037,
"Timestamp": "2014-03-19T04:56:00Z"
}
]

3. 最新のメトリクスのみ取得

配列の要素数は、length関数で取得できます。
最新のメトリクスは配列の末尾に存在するので、「要素数 – 1」を
指定して取得します。

$ cat requestcount.json | jq '.Datapoints | sort_by(.Timestamp) | .[(length)-1]'
{
"Unit": "Count",
"Sum": 527037,
"Timestamp": "2014-03-19T04:56:00Z"
}

4. 最新のメトリクスの値のみを取得

“Sum”を指定して、最新のメトリクス値のみを取得します。

$ cat requestcount.json | jq '.Datapoints | sort_by(.Timestamp) | .[(length)-1].Sum'
527037

参照

Munin
Munin
Docs about Plugins
Installation on various flavours of Linux
AWS CLI
What Is the AWS Command Line Interface? – AWS Command Line Interface
AWS CLI 1.3.1 documentation
jq
jq Manual
軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*