メールの流量を調べる
メールサービスの将来像を検討するための材料として、現在のメール流通量を調べるべくチャンレンジ。
全部のバイト数
Solarisの場合、sendmailのログは/var/log/syslogにでます。調べたい月のログを抜き出してから全部のメールの流通量を調べるにはこんな感じ。
# grep '^Nov' /var/log/syslog* | mm.pl
mm.plの中身はこんなの。
#!/usr/local/bin/perl while(<>){ if (/, size=(\d+)/ ){ $total_size += $1 } } print $total_size ;
簡単だなぁ。私が管理している環境では受信用に3台、発信用に1台のサーバがあるのでそれぞれで実行して電卓を叩けば答えがでます。
でも
受信用のサーバではスパムフィルタを実施しています。スパムフィルタにひっかかったメールの流量は除きたい。すこし前に調べたところ、すべてのSMTPコネクションのうち、約70%はスパムとして扱っています。だからすべての流通量×0.3でいいかなと考えましたが、せっかくなのでちゃんと計算することに。ちょっと考えてこんなステップを踏むことにしました。
- 全部のメールIDとSPAMチェックにひっかかったメールIDをそれぞれ調べる。
- 上記の2つの差分を取ってスパムチェックにひっかからなかったメールIDを調べる。
- このメールIDが含まれたログからサイズを計算する。
実際にやったことは
まずすべてのメールIDを抜き出します。nov_syslogには11月分だけのログが含まれています。
$ ./mmm.pl nov_syslog | sort -u > spamid.log
mmm.plの内容はこんなの。正規表現で引っ掛けます。定義あってるのかな。
#!/usr/local/bin/perl while(<>){ if( / ([a-zA-Z\d]{14}): / ){ print $1 ,"\n"; } }
続いてSPAMチェックにひっかかったメールのIDを調べます。SpamAssassinをMimedefangと組みあわせて、ヘッダにタグをつけている運用をしています。この場合、スパムチェックにひっかかったメールはこんな風にログ出力されます。
Nov 24 03:10:12 hogehoge sendmail[3959]: [ID 801593 mail.info] lANIA0pjXXXXXX: Milter change: header Subject: from Re: to =====SPAM===== Re:
SpamAssassinでSPAM判断されるとヘッダ中のSubjectを書き換えて"=====SPAM====="を頭につけます。なので、perlに書く抽出条件はこんな感じ。
#!/usr/local/bin/perl while(<>){ if( / ([a-zA-Z\d]{14}): Milter change: header Subject:/ ){ print $1 ,"\n"; } }
これをmmm.plに書き込んで先ほどと同じように実行。
$ ./mmm.pl nov_syslog | sort -u > allspam.log
差分を取ります。
$ diff allspam.log allid.log | grep '^[<>]' | sed -e 's/^[<>] //' > ham.log
と、ここまでやってそのIDがなんと50万もあることがわかった。syslogからそのIDが含まれている行をどうやって抜き出すのがいいんだろう。
もちろんシェルでこうやって抜き出すこともできるけど、
for i in `cat ham.log` do fgrep $i nov_syslog >> nov_syslog.ham done
とりあえずはこれで抜き出しを実施しつつ、スマートな方法ないか考えよう。