muninで指定したディレクトリのサイズを監視する(キャッシュ対応)

先日作ったプラグインだとどうも深夜だけタイムアウトしてしまって値の取得に失敗してしまうので*1、cronで定期的に値をファイルに保存するようにして、munin-nodeでは保存された値を読み込んで返すだけで済むように修正した。

ソース: du - munin plugin

#!/bin/sh
#
# Disk Usage (per directory)
# version 1.1
#
# sample conf
# [du]
# user root
# env.dirs /var/log:/var/www
# #env.cache /tmp/munin-plugin-du
#
# crontab to use cache
# 2 * * * * rm /tmp/munin-plugin-du && /usr/sbin/munin-run du
#
#%# family=auto
#%# capabilities=autoconf

du=${du:-`which du`}
dirs=${dirs:-/home}":"
cache=${cache:-/tmp/munin-plugin-du}

if [ "$1" = "autoconf" ]; then
        if [ -x $du ]; then
                echo "yes"
                exit 0
        else
                echo "no (command 'du' not found)"
                exit 1
        fi
fi

if [ "$1" = "config" ]; then

        echo 'graph_title Disk usage '
        echo 'graph_args --upper-limit 1000 -l 0'
        echo 'graph_vlabel size (byte)'
        echo 'graph_category disk'
        echo 'graph_info This graph shows size of designated directories.'

        stack=0
        while [ $dirs  ]
        do
                dir=${dirs%%:*}
                dirs=${dirs#*:}

                basename=`basename $dir`
                echo "$basename.label $dir"
                if [ $stack -eq 0 ]; then
                        echo "$basename.draw AREA"
                        stack=1
                else
                        echo "$basename.draw STACK"
                fi
                
        done
        exit 0
fi

# Delete cache if two hours (120 minutes) have passed since its last modification.
find `dirname $cache` -name `basename $cache` -mmin +120 | while read file
do
        rm $file
done

if [ -e $cache ]; then
# Use cache if it exists.
        cat $cache
else
# Excecute du and create a cache file if it does not exist.
        while [ $dirs  ]
        do  
                dir=${dirs%%:*}
                dirs=${dirs#*:}
                basename=`basename $dir`
                
                size=`$du -sb $dir | cut -f 1`
                echo "$basename.value $size"
                echo "$basename.value $size" >> $cache
        done
fi

exit 0

キャッシュ周りの動作の簡単な説明

2時間以内に作成されたキャッシュファイルがあればそれを読み込んでそのまま出力する。

キャッシュファイルがない場合は、新たにキャッシュファイルを作成しつつ出力する。
キャッシュファイルが作成されてから2時間以上経っている場合も新たにキャッシュファイルを生成するので、タイムアウトの心配がなくて、かつ小刻みのデータが必要ない場合は後述するcronの設定は不要である。

設定ファイル(plungin-conf.d/du)の例

[du]
user root
env.dirs /var/log:/var/www
env.cache /tmp/munin-plugin-du

設定項目に env.cache が加わった。
env.cacheはキャッシュファイルを指定する。省略してもよくて、省略すると /tmp/munin-plugin-du になる。
前回は述べなかったが、userは必ずしもrootである必要はなく、対象ディレクトリに対してduできる権限を持ったユーザーであればよい。

cronの設定の例

毎時2分にキャッシュを再生成する場合は以下のように設定する。

2 * * * * rm /tmp/munin-plugin-du & /usr/sbin/munin-run du

/tmp/munin-plugin-du はキャッシュファイルを指定する。
/usr/sbin/munin-run はmunin-runをフルパスで指定する。

munin本体からのアクセスと時間がかぶらないようにするために、0分ちょうどではなく2分にずらしている。
一時間単位のデータでは荒いという場合は5分ごとに実行するように設定すればよい。

*1:10秒でタイムアウトするようだ。タイムアウト時間はプラグインごとに設定できるとのこと→http://munin-monitoring.org/wiki/plugin-conf.d