前回の記事で、
LTSV -> fluentd -> BigQuery
という構成時、 BigQuery に boolean
が正しく格納されない問題がある、と書きました。
この問題に対し、 @yukiyan_w さんが以下の様なサンプルコードを教えてくださいました。
これで動いたので貼っときますね https://t.co/Vv426HFrsx / “fluentd で LTSV なログを BigQuery に送るときの注意点 - はのちゃ爆発” https://t.co/h1V20DF1UT
— Yukiyan (@yukiyan_w) July 31, 2016
また、サンプル以外でも以下の様なつぶやきがあったので、色々調べつつやってみました。
in_tail使ってるならtypes使えば良いが...
— Yukiyan (@yukiyan_w) July 31, 2016
起こっていた問題と解決方法
今回、以下の様なsource
ディレクティブを設定して処理を行っていました。(一部改変)
<source> @type tail format ltsv time_format %Y-%m-%dT%H:%M:%S %z path /var/www/hoge.log pos_file /var/log/td-agent/hoge.log tag hoge.fuga </source>
上記のsource
は、boolean
が正しくBigQueryに格納されない時のものです。
このsource
に対し、以下のオプションを追加します。
types is_awesome:bool
ログにis_awesome
という項目がある、という前提です。
types
?
types
って何やねんという感じですよね。公式サイトの説明は以下。
今回は@type
がtail
なので、tail Input Plugin
を見ています。
types (optional)
Although every parsed field has type string by default, you can specify other types.
types
を指定しないとデフォルトのstring
でパースされます、と。
types
を指定すれば別の型を指定することが可能に。
The syntax is
types <field_name_1>:<type_name_1>,<field_name_2>:<type_name_2>,... e.g.,
types user_id:integer,paid:bool,paid_usd_amount:float
フィールド名: 型
という形式で指定します。カンマで区切って複数指定も可能。
Unspecified fields are parsed at the default string type.
不明な型を指定した場合はstring
として解釈されるとのこと。
使用できる型は以下の通り。int
は使えずinteger
なことに注意。
string bool integer (“int” would NOT work!) float time array
array
と time
に関しては別の扱い方が出来たりするみたいだけど、今は省略します。
json and none parsers don’t support types parameter.
あと、パーサがjson
、none
の場合はtypes
が効かないので注意、とのこと。
まとめ
今回、以下の様な構成で fluentd から BigQuery にデータを送っていました。
System -> LTSV log -> fluentd(tail, fluent-plugin-bigquery) -> BigQuery
fluentd のtail Input Plugin
を使って読み込まれるデータは、デフォルトでは文字列でパースされます。
実際に BigQuery にデータを送信する際のスキーマファイル内でboolean
を指定していても、その手前、
ソースからデータを読み込んでパースする部分で、すべて文字列としてパースされてしまいました。
今回のトラブルは、パースされたtrue
やfalse
などの文字列を boolean
に変換しようとした結果、
全て true
に変換されてしまっていたのが原因でした。
こうした事態を防ぐため、types
オプションを source
ディレクティブ内に記述しました。
これによって、ログファイルの指定フィールドを、きちんとboolean
としてパースさせることが出来るようになりました。
fluentd について扱っている記事で、types
について触れているものは見かけた記憶があまりありませんでした。
あんまりこの辺で引っかかることはないんでしょうか…?