blog/content/post/2012-03-27-00001548.md

7.7 KiB

title author date url wordtwit_post_info categories
nginxのアクセス数を集計するプラグイン kazu634 2012-03-27 /2012/03/27/_1762/
O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";s:1:"1";s:5:"delay";s:1:"0";s:7:"enabled";s:1:"1";s:10:"separation";i:60;s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:5453;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}
つれづれ

muninでnginxのアクセス数を集計するプラグインを作成してみました。

やりたいこと

nginxのログファイルからお手軽にアクセス数を集計したい。

muninプラグインの仕様

  • configという引数を与えられると、muninのconfigを標準出力に出力する
  • 引数なしの場合には、「属性名 数値」を出力する
  • 5分毎に呼び出される

詳細は HowToWritePlugins ? Munin を参照のこと。

nginxのログの仕様

  • 1アクセスが1行のログとして書き込まれる
  • (私の場合は)24hごとにログがローテーションする

デザイン

  • 1アクセスが1行のログとして書き込まれることから、wcコマンドで行数をカウントすればよさそう。この時点でシェルスクリプトで作成することに決定
  • 直前にスクリプトを実行した際の行数と、現在の行数をカウントして、その差がアクセス数
  • ローテーションした場合には「現在の行数」< 「直前にスクリプトを実行した際の行数」の時。この時はアクセス数は0とする。次回の起動時にアクセス数としてカウントする。

作成したスクリプト

#!/bin/bash
# -----------
# varibales
# -----------
LOGFILE="/var/log/nginx/front_proxy.access.log"
LASTDATA="/tmp/.munin-nginx"
# -----------------------
# Handling the arguments
# -----------------------
case $1 in
config)
cat <<'EOM'
graph_args -l 0
graph_scale no
graph_category nginx
graph_title Nginx Access
graph_vlabel access
access.label access
EOM
exit ;;
esac
# -----------------------
# Collecting data
# -----------------------
CURRENT_LINENUM=`wc -l ${LOGFILE} | perl -pe "s/^ +//" | cut -f 1 -d " "`
# checks if the last recorded data exists or not:
if [ -e ${LASTDATA} ]; then
 # Get the last line number
LASTLINE=`cat ${LASTDATA}`
expr ${CURRENT_LINENUM} \< ${LASTLINE} > /dev/null
RESULT=$?
 # when the target log file is rotated,
if [ $RESULT -eq  ]; then
 # it returns 0
echo "access.value 0"
 # and sets 0 to the $LASTDATA
echo 0 > ${LASTDATA}
 # not rotated
else
echo -n "access.value "
echo `expr ${CURRENT_LINENUM} - ${LASTLINE}`
echo ${CURRENT_LINENUM} > ${LASTDATA}
fi
else
 # if the log file does not exist, it returns 0
echo "access.value 0"
 # and sets the current line number to the $LASTDATA
echo ${CURRENT_LINENUM} > ${LASTDATA}
fi
exit