F@N Ad-Tech Blog

株式会社ファンコミュニケーションズ nend・nex8・viidleのエンジニア・技術ブログ

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

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

環境は以下の通りです。

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

Muninとは

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

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

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

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

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

yum -y install httpd.x86_64

[/bash] Muninを起動 [bash]

/etc/init.d/munin-node start

Starting Munin Node: [ OK ] [/bash]

Apacheも起動します。 [bash]

/etc/init.d/httpd start

Starting httpd: [ OK ] [/bash] 今回は、Basic認証用のユーザを追加します。 ※ IDは任意のもので問題ありません。 [bash]

cd /etc/munin

htpasswd -c munin-htpasswd admin

New password: Re-type new password: Adding password for user admin [/bash] MuninのWeb UIへのアクセスを確認しておきます。

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

munin_overview

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

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

AWS CLIのインストール

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

python --version

Python 2.6.9 [/bash] pipでインストールするので、pipをインストールします。 [bash]

easy_install pip

[/bash] そして、awscliをインストールします。 [bash]

pip install awscli

[/bash] jqコマンドもインストールします。 [bash]

yum -y install jq

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

vi /usr/share/munin/plugins/aws_elb_

[/bash] [shell]

!/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 [/shell]

実行権限を付与します。

[bash]

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

[/bash]

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

vi /etc/munin/plugin-conf.d/aws_elb_

[/bash]

[shell] [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 [/shell]

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

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

ln -s /usr/share/munin/plugins/aws_elb /etc/munin/plugins/aws_elb

[/bash]

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

「autoconf」の動作確認

[bash]

/usr/sbin/munin-run aws_elb_ autoconf

yes [/bash]

「suggest」の動作確認

[bash]

/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 [/bash]

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

[bash]

rm -f /etc/munin/plugins/aws_elb_

[/bash]

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

[bash]

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

[/bash]

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

[bash]

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 [/bash]

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

「config」の動作確認 [bash]

/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 [/bash]

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

/usr/sbin/munin-run aws_elb_RequestCount_aws-elb-web-001

current.value 247730 [/bash]

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

[bash]

/etc/init.d/munin-node restart

Stopping Munin Node agents: [ OK ] Starting Munin Node: [ OK ] [/bash]

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

munin_aws_elb-day_request_count

おまけ

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

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

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

view /var/log/httpd/error_log

[/bash]

[shell] 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: [/shell]

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

[bash]

chown munin:apache /var/log/munin

chmod g+w /var/log/munin

[/bash]

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

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

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

[bash] $ 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 [/bash]

[bash] $ 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" } [/bash]

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

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

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

1. メトリクスのみ取得

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

[bash] $ 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" } ] [/bash]

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

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

[bash] $ 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" } ] [/bash]

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

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

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

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

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

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

参照

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