ログのフォーマットやparse処理についてつらつら書いてみる。
ある程度構造化された半構造化ログのパターンとしては以下があると個人的には思ってる。
- Apacheのcombined ログフォーマットや独自フォーマットなどである程度決まったフォーマットで保存されておりHuman Readableだけどログのparseに正規表現が必要なもの。
- アプリで扱っているモデルをそのままMessagePack, Protocol Buffersなどの形式でシリアライズしたもの。Machine ReadableではあるけどHuman Readableではない。
- モデルを分解してkey-value形式でJSONやLTSVなどの形式で保存されており(上記1ほどでは無いにしろ)Human Readableであり(上記2ほどでは無いにしろ)Machine Readableでありログのparseに正規表現が不要なもの
個人的な意見として正規表現を使うのは*.txtのような比較的単純な場合に限定した方が良いと思っています。理由は複雑な正規表現は書くのが難しいし可読性も悪いからです。まあ現実はそうも言ってられないんですけどね。。。
で、それはともかく、さらにいうと予期せぬ長大なログが来た場合にJavaだとStackOverFlowErrorが起きる危険性があります。他言語は知りません。
そのような理由から上記1はあんまり良くないかな〜と思ってます、しかし現実は(ry
上記2はparseが要らないのでその意味では良いのですが、Human Readableじゃないんですよね。。。シリアライズしてbase64でファイルに保存とかするわけですが、何か問題があって中身をチェックしたくてもやりづらい。。。
そしてもうひとつの問題はログ解析側がモデルのバージョンアップに追随する必要があることです。
public class User { private String name; private Date birthDay; ...
みたいなモデルがあってメールアドレスの情報も追加しようってことになると下記のようなフィールドが追加されるわけです。
private String email;
こうなると新しいモデルでシリアライズしたデータを古いモデルではデシリアライズできません。まあデシリアライズできないデータはskipという形になるでしょう。
ログを埋め込む人と解析する人は大抵別なのでどうしても新しいデータに対応するのは遅れがちになるでしょう。
この問題の解決は技術というよりマネジメント寄りの話になるかと思います。
上記3でも本質的にはこの問題は解決できません。新しい値が追加されたらpase側が対応するまではskipされるだけです。ただし3の場合はparseに正規表現使わないのでへんなデータに対する耐性はあると思います。あと多少はHuman Readableかなと思ってます。
僕個人は上記1と2は経験してますが3は未経験です。ただ3はなんとなく良さげかなと思ってます。