おそらくはそれさえも平凡な日々

恐らくそれなりに正確なGoのApacheログパーザーを書いた

https://github.com/Songmu/axslogparser/

下記のようにすれば、ApacheログかLTSVログをよしなにパーズしてくれます。

import "github.com/Songmu/axslogparser"

log, err := axslogparser.Parse(line)

Apacheのログ形式として知られるアクセスログはいろいろな形式があり、正確なパーズが何気に困難であることが知られています。よく使われるのは以下のような形式です。axslogparserはこれらの形式をサポートしています。

  • commonログ
  • commonログの先頭にvhostが付いたもの
  • combinedログ
  • combinedに独自フィールドが追加されたもの

フィールドの区切り文字は一般的には半角スペースが使われますが、パーズし易さのためにタブ文字が使われることもあります。現在はcombinedログに独自フィールドがいくつか追加されたものが多く使われているのではないでしょうか。

これらをパーズする正規表現は結構出回っていますが、大体の場合不正確です。特に難しいのが、ダブルコーテーションの扱いで「エスケープされていないダブルコーテーションで囲まれたフィールド」を正規表現で正確に取り出すのは実はかなり難しいです。

Goでも案の定、正確にパーズできるパーザーが見当たらなかったので、カッとなって書きました。結構正確はなず。戦略としては、タイムスタンプの部分まで正規表現でマッチさせて、それ以降は素朴にフィールドを取り出すようにしています。

既存の類似ライブラリは、ログのフォーマットを指定して、それに従ってパーズするようになっているものが多いのですが、指定無しで大体の場合をケアできるようにしたかったのでそのようになっています。そのうちフォーマット指定できるようにするかもしれない。

動機としてはアクセスログを舐めて集計するような処理を書きやすくしたくて作った。はてなのアクセスログはほとんどLTSVになってるんだけど、Mackerelのプラグインで使いたいというのがあって、頑張ってApacheログもケアしたかった。もうちょっとお茶を濁しても良かったと思うんだけど凝り性なのでついついこだわってしまった。

なので、本命としてはLTSVアクセスログなのでみなさんアクセスログをファイルに落とす場合はLTSVを使いましょう。もしくはローカルのファイルシステムにアクセスログを書き込むのはもう古い(適当

created at
last modified at

2017-06-24T01:34:06+0900

comments powered by Disqus