« あとで新聞、新着記事を RSS 配信する仕様に切り替えました(追記あり) | メイン | スパムサイト作成講座42 - 実験サイトからみる傾向と対策 »
2007年10月04日
(高速に)Apache の log を解析する正規表現(追記あり)
※(多分)最終バージョンはこちらです。 ⇒[ぴ] - Apache Combined Log を効率的にパースする正規表現メモ , Apache Combined Log 解析正規表現ベンチマークの補足 (2007/10/05) ※ベンチマークありがとうございました。
ネタ的には既出なんですが・・・
Ref: [ぴ] - Apache Combined Log を効率的にパースする正規表現メモ
グーグル先生でよく教えてもらえる正規表現というのがありまして、
!^(.*) (.*) (.*) \[(.*)\] "(.*)" (.*) (.*) "(.*)" "(.*)"!
これ、使ってみると 1万行解析するのに 7.617 秒かかりました。ありえない。(Let's note T5 / CentOS)
で、バックトラックかからないよう、例えばこんな感じに適当に変更:
!^([^\s]*) [^\s]* [^\s]* \[([^]]*)\] "([^"]*)" ([^\s]*) [^\s]* "([^"]*)" "([^"]*)"!
すると1万行解析するのに 0.093 秒と劇的に改善。約80倍!
多分検索すると出てくるので最初の正規表現結構使われてると思うんですが、こんなの広めちゃいかん と思いついついエントリ。
ま、たまにはこんなゆるいエントリもあり、ということで。
■(追記)
Referer に 「"」が含まれている場合に対応してません(とコメントいただきました)。
そこだけ戻して
!^([^\s]*) [^\s]* [^\s]* \[([^]]*)\] "([^"]*)" ([^\s]*) [^\s]* "(.*)" "(.*)"!
としてみました。これでもパフォーマンスはほとんど変わりませんでしたので、こちらでどうぞ。
※んん・・UserAgent に 「"(+空白)..."...」が含まれてると正しくパースしませんね、これじゃ。ちゃんとエスケープ処理しないとだめか・・・あとはどなたかにおまかせ。
※[^\s] は \S でも OK です。コメントありがとうございます。もはや \S 対応してないやつなんてないですね・・・
■(余談1)
私が正規表現で「!」を使うようになったのは青い人の影響です。
■(余談2)
任天堂の Favicon なんかいいですよねw
投稿者 aka : 2007年10月04日 16:38 / 2007年10月 / メモ
トラックバック
このエントリーのトラックバックURL:
http://133.242.136.64/mt-tb-sf.cgi/649
コメント
"([^"]*)" の部分なのですが、稀にリクエストの中に「 " そのもの」が入っている場合があって、その場合に正しくパースできなくなります。
で、私はそこだけは仕方なく "(.*?)" として対処しました。
もっとも " そのものが入っている場合には \" とエスケープされて記録されるので、その辺踏まえると矛盾無くもう少し効率化することができるかもしれません。("((\\"|[^"])*)" とか)
投稿者 pmakino : 日時 2007年10月04日 19:25
コメントありがとうございます。そうですね、" が含まれている場合に対応できてないですね。。。。
投稿者 aka : 日時 2007年10月04日 23:29
Referer だけでなく Request にも " が含まれることがありますので、"([^"]*)" の部分は全部 "(.*?)" にするのが良いかと思います。
色々試してみたところ、.* を .*? に変えるだけでもかなり大きな効果があるようです。
また、[^\s] を \S に変えると Windows 上では僅かにパフォーマンスが上がりましたが Linux 上では逆に3/4程度に下がりました。
投稿者 pmakino : 日時 2007年10月05日 02:25
> また、[^\s] を \S に変えると Windows 上では僅かにパフォーマンスが上がりましたが Linux 上では逆に3/4程度に下がりました。
すみません、これは嘘でした。たまたま別プロセスに CPU を取られていただけのようです。
何度か繰り返してみたところ Linux 上でも \S に変えた方がおおむね10~20%程度パフォーマンスが上がりました。
投稿者 pmakino : 日時 2007年10月05日 03:15