はじめに
Embulkというのをつい先日まで知らなかったのですが、
簡単にいうと「色々な所のデータを、バッチで、変換→Importするフレームワーク」みたいなものかな、と思います。
色々Pluginを作ることができて既にたくさんあるのですが、ちょっと変則的なApacheのAccessLogをBigQueryにImportしようとしたときに良いParserが無かった(わからなかった)ので、正規表現で文字列を1行ずつParseするものを作ってみました。
Version
- Embulk 0.7.4
で動作確認しています。
使い方
install
embulk gem install embulk-parser-regex
guess
一応 ApacheのAccessLogの common/combined/combinedio は guessで作れます。
とりあえず、それを雛形に独自の項目を追加すると良いと思います。
例えば、
in:
type: file
path_prefix: /path/to/data/access_log.
parser:
charset: UTF-8
newline: LF
out:
type: stdout
という config.yml
に対して以下を実行します。
embulk guess -g regex config.yml -o guessed.yml
すると、 guessed.yml
が生成されるので、
embulk preview guessed.yml
とすれば、上手く言っていればParseされた内容が表示されていると思います。
設定項目
YAMLの parser
配下に設定を書きます。
type
type は regex と指定します
regex
行をParseするときに使う正規表現です。
Named Capturing Group
というやつで書く必要があります。
例えば、 (?<name>\S+)
というような ?<name>
を付けるということです。
で、この name
ですが、 [a-zA-Z0-9]
という文字しか使えないので注意してください( _
とか使えない)。
columns
他のPluginと同じように column の定義を書きます。 参考
本Pluginの特別な属性として以下のものがあります。
-
regex_name:
Named Capturing Group
で使われている名前を指定します(省略時は name属性が使われます)。nameに_
などがある場合はそのまま正規表現のグループ名に使えないので、ここで指定します。
skip_if_unmatch
regexで指定した正規表現にマッチしなかったときに、
- true ならば、 例外をthrowします
- false ならば、 その行をSkipします
デフォルトは false です。
設定例
in:
type: any file input plugin type
parser:
type: regex
charset: UTF-8
newline: LF
regex: ^(?<remoteHost>[.:0-9]+) (?<identity>\S+) (?<user>\S+) \[(?<datetime>[^\]]*)\] "((?<method>\S+) (?<path>\S+) (?<protocol>HTTP/\d+\.\d+)|-)" (?<status>[0-9]+) (?<size>[0-9]+|-) "(?<referer>[^"]*)" "(?<userAgent>[^"]*)" (?<inByte>[0-9]+) (?<outByte>[0-9]+)$
columns:
- {name: remote_host, type: string, regex_name: remoteHost}
- {name: identity, type: string}
- {name: user, type: string}
- {name: datetime, type: timestamp, format: '%d/%b/%Y:%H:%M:%S %z'}
- {name: method, type: string}
- {name: path, type: string}
- {name: protocol, type: string}
- {name: status, type: long}
- {name: size, type: long}
- {name: referer, type: string}
- {name: user_agent, type: string, regex_name: userAgent}
- {name: in_byte, type: long, regex_name: inByte}
- {name: out_byte, type: long, regex_name: outByte}
out:
type: stdout
source
以下のソースコードからかなりコピペしました。。
- https://github.com/hiroyuki-sato/embulk-parser-apache-log
- https://github.com/frsyuki/embulk-parser-msgpack
さいごに
Java で Embulk Output Plugin を書く などを参考にしながらそれほどハマることなく作れました。すごい。
Pluginとか作るときはJavaは便利だなーと思います。
IDEAなどのIDEでIntellisenseをフル活用しながら、なんとなく書けちゃいますからね。