squidのアクセスログからアクセスしたドメイン毎の1分間単位のアクセスを調べるワンライナーを書いたのでメモ。
squidに限らず、アクセスログの時間単位の集計は基本的に以下にならってやれば良いのでないかと思います。(簡易なものは)
- sedでアクセスログの時間列の不要部分を削除する
- awkで必要な列だけ抽出
- sort と uniq -cで行数をカウント
最終的なワンライナー
$sed 's/:[0-9][0-9][\x20]+\+0900\.[0-9][0-9][0-9]|//g' access.log | awk -F "|" '{ print $1,$8; }' | sort | uniq -c
2 06/Oct/2015:18:00 - AAA.ne.jp
2 06/Oct/2015:18:00 - BBB.ne.jp
2 06/Oct/2015:18:07 - CCC.ne.jp
2 06/Oct/2015:18:07 - AAA.ne.jp
3 06/Oct/2015:18:10 - CCC.ne.jp
4 06/Oct/2015:18:10 - BBB.ne.jp
・・・・
sedでアクセスログの時間列の不要部分を削除する
最後のパイプの部分でuniqコマンドによってユニークな行数をカウントするので、不要な秒やそれ以外の時間の部分をsedコマンドを使って削除します。
正規表現で合致する部分を任意の文字列に置き換えることができるので、今回は正規表現にマッチした部分(秒以下の時間の部分)を空文字に置換(つまり削除)するようにしています。
$cat access.log
06/Oct/2015:18:00:47 +0900.483|200|・・・
$sed 's/:[0-9][0-9][\x20]+\+0900\.[0-9][0-9][0-9]|//g' access.log
06/Oct/2015:18:00 -|200|・・・
集計単位が時、秒の場合も同様に不要な部分を削除すれば同じ要領で集計が出来ると思います。
awkで必要な列だけ抽出
今回、ドメイン毎の集計なのでアクセス時間とドメイン部分以外はuniqコマンドで集計する際に邪魔です。
必要な列の抜き出しにはawkコマンドを使います。
今回のログでは1列目にアクセス日時、8行目にドメインの記載があったので該当列のみ抽出します。
各列のセパレーターは「|」なので-Fオプションで指定します。
$ awk -F "|" '{ print $1,$8; }' access.log
上記で該当列のみの抽出が出来ます。
sort と uniq -cでカウント
uniqコマンドの-cオプションを付与することで内容が同じ行のカウントができるのでこれを利用します。
sedとawkによって既に集計したい時間とドメインのみの行となっているので、アクセスした日時分までが同じでかつ、同じドメインの場合には同じ文字列となっているはずです。
上記を利用し、uniq -cによって行数を集計します。
なお、uniqは事前にソートされている必要があるのでsortコマンドを使って事前にソートするようにしています。