Apache Pig で LTSV をロードするための UDF を書きました

2013-02-08 くらいから LTSV というログ用のファイルフォーマットが話題になっています (id:naoya:20130209:1360381374) 。 TSV の各列を「<ラベル>:<値>」で構成するというだけのものですが、 awk 等のプレーンなツールで処理しやすい上に、変更に強く、可読性もそこそこという優れた性質があります。

出したログは Hadoop に持って来て Pig で処理したいので、 Pig で LTSV をロードするための UDF を書きました。気難しい CombinedLogLoader を使うよりは、いくらか簡単になるはずです。

使い方は上記リンク先にある通りですが、再掲します。

次のようなアクセスログファイルがあるとします (各列はタブ区切り) 。

host:host1.example.org   req:GET /index.html     ua:Opera/9.80
host:host1.example.org   req:GET /favicon.ico    ua:Opera/9.80
host:pc.example.com      req:GET /news.html      ua:Mozilla/5.0

これを、次のような Pig スクリプトで処理します。

-- UDF の JAR ファイルを登録後、 UDF を呼び出すための短い名前を付ける
REGISTER pig-ltsv-storage.jar;
DEFINE LTSVLoader org.ltsv.pig.LTSVLoader;

-- アクセスログをパースしてユーザエージェントのフィールドだけを出力
access = LOAD 'access.log' USING LTSVLoader() AS (m:map []);
user_agent = FOREACH access GENERATE m#'ua' AS ua;

-- 各アクセスのユーザエージェントを出力
DUMP user_agent;

結果は次のようになります。

(Opera/9.80)
(Opera/9.80)
(Firefox/5.0)

LTSV の各行は 1 つのマップ型フィールド (ラベル→値) からなるタプルとして読み込みます。 LTSV 中の各列の値は「<マップのフィールド名>#'<ラベル>'」としてアクセスできます。

今はまだ .gz とか .bz2 とかの圧縮ファイルが読めないので、なんとかします。首尾整ったら PiggyBank (Pig の UDF のリポジトリ) に寄贈します。