2016年12月6日火曜日

Haskellでログパーサを書く時の参考記事

Haskellでログ解析をしたいときに、こちらの記事が参考になります。

Parsec を使って Apache のログファイルをパースしてみる

Parsec を使って Apache のログファイルをパースしてみる2

内容は、ApacheログをParsecを使ってパーサを作ってレコードシンタックスのデータとして読み込むところまでをステップバイステップで解説しています。

ログを解析するような処理は、awkなどのコマンド/PythonなどのLL言語と、正規表現を使うのが一般的だと思います。

そこでHaskellでパーサを使うメリットが、この文章に集約されてます。

このスクリプトを Python が書いた時、正規表現を用いてパースをしました。すると、コーディングに時間がかかり、また使っている間はずっとバグに出会う羽目になりました。しかし、 Haskell はもっとよい方法を提示してくれています。正規表現を用いるより、 Parsec ライブラリのパーサコンビネータを使いましょう。 小さなパーサをつなげて大きなパーサにするという Parsec のアイデアは、対象物が何であるかを一歩一歩確実に定義していくことを可能にしています。

Haskellもできあがりのコードをいきなり見ると、難しい場合もありますが、小さく簡単なものから作っていけば十分理解できます。

Haskellを始めたばかりの人にもおすすめです。

現行のGHCでは動かないコードがあったので、同じくコンパイルできない方は、以下のコードを試してみるといいと思います。

2の最後の2つのコードの箇所です。

main = do
  file <- readFile "logfile.txt"
  let logLines = lines file
  let result = map (parse line "(test)") logLines -- result::[Either ParseError String] 
  mapM_ (either print print) result

記事に記載のこちらだと、

result <- mapM (parse line "(test)") logLines

mapM...の戻り値がIO (...)でないといけないのですが、実際には、Either ...となってしまいます。

説明が丁寧でとてもいい記事なので、ぜひお試しください。

よきHakellライフを!